Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# Status

Source of truth for where this project stands. Keep it current.

## State

**Runner implementation LANDED (separate runner-only PR).** The research + proposal +
author-review revision (Part 1 trust/transport, Part 2 enforcement matrix) is complete and was
docs-only. The decided near-term code changes are now implemented in a follow-up runner-only PR
(lane `feat/agent-sidecar-trust-enforcement`, `services/agent/src/**` only):

1. **Network isolation + optional `/run` token** (Part 1 steps 1–2): the sidecar binds to
loopback by default (`AGENTA_AGENT_RUNNER_HOST`, default `127.0.0.1`, never `0.0.0.0`), and
an OPTIONAL shared token (`AGENTA_AGENT_RUNNER_TOKEN`, default OFF) gates `/run` with a
constant-time compare when set (`server.ts`). `/health` stays open. mTLS / scoped tokens /
payload encryption remain deferred.
2. **Error-on-unimplemented `sandbox_permission`** (Part 2): `run-plan.ts` now errors the
not-implemented way (mirroring `code.ts`) when a restricted `network` policy is set on the
LOCAL sandbox (any `enforcement`), and whenever `filesystem` is specified (any backend, since
none enforce it). The Daytona strict-mode runner-host-tool guard stays.
3. **stdio MCP disabled** (Part 2): the stdio MCP implementation is disabled the same way code
execution was — `MCP_UNSUPPORTED_MESSAGE` in `tools/mcp-bridge.ts`; `buildToolMcpServers`,
`toAcpMcpServers`, and `mcp-server.ts` throw/refuse; `run-plan.ts` rejects any run carrying a
stdio MCP server. The wire shapes (`McpServerConfig`, `mcpServers`) are unchanged; only the
runtime delivery is gated. This removes custom-tool delivery to non-Pi harnesses (Claude) and
user-declared stdio MCP servers until the security issues are fixed.

`protocol.ts` was NOT edited (A3-owned; the error-on-unimplemented behavior is runtime, not a new
wire field). Gateway/callback tools were NOT touched (Layer-3 tool-permission, not Layer-2
`sandbox_permission`). Tests green: `pnpm test` (168) + `pnpm run typecheck` in `services/agent`.

## Scope

- **In scope:** documenting the trust model of the service→runner `/run` boundary; proposing
transport/auth options; correcting the "declared, not enforced" record for `SandboxPermission`.
- **Out of scope (unchanged by this work):** Composio, the tool gateway, named connections,
MCP. Token issuance design (Part 1 option 4) is platform-side and only recommended here.
Editing `protocol.ts` (owned by sibling agent A3 this cycle).

## Key findings (verified in code)

Part 1 (transport):
- `services/oss/src/agent/config.py` `runner_url()` reads `AGENTA_AGENT_RUNNER_URL`: set →
HTTP; unset → local CLI subprocess.
- `sdks/python/agenta/sdk/agents/utils/ts_runner.py` `deliver_http` posts `json=payload` with
no auth header, no TLS, no shared token. Only `Accept` is set (streaming).
- `services/agent/src/server.ts` `createRequestListener` serves `/run` with **no auth check**.
- The payload carries plaintext `secrets` (provider keys), `toolCallback.authorization`, and
`trace.authorization` (the caller's full `Authorization` header, copied in
`services/oss/src/agent/tracing.py`).
- Precedent for a shared-token gate already exists: `X-Agenta-Internal-Token` /
`AGENTA_VAULT_RESOLVE_INTERNAL_TOKEN` on the platform vault-resolve route.

Part 2 (enforcement):
- Daytona network egress IS enforced: `provider.ts` `daytonaNetworkFields()` →
`buildSandboxProvider()` (off/empty-allowlist → `networkBlockAll`, non-empty → `networkAllowList`).
- Local sandbox cannot enforce egress: `run-plan.ts` rejects under `strict`, warns under `best_effort`
today (decision: should ERROR whenever `network` is set on local — see review decisions).
- Filesystem declared-only, enforced nowhere (`protocol.ts:159`; decision: should ERROR when specified).
- **`code` execution is ALREADY REMOVED** from the sidecar: `runCodeTool` (`tools/code.ts`) throws
`CODE_TOOL_UNSUPPORTED_MESSAGE` ("Code tools are not supported by the sidecar."); interface kept,
every path funnels through the throwing gate (`dispatch.ts` / `relay.ts`). This is the
not-implemented pattern the local-network + filesystem + MCP decisions mirror.
- **stdio MCP is STILL implemented** on the runner host: `tools/mcp-bridge.ts`
(`buildToolMcpServers`) launches `tools/mcp-server.ts` (JSON-RPC stdio). Decision: disable it the
same way as code execution and remove the sidecar implementation.
- gateway/callback tools run on the runner host (`relay.ts`), governed by **Layer-3
tool-permission** (`resolvePermission`), NOT `sandbox_permission` (Layer 2) — no change needed.
- **Legacy in-process `pi` engine REMOVED:** `engines/pi.ts` no longer exists (A3 landed it;
shows as `D` in the working tree). Only `sandbox_agent.ts` / `sandbox_agent/` / `skills.ts` remain.
- The stale `protocol.ts:149-150` comment was ALREADY corrected by A3 (now reads "network policy
IS enforced on Daytona … `filesystem` is declared-only on every provider"). Two follow-up comment
edits remain (filesystem→error, local-network→error) once that behavior lands.

## Review decisions (PR #4831)

The author left 6 inline comments; each is folded into the README:

1. README network-isolation/loopback-binding option — **endorsed** ("agree"). Kept as decided step 1.
2. Recommendation — **scope near-term to steps 1 & 2 only** ("only implement 1 and 2 now"). mTLS /
short-lived scoped tokens / payload encryption moved to an explicit "Later / deferred hardening"
subsection.
3. Local network — **error when `network` set on local** (not-implemented-style, mirroring
`code.ts`'s `CODE_TOOL_UNSUPPORTED_MESSAGE` gate / the typed `*Unsupported*Error`s in
`connections/errors.py`), regardless of `enforcement`. Decision documented; code change separate.
4. Filesystem — **error when `filesystem` specified** (not implemented anywhere), same pattern.
5. MCP / gateway / layering — **disable stdio MCP-server execution in the sidecar** the same way
code execution was disabled (not-implemented gate + remove `mcp-bridge.ts` / `mcp-server.ts` /
stdio plumbing), until security is fixed. **gateway tools = no action**: they are Layer-3
tool-permission, NOT Layer-2 `sandbox_permission`. Code-state verified: code exec removed, MCP
still present. Decisions documented; code change separate (another agent owns the sidecar).
6. Legacy `pi` engine — verified **removed** (A3); doc now presents it as removed/historical only.

## Recommendation (Part 1)

**Decided near-term scope (implement now): steps 1 & 2 only** (author: "only implement 1 and 2
now"). (1) assert + enforce localhost/in-cluster-only binding and document the plaintext-secrets
trust model; (2) add an optional shared `/run` token (reuse the `X-Agenta-Internal-Token`
pattern). **Deferred (NOT near-term):** (3) TLS, mTLS via a service mesh where available; (4)
short-lived audience-scoped trace/callback tokens; (5) payload encryption held in reserve. Full
rationale in README Part 1.

## Coordination

- Lease claimed on `docs/design/agent-workflows/scratch/agent-coordination.md` as
`sidecar-trust-research` (docs-only, this project's two files only).
- **A3 already applied the network half** of the `protocol.ts` comment correction (the comment
now reads "network policy IS enforced on Daytona … `filesystem` is declared-only"). Two
follow-up comment edits remain (filesystem→error, local-network→error) once that behavior
lands. This project does not touch `protocol.ts`.
- The decided code changes (local-network + filesystem → error; disable + remove stdio MCP in
the sidecar) are SEPARATE tasks. Another agent is editing the sidecar (`services/agent/`) this
cycle, so this revision touches ONLY this project's two doc files and stages only them.
- Related (not blocking): the `contract-versioning (A1)` lease notes `/health` advertises
`protocol: 1` that the Python client never reads. Orthogonal to this work.

## Open questions / follow-ups

1. **Whose decision is the default transport posture?** Decided near-term = localhost/in-cluster-only
binding + optional token; the actual default (token on/off) is a deployment policy call for the
sidecar-deployment owners. (TLS/mTLS now deferred, not near-term.)
2. **Deferred hardening** (TLS/mTLS, short-lived audience-scoped trace/callback tokens, payload
encryption) — explicitly out of near-term scope per review; recorded, not designed here.
3. **Where the Part 1 recommendation lands when implemented:** the hardening section of
`../sidecar-deployment-proposal/proposal.md`.
4. **Decided code changes (separate tasks, not this PR):** (a) `run-plan.ts` error when local
`network` set / when `filesystem` specified (not-implemented gate, mirroring `code.ts`); (b)
disable + remove the stdio MCP sidecar implementation (`mcp-bridge.ts` / `mcp-server.ts` /
stdio plumbing) the way code execution was removed; (c) the two follow-up `protocol.ts` comment
edits. Owned by whoever lands the runner change this cycle.

## Changelog

- 2026-06-24: Project created. Part 1 (transport trust proposal) + Part 2 (enforcement matrix
+ protocol.ts comment correction) written and verified against code. Lease + A3 flag posted
on the coordination board. No code changed.
- 2026-06-24: Revised per author review on PR #4831 (6 inline comments). Scoped near-term work to
steps 1 & 2 (deferred mTLS / scoped tokens / payload encryption to a "Later / deferred"
subsection); documented error-on-specified behavior for local network + filesystem (mirroring
the `code.ts` not-implemented gate); documented the decision to disable + remove the stdio MCP
sidecar implementation; clarified gateway = Layer-3 tool-permission, not Layer-2
`sandbox_permission`; updated the legacy `pi` engine to removed/historical. Verified code state:
`code` execution already removed (`runCodeTool` throws), stdio MCP still present, `engines/pi.ts`
gone, `protocol.ts` network comment already corrected by A3. Docs-only, two files; no code changed.
- 2026-06-24: **Runner implementation LANDED** (separate runner-only PR, lane
`feat/agent-sidecar-trust-enforcement`, `services/agent/src/**` only). (1) loopback binding +
optional `/run` token in `server.ts`; (2) `run-plan.ts` errors on local `network` / on
`filesystem` specified (not-implemented gate, any enforcement); (3) stdio MCP disabled
(`MCP_UNSUPPORTED_MESSAGE`, `mcp-bridge.ts`/`mcp-server.ts`/`toAcpMcpServers`/run-plan gate),
removing custom-tool delivery to non-Pi harnesses + user stdio MCP. `protocol.ts` untouched
(A3-owned; runtime behavior, no new wire field). Runner README MCP/tools lines synced. Tests
green: 168 vitest + typecheck in `services/agent`.
4 changes: 4 additions & 0 deletions hosting/docker-compose/ee/docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,10 @@ services:
# the runner reads for the `daytona` sandbox provider.
environment:
PORT: "8765"
# Bind on all interfaces: the co-located Python `services` container reaches the
# sidecar over the compose network at `sandbox-agent:8765`, so the trust-model
# default of `127.0.0.1` (same-host only) is unreachable cross-container.
AGENTA_AGENT_RUNNER_HOST: ${AGENTA_AGENT_RUNNER_HOST:-0.0.0.0}
Comment on lines 465 to +470

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Expose runner token env in compose for /run auth.

This service now binds to 0.0.0.0, but AGENTA_AGENT_RUNNER_TOKEN is not plumbed in this environment block. Because this container intentionally has no env_file, operators cannot enable the server’s token gate without editing compose again. Add an explicit token env entry so authorization can be turned on safely.

Suggested patch
         environment:
             PORT: "8765"
             # Bind on all interfaces: the co-located Python `services` container reaches the
             # sidecar over the compose network at `sandbox-agent:8765`, so the trust-model
             # default of `127.0.0.1` (same-host only) is unreachable cross-container.
             AGENTA_AGENT_RUNNER_HOST: ${AGENTA_AGENT_RUNNER_HOST:-0.0.0.0}
+            AGENTA_AGENT_RUNNER_TOKEN: ${AGENTA_AGENT_RUNNER_TOKEN:-}
             PI_CODING_AGENT_DIR: /pi-agent
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
environment:
PORT: "8765"
# Bind on all interfaces: the co-located Python `services` container reaches the
# sidecar over the compose network at `sandbox-agent:8765`, so the trust-model
# default of `127.0.0.1` (same-host only) is unreachable cross-container.
AGENTA_AGENT_RUNNER_HOST: ${AGENTA_AGENT_RUNNER_HOST:-0.0.0.0}
environment:
PORT: "8765"
# Bind on all interfaces: the co-located Python `services` container reaches the
# sidecar over the compose network at `sandbox-agent:8765`, so the trust-model
# default of `127.0.0.1` (same-host only) is unreachable cross-container.
AGENTA_AGENT_RUNNER_HOST: ${AGENTA_AGENT_RUNNER_HOST:-0.0.0.0}
AGENTA_AGENT_RUNNER_TOKEN: ${AGENTA_AGENT_RUNNER_TOKEN:-}

PI_CODING_AGENT_DIR: /pi-agent
# Tracing export fallback (used when a request carries no usable OTLP
# credential). Must be reachable from this container.
Expand Down
4 changes: 4 additions & 0 deletions hosting/docker-compose/oss/docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,10 @@ services:
# its own port plus optional runner-scoped provider credentials.
environment:
PORT: "8765"
# Bind on all interfaces: the co-located Python `services` container reaches the
# sidecar over the compose network at `sandbox-agent:8765`, so the trust-model
# default of `127.0.0.1` (same-host only) is unreachable cross-container.
AGENTA_AGENT_RUNNER_HOST: ${AGENTA_AGENT_RUNNER_HOST:-0.0.0.0}
Comment on lines 445 to +450

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Add token env passthrough for optional /run authorization.

AGENTA_AGENT_RUNNER_HOST is opened to all interfaces, but AGENTA_AGENT_RUNNER_TOKEN is missing from the allowed env list. Since sandbox-agent has no env_file, this blocks enabling the server’s token check via normal env configuration.

Suggested patch
         environment:
             PORT: "8765"
             # Bind on all interfaces: the co-located Python `services` container reaches the
             # sidecar over the compose network at `sandbox-agent:8765`, so the trust-model
             # default of `127.0.0.1` (same-host only) is unreachable cross-container.
             AGENTA_AGENT_RUNNER_HOST: ${AGENTA_AGENT_RUNNER_HOST:-0.0.0.0}
+            AGENTA_AGENT_RUNNER_TOKEN: ${AGENTA_AGENT_RUNNER_TOKEN:-}
             PI_CODING_AGENT_DIR: /pi-agent
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
environment:
PORT: "8765"
# Bind on all interfaces: the co-located Python `services` container reaches the
# sidecar over the compose network at `sandbox-agent:8765`, so the trust-model
# default of `127.0.0.1` (same-host only) is unreachable cross-container.
AGENTA_AGENT_RUNNER_HOST: ${AGENTA_AGENT_RUNNER_HOST:-0.0.0.0}
environment:
PORT: "8765"
# Bind on all interfaces: the co-located Python `services` container reaches the
# sidecar over the compose network at `sandbox-agent:8765`, so the trust-model
# default of `127.0.0.1` (same-host only) is unreachable cross-container.
AGENTA_AGENT_RUNNER_HOST: ${AGENTA_AGENT_RUNNER_HOST:-0.0.0.0}
AGENTA_AGENT_RUNNER_TOKEN: ${AGENTA_AGENT_RUNNER_TOKEN:-}

PI_CODING_AGENT_DIR: /pi-agent
AGENTA_HOST: ${AGENTA_HOST:-}
AGENTA_API_KEY: ${AGENTA_API_KEY:-}
Expand Down
4 changes: 4 additions & 0 deletions hosting/docker-compose/oss/docker-compose.gh.yml
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,10 @@ services:
# === CONFIGURATION ======================================== #
environment:
PORT: "8765"
# Bind on all interfaces: the co-located Python `services` container reaches the
# sidecar over the compose network at `sandbox-agent:8765`, so the trust-model
# default of `127.0.0.1` (same-host only) is unreachable cross-container.
AGENTA_AGENT_RUNNER_HOST: ${AGENTA_AGENT_RUNNER_HOST:-0.0.0.0}
Comment on lines 348 to +353

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Keep auth configurable in GH stack by wiring runner token env.

This compose file exposes the runner on 0.0.0.0 but does not pass AGENTA_AGENT_RUNNER_TOKEN. That prevents enabling the /run auth gate without modifying compose again.

Suggested patch
         environment:
             PORT: "8765"
             # Bind on all interfaces: the co-located Python `services` container reaches the
             # sidecar over the compose network at `sandbox-agent:8765`, so the trust-model
             # default of `127.0.0.1` (same-host only) is unreachable cross-container.
             AGENTA_AGENT_RUNNER_HOST: ${AGENTA_AGENT_RUNNER_HOST:-0.0.0.0}
+            AGENTA_AGENT_RUNNER_TOKEN: ${AGENTA_AGENT_RUNNER_TOKEN:-}
             AGENTA_HOST: ${AGENTA_HOST:-}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
environment:
PORT: "8765"
# Bind on all interfaces: the co-located Python `services` container reaches the
# sidecar over the compose network at `sandbox-agent:8765`, so the trust-model
# default of `127.0.0.1` (same-host only) is unreachable cross-container.
AGENTA_AGENT_RUNNER_HOST: ${AGENTA_AGENT_RUNNER_HOST:-0.0.0.0}
environment:
PORT: "8765"
# Bind on all interfaces: the co-located Python `services` container reaches the
# sidecar over the compose network at `sandbox-agent:8765`, so the trust-model
# default of `127.0.0.1` (same-host only) is unreachable cross-container.
AGENTA_AGENT_RUNNER_HOST: ${AGENTA_AGENT_RUNNER_HOST:-0.0.0.0}
AGENTA_AGENT_RUNNER_TOKEN: ${AGENTA_AGENT_RUNNER_TOKEN:-}
AGENTA_HOST: ${AGENTA_HOST:-}

AGENTA_HOST: ${AGENTA_HOST:-}
AGENTA_API_KEY: ${AGENTA_API_KEY:-}
SANDBOX_AGENT_PROVIDER: ${SANDBOX_AGENT_PROVIDER:-local}
Expand Down
21 changes: 13 additions & 8 deletions services/agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

The Node side of the agent workflow service. It runs the actual agent loop and serves one
contract: a JSON request in, a structured result out. The Python service
(`services/oss/src/agent/`) decides *what* to run (config, tools, secrets, trace) and calls
in here; this package *runs* it. It lives in Node because the harnesses (Pi, Claude Code,
(`services/oss/src/agent/`) decides _what_ to run (config, tools, secrets, trace) and calls
in here; this package _runs_ it. It lives in Node because the harnesses (Pi, Claude Code,
and the `sandbox-agent` package) are Node libraries with no Python SDK.

## How it is invoked
Expand Down Expand Up @@ -36,8 +36,8 @@ src/
callback.ts the one /tools/call HTTP client
code.ts execute resolved code tools in a scoped subprocess
dispatch.ts dispatch resolved tools by executor kind
mcp-bridge.ts build the MCP server config that exposes tools to a harness
mcp-server.ts the stdio MCP server itself (launched per session by the daemon)
mcp-bridge.ts stdio MCP bridge — DISABLED (throws MCP_UNSUPPORTED_MESSAGE)
mcp-server.ts the stdio MCP server — REMOVED (refuses to serve; no longer launched)
extensions/
agenta.ts the Pi extension (tracing + tools), bundled into dist/ for Pi to load
```
Expand Down Expand Up @@ -85,10 +85,15 @@ live workflow span.
## Tools

Tools are resolved in the Python backend and arrive on the request as `customTools` plus a
`toolCallback`. Delivery is capability-routed: the Pi extension registers them natively;
other harnesses get them over MCP through `tools/mcp-bridge.ts` + `tools/mcp-server.ts`.
Either way each call POSTs back to Agenta's `/tools/call` (`tools/callback.ts`), so the
provider key and connection auth stay server-side.
`toolCallback`. The Pi extension registers them natively, and each call POSTs back to Agenta's
`/tools/call` (`tools/callback.ts`) so the provider key and connection auth stay server-side.

The stdio MCP delivery path that exposed tools to non-Pi harnesses (`tools/mcp-bridge.ts` +
`tools/mcp-server.ts`) is **disabled** in the sidecar — it launched an unconfined child process
on the runner host, the same execution bypass that had code tools removed. Until the security is
fixed, delivering a tool over MCP throws `MCP_UNSUPPORTED_MESSAGE`, so a non-Pi harness (e.g.
Claude) cannot take custom tools, and the run plan refuses any request carrying a stdio MCP
server. See `docs/design/agent-workflows/projects/sidecar-trust-and-sandbox-enforcement/`.

## The extension bundle

Expand Down
33 changes: 18 additions & 15 deletions services/agent/src/engines/sandbox_agent/mcp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,38 @@ import type {
ResolvedToolSpec,
ToolCallbackContext,
} from "../../protocol.ts";
import { buildToolMcpServers, type McpServerStdio } from "../../tools/mcp-bridge.ts";
import {
buildToolMcpServers,
MCP_UNSUPPORTED_MESSAGE,
type McpServerStdio,
} from "../../tools/mcp-bridge.ts";

type Log = (message: string) => void;

/**
* Convert user-declared MCP servers (already resolved server-side, secrets injected into
* `env`) into ACP stdio entries. Only `stdio` is delivered over ACP today.
* Convert user-declared MCP servers into ACP stdio entries — DISABLED in the sidecar.
*
* A stdio MCP server launches an arbitrary process on the runner host, outside the sandbox
* boundary, so the implementation is disabled until its security is fixed (parity with the
* removed code execution; see `tools/mcp-bridge.ts`). The wire shape (`McpServerConfig`) is
* kept, but any stdio server throws `MCP_UNSUPPORTED_MESSAGE` rather than being delivered.
* Remote (`http`) servers were never delivered over ACP and are still skipped (logged), so a
* request carrying only remote servers stays a no-op.
*/
export function toAcpMcpServers(
servers: McpServerConfig[] | undefined,
log: Log = () => {},
): McpServerStdio[] {
const out: McpServerStdio[] = [];
for (const s of servers ?? []) {
if ((s.transport ?? "stdio") !== "stdio" || !s.command) {
log(`skipping non-stdio MCP server '${s?.name ?? "?"}' (remote transport deferred)`);
log(
`skipping non-stdio MCP server '${s?.name ?? "?"}' (remote transport deferred)`,
);
continue;
}
if (s.tools && s.tools.length > 0) {
log(`MCP server '${s.name}': per-server tool allowlist not enforced over ACP (v1)`);
}
out.push({
name: s.name,
command: s.command,
args: s.args ?? [],
env: Object.entries(s.env ?? {}).map(([name, value]) => ({ name, value: String(value) })),
});
throw new Error(MCP_UNSUPPORTED_MESSAGE);
}
return out;
return [];
}

export interface BuildSessionMcpServersInput {
Expand Down
Loading
Loading