MCP Bridge¶
Foundation Protocol is designed to host any Model Context Protocol server as a first-class FP entity. Once registered, the MCP server is addressable like any other entity — agents on the network call its tools through normal INVOKE messages, with the same signing, routing, and checkpoint enforcement as everything else.
What fp/ provides¶
The reference runtime ships the mechanism, not a packaged MCP client. Specifically:
EntityKind.TOOL(andRESOURCE,SERVICE) — classifier tags so application code can branch on entity purpose.- The
metadatadict on every entity — a free-form bag where the convention is to putmcp_config(transport, command, URL, headers). - The checkpoint pipeline with a
handler=callablehook onregister_entity— the supported way to plug in any custom message-dispatch behavior.
What the fp package does not include is a concrete MCPHandler. The bridge between an incoming INVOKE message and the upstream MCP server lives in the application layer — for example in AI-Link-Net — because the choice of MCP client library, process lifecycle, and connection pooling is application policy, not protocol.
The convention¶
When an application layer wires up an MCP bridge on top of FP, it typically:
- Registers a
kind=TOOLentity with anmcp_configmetadata block. - Attaches a callback (or a
BaseHandlersubclass) that knows how to readmcp_configand dispatch. - The callback runs at the tail of the checkpoint pipeline, just like any other handler.
The shape of mcp_config that the example servers and AI-Link-Net both use:
metadata={
"mcp_config": {
"transport": "stdio", # or "http"
"command": ["python", "server.py"], # stdio
# "url": "https://mcp.example.com", # http
# "headers": {"Authorization": "..."}, # http
}
}
Runnable examples¶
The example/ directory has working scripts that drive the full pipeline. They depend on an MCP-handler implementation provided by the runtime in which they're executed (not by fp alone):
example/case_mcp.py— local Host, stdio echo server, caller invokes viaINVOKE.example/case_mcp_http.py— same flow over HTTP transport.example/case_mcp_filesystem.py— driving an official@modelcontextprotocol/server-filesystem.example/case_mcp_list_tools.py— discovery viatools/list.example/case_mcp_cross_host.py— invoking an MCP entity across federated hosts.
The convention these scripts follow — INVOKE payload with {"method": "tools/call", "params": {...}} — is the protocol-level shape. The actual MCP dispatch is performed by the application's handler.
Why bridge instead of using MCP directly¶
You'd want to put an MCP server behind an FP entity when you want:
- Identity and audit — every tool call is signed, routed through the checkpoint pipeline, and recorded in mailboxes.
- Owner observability — see Carbon Copy. Tool invocations made by an owned agent are visible to the owner without changing the tool.
- Federation — the MCP server lives on one host; callers on any federated host can reach it through the parent.
- Policy — checkpoints can enforce rate limits, friend-only access, or contract-gated invocation on top of MCP without modifying the upstream server.
If none of those apply, you can keep using MCP directly. The bridge is a packaging choice, not a requirement.