Skip to content

Commit bf81358

Browse files
authored
Merge branch 'main' into feat/exit-plan-mode-hitl
2 parents d7352bb + cb01c10 commit bf81358

4 files changed

Lines changed: 104 additions & 58 deletions

File tree

components/runners/ambient-runner/.mcp.json

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -13,45 +13,6 @@
1313
"args": [
1414
"mcp-server-fetch"
1515
]
16-
},
17-
"mcp-atlassian": {
18-
"command": "uvx",
19-
"args": [
20-
"mcp-atlassian"
21-
],
22-
"env": {
23-
"JIRA_URL": "${JIRA_URL}",
24-
"JIRA_USERNAME": "${JIRA_EMAIL}",
25-
"JIRA_API_TOKEN": "${JIRA_API_TOKEN}",
26-
"JIRA_SSL_VERIFY": "true",
27-
"READ_ONLY_MODE": "${JIRA_READ_ONLY_MODE:-true}"
28-
}
29-
},
30-
"openshift": {
31-
"command": "uvx",
32-
"args": [
33-
"kubernetes-mcp-server@latest",
34-
"--kubeconfig",
35-
"/tmp/.ambient_kubeconfig",
36-
"--disable-multi-cluster"
37-
]
38-
},
39-
"google-workspace": {
40-
"command": "uvx",
41-
"args": [
42-
"workspace-mcp@1.17.1",
43-
"--permissions",
44-
"gmail:send",
45-
"drive:full"
46-
],
47-
"env": {
48-
"GOOGLE_MCP_CREDENTIALS_DIR": "${GOOGLE_MCP_CREDENTIALS_DIR}",
49-
"MCP_SINGLE_USER_MODE": "1",
50-
"GOOGLE_OAUTH_CLIENT_ID": "${GOOGLE_OAUTH_CLIENT_ID}",
51-
"GOOGLE_OAUTH_CLIENT_SECRET": "${GOOGLE_OAUTH_CLIENT_SECRET}",
52-
"GOOGLE_OAUTH_REDIRECT_URI": "${GOOGLE_OAUTH_REDIRECT_URI}",
53-
"USER_GOOGLE_EMAIL": "${USER_GOOGLE_EMAIL:-user@example.com}"
54-
}
5516
}
5617
}
5718
}

components/runners/ambient-runner/Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ RUN npm install -g @google/gemini-cli@${GEMINI_CLI_VERSION} && \
4444
npm cache clean --force
4545

4646
# Install CodeRabbit CLI (official install script, binary for current arch)
47-
RUN curl -fsSL https://cli.coderabbit.ai/install.sh | CODERABBIT_INSTALL_DIR=/usr/local/bin sh
47+
RUN curl -fsSL https://cli.coderabbit.ai/install.sh | CODERABBIT_INSTALL_DIR=/usr/local/bin sh \
48+
|| echo "WARNING: CodeRabbit CLI install failed — cli.coderabbit.ai may be down; continuing without it"
4849

4950
# Set environment variables
5051
ENV PYTHONUNBUFFERED=1

components/runners/ambient-runner/ambient_runner/bridges/claude/mcp.py

Lines changed: 96 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ def build_mcp_servers(
7474
load_rubric_content,
7575
)
7676
from ambient_runner.bridges.claude.corrections import create_correction_mcp_tool
77-
from ambient_runner.bridges.claude.backend_tools import create_backend_mcp_tools
7877

7978
mcp_servers = load_mcp_config(context, cwd_path) or {}
8079

@@ -130,18 +129,12 @@ def build_mcp_servers(
130129
mcp_servers["corrections"] = correction_server
131130
logger.info("Added corrections feedback MCP tool (log_correction)")
132131

133-
# Backend API tools (session management)
134-
backend_tools = create_backend_mcp_tools(sdk_tool_decorator=sdk_tool)
135-
if backend_tools:
136-
backend_server = create_sdk_mcp_server(
137-
name="acp", version="1.0.0", tools=backend_tools
138-
)
139-
mcp_servers["acp"] = backend_server
132+
# Credential-aware MCP servers (dynamically configured per bound credentials)
133+
credential_mcp_servers = build_credential_mcp_servers()
134+
mcp_servers.update(credential_mcp_servers)
135+
if credential_mcp_servers:
140136
logger.info(
141-
f"Added backend API MCP tools ({len(backend_tools)}): "
142-
"acp_list_sessions, acp_get_session, acp_create_session, "
143-
"acp_stop_session, acp_send_message, acp_get_session_status, "
144-
"acp_restart_session, acp_list_workflows, acp_get_api_reference"
137+
"Added credential MCP servers: %s", list(credential_mcp_servers.keys())
145138
)
146139

147140
# Gerrit MCP server (only if credentials are configured)
@@ -160,6 +153,97 @@ def build_mcp_servers(
160153
return mcp_servers
161154

162155

156+
_CREDENTIAL_MCP_REGISTRY: dict[str, dict] = {
157+
"jira": {
158+
"command": "uvx",
159+
"args": ["mcp-atlassian"],
160+
"env": {
161+
"JIRA_URL": "${JIRA_URL}",
162+
"JIRA_USERNAME": "${JIRA_EMAIL}",
163+
"JIRA_API_TOKEN": "${JIRA_API_TOKEN}",
164+
"JIRA_SSL_VERIFY": "true",
165+
"READ_ONLY_MODE": "${JIRA_READ_ONLY_MODE:-true}",
166+
},
167+
"server_name": "mcp-atlassian",
168+
},
169+
"kubeconfig": {
170+
"command": "uvx",
171+
"args": [
172+
"kubernetes-mcp-server@latest",
173+
"--kubeconfig",
174+
"/tmp/.ambient_kubeconfig",
175+
"--disable-multi-cluster",
176+
],
177+
"server_name": "openshift",
178+
},
179+
"google": {
180+
"command": "uvx",
181+
"args": ["workspace-mcp@1.17.1", "--permissions", "gmail:send", "drive:full"],
182+
"env": {
183+
"GOOGLE_MCP_CREDENTIALS_DIR": "${GOOGLE_MCP_CREDENTIALS_DIR}",
184+
"MCP_SINGLE_USER_MODE": "1",
185+
"GOOGLE_OAUTH_CLIENT_ID": "${GOOGLE_OAUTH_CLIENT_ID}",
186+
"GOOGLE_OAUTH_CLIENT_SECRET": "${GOOGLE_OAUTH_CLIENT_SECRET}",
187+
"GOOGLE_OAUTH_REDIRECT_URI": "${GOOGLE_OAUTH_REDIRECT_URI}",
188+
"USER_GOOGLE_EMAIL": "${USER_GOOGLE_EMAIL:-user@example.com}",
189+
},
190+
"server_name": "google-workspace",
191+
},
192+
}
193+
194+
195+
def _expand_env_vars(value: str) -> str:
196+
import re as _re
197+
198+
def _replace(match: _re.Match) -> str:
199+
expr = match.group(1)
200+
if ":-" in expr:
201+
var, default = expr.split(":-", 1)
202+
return os.environ.get(var, default)
203+
return os.environ.get(expr, match.group(0))
204+
205+
return _re.sub(r"\$\{([^}]+)}", _replace, value)
206+
207+
208+
def build_credential_mcp_servers() -> dict:
209+
credential_ids_raw = os.getenv("CREDENTIAL_IDS", "").strip()
210+
if not credential_ids_raw:
211+
return {}
212+
213+
try:
214+
credential_ids = json.loads(credential_ids_raw)
215+
except (json.JSONDecodeError, TypeError):
216+
logger.warning("Failed to parse CREDENTIAL_IDS — skipping credential MCP servers")
217+
return {}
218+
219+
servers: dict = {}
220+
for provider, _cred_id in credential_ids.items():
221+
registry_entry = _CREDENTIAL_MCP_REGISTRY.get(provider)
222+
if not registry_entry:
223+
continue
224+
225+
server_name = registry_entry["server_name"]
226+
server_config: dict = {
227+
"command": registry_entry["command"],
228+
"args": list(registry_entry["args"]),
229+
}
230+
231+
if "env" in registry_entry:
232+
server_config["env"] = {
233+
k: _expand_env_vars(v) for k, v in registry_entry["env"].items()
234+
}
235+
236+
servers[server_name] = server_config
237+
logger.info(
238+
"Configured %s MCP server for bound credential %s (provider: %s)",
239+
server_name,
240+
_cred_id,
241+
provider,
242+
)
243+
244+
return servers
245+
246+
163247
def build_allowed_tools(mcp_servers: dict) -> list[str]:
164248
"""Build the list of allowed tool names from default tools + MCP servers."""
165249
allowed = list(DEFAULT_ALLOWED_TOOLS)

components/runners/ambient-runner/uv.lock

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)