MCP integration

Forge as an MCP client and server via forge-mcp.

Model Context Protocol (MCP)

forge-mcp is Forge's Model Context Protocol implementation. It speaks both sides of the wire:

  • Client — connect to external MCP servers and import their tools into a Forge ToolRegistry
  • Server — expose a Forge agent's tools (or the agent itself) over MCP for use by Claude Desktop, Cursor, Codex, and other MCP clients

Client

use forge::mcp::{MCPClient, register_mcp_tools};

let mcp = MCPClient::connect("stdio:./my-mcp-server").await?;
register_mcp_tools(&mcp, &registry).await?;

Every tool the MCP server exposes becomes a Forge ToolDefinition:

  • The MCP tool's JSON schema becomes the input_schema
  • The MCP tool's tier hint becomes ToolTier
  • Required scopes default to ["mcp.<server_id>.<tool_name>"]

When the agent's loop selects an MCP tool, the bridge dispatches the call back through the MCP client. The result rolls up as a normal ToolInvocationRecord.

Supported transports

Transport Use case
stdio: Local subprocess (most common)
http+sse: Remote MCP server over SSE
ws: WebSocket transport

Server

use forge::mcp::McpServer;

let server = McpServer::builder()
    .name("forge-research")
    .version("0.1.0")
    .agent(agent)         // expose the whole agent
    .build()?;

server.serve_stdio().await?;

Or expose individual tools:

let server = McpServer::builder()
    .tool(my_executor)
    .tool(another_executor)
    .build()?;

Capability scoping

When a Forge agent invokes an MCP tool, the agent's ACT must contain the tool's required scopes. The bridge does not relax capability checks for MCP tools — they are first-class Forge tools.

Conversely, when an MCP client calls into a Forge-served tool, the server checks the client's capability via the MCP transport's auth layer. Pair forge-mcp with forge-auth to enforce ACTs over MCP.

Compatibility

forge-mcp targets MCP 2024-11-05 and tracks the live spec. See the MCP repo for protocol details.

Next