Skip to content

feat(mcp-bridge): bridge external MCP tools onto the mesh#42

Open
Lanzelot1 wants to merge 2 commits into
mainfrom
feat/mcp-bridge
Open

feat(mcp-bridge): bridge external MCP tools onto the mesh#42
Lanzelot1 wants to merge 2 commits into
mainfrom
feat/mcp-bridge

Conversation

@Lanzelot1

@Lanzelot1 Lanzelot1 commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

What

A new standalone endpoint (implementations/mcp-bridge) that connects to an MCP server once and offers its tools to the whole mesh as a callable service — instead of each agent wiring up its own MCP servers. The MCP server becomes a lateral peer whose service is "run this tool"; Cotal's existing control plane is the call mechanism. No core-protocol changes.

Works with any MCP-compatible server: local stdio, or remote HTTP / SSE, with static bearer/header auth or full interactive OAuth.

How it works

Provider — McpBridge (src/bridge.ts, src/transport.ts)

  • Connects out to the MCP server as a client. Transport is chosen per spec (src/transport.ts): StdioClientTransport, StreamableHTTPClientTransport, or SSEClientTransport. listTools() populates the catalog (multiple servers namespace as <server>.<tool>).
  • Joins the mesh like the manager (CotalEndpoint, consume:false, role: mcp-bridge) and serveControl("mcp", …) with two ops: list (catalog) and call ({tool, arguments}client.callTool → result; MCP isError{ok:false}).

OAuth — src/oauth.ts

  • cotal mcp-bridge login --url <server> runs the interactive flow: a node:http loopback callback + browser open; the SDK does discovery (RFC 9728/8414), dynamic client registration, PKCE, and code exchange. Tokens cache to ~/.cotal/mcp-auth/<service>/ (0600).
  • The daemon (--oauth) loads cached tokens (SDK auto-refreshes); if none, it throws an actionable error pointing at login — no interactive auth from a daemon.

Wire path — the control plane (serveControl/requestControl)

  • Request/reply, queue-grouped (run several bridges of one service to load-balance), authenticated (handler sees a verified req.from.id — the seam a per-caller ACL hooks into). Consumer calls with a 60s timeout.

Consumer — coding agents (connector-core, off by default)

  • Gated behind COTAL_MCP_BRIDGE=1. cotalToolSpecs() appends cotal_tools (list) + cotal_tool (call) via thin MeshAgent helpers — two generic tools, no per-tool JSON-Schema→Zod conversion, no renderer changes.

CLI

cotal mcp-bridge --space <s> -- npx -y @modelcontextprotocol/server-everything   # stdio
cotal mcp-bridge --space <s> --url https://host/mcp --bearer <token>             # remote, static token
cotal mcp-bridge login       --url https://host/mcp                               # remote, OAuth (one-time)
cotal mcp-bridge --space <s> --url https://host/mcp --oauth                        # remote, OAuth (cached token)

Verification

  • pnpm typecheck — clean across all projects.
  • pnpm smoke:mcp-bridge (stdio) — discover → list over mesh → call round-trips → unknown rejected. 4/4.
  • pnpm smoke:mcp-bridge:remote (hermetic, no network):
    • HTTP + static bearer: bearer-gated Streamable HTTP fixture → list/call over the mesh.
    • Full OAuth: a fake auth+resource server (DCR + PKCE + authorize/token); headless login caches a token, then the daemon runs with --oauth off it and calls echo. 4/4.

Conventions

Added @cotal-ai/mcp-bridge to the changeset fixed group + a changeset file, and to the README package table, CLAUDE.md Layout, and docs/release.md.

Follow-ups (deferred)

  • Per-caller ACLs on the call op (gate by the verified req.from.id).
  • Streaming / long-running tool results (one-shot reply today).
  • Multiple servers in one CLI invocation (run one bridge per server today).
  • Deep protocol writeup in docs/architecture.md + SPEC.

🤖 Generated with Claude Code

Lanzelot1 and others added 2 commits June 18, 2026 00:55
A standalone endpoint that connects to an MCP server once and serves its
tools to the whole space over the control plane (list/call on the "mcp"
service). Coding agents opt in via COTAL_MCP_BRIDGE=1 to get cotal_tools /
cotal_tool. Verified by pnpm smoke:mcp-bridge.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bridge remote MCP servers, not just stdio: Streamable HTTP / SSE with static
bearer/header auth or full interactive OAuth (cotal mcp-bridge login caches
tokens to ~/.cotal/mcp-auth; the daemon refreshes them). Adds a hermetic
remote smoke (HTTP+bearer + a fake OAuth/DCR/PKCE server). Also wires the
package into the changeset fixed group, README, CLAUDE.md, and release docs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment thread remotion/src/explainer/S5Topology.tsx Fixed
Comment thread remotion/src/explainer/S5Topology.tsx Fixed
Comment thread remotion/src/explainer/S5Topology.tsx Fixed
Comment thread remotion/src/explainer/S5Topology.tsx Fixed
Comment thread remotion/src/explainer/S5Topology.tsx Fixed
Comment thread remotion/src/explainer/S6Logo.tsx Fixed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant