Skip to content

MCP Integration

The MCP (Model Context Protocol) integration connects external MCP-compatible servers and injects their tools into the agent’s ToolRegistry. The LLM can then call these external tools the same way it calls local tools. The SDK uses NativeMcpBackend on native (via rmcp) and WasmMcpBackend on WASM (via mcp_protocol + Spin HTTP) — the correct backend is selected automatically by target architecture.

[dependencies]
agent_sdk = { package = "pf_agent_sdk", path = "../../crates/agent_sdk", features = ["llm-engine", "mcp-client"] }
  1. Create an MCP servers config file

    The config format is compatible with the industry-standard mcp.json used by Cursor, Claude Desktop, VS Code, and other MCP clients.

    {
    "mcp_servers": {
    "tavily": {
    "command": "npx",
    "args": ["-y", "tavily-mcp@latest"],
    "env": { "TAVILY_API_KEY": "${TAVILY_API_KEY}" }
    }
    }
    }
  2. Load the config and connect

    use agent_sdk::mcp_tools::{McpServersConfig, McpToolAdapter, NativeMcpBackend};
    use agent_sdk::agent::tools::ToolRegistry;
    use std::sync::Arc;
    let config = McpServersConfig::from_file("mcp_servers.json")?;
    let source = NativeMcpBackend::connect(&config).await?;
    let mut tools = ToolRegistry::new();
    McpToolAdapter::register_mcp_tools(&mut tools, Arc::new(source)).await?;
    // tools now contains entries like mcp_tavily_search, mcp_tavily_extract
  3. Wire into the agent

    agent.configure_llm_runtime(
    llm_client,
    "gpt-4o",
    tools,
    Some("You are a helpful assistant with web search.".into()),
    None,
    None,
    )?;
use agent_sdk::Agent;
use agent_sdk::agent::tools::ToolRegistry;
use agent_sdk::mcp_tools::{McpServersConfig, McpToolAdapter, NativeMcpBackend};
use std::sync::Arc;
async fn build_agent_with_mcp(
llm_client: impl agent_sdk::agent::llm_orchestrator::IntoLlmInvoker
+ agent_sdk::agent::llm_orchestrator::IntoLlmStreamInvoker + Clone,
) -> anyhow::Result<Agent> {
let mut agent = Agent::new("mcp-demo")?;
agent
.add_skill("research")
.description("Research topics using web search")
.register()?;
// Load MCP servers config
let config = McpServersConfig::from_file("mcp_servers.json")?;
let source = NativeMcpBackend::connect(&config).await?;
// Register MCP tools into the agent's tool registry
let mut tools = ToolRegistry::new();
McpToolAdapter::register_mcp_tools(&mut tools, Arc::new(source)).await?;
agent.configure_llm_runtime(
llm_client,
"gpt-4o",
tools,
Some("You are a research assistant with web search capabilities.".into()),
None,
None,
)?;
Ok(agent)
}
FieldTypeDescription
commandOption<String>Stdio transport: command to execute (e.g. "npx")
argsVec<String>Arguments to the command
envHashMap<String, String>Environment variables (supports ${VAR} interpolation)
urlOption<String>Remote transport: SSE / streamable HTTP URL
disabledboolSkip this server without removing config
auth_tokenOption<String>Bearer token (supports ${VAR} interpolation)
forward_caller_authboolForward inbound Authorization header to MCP server
tool_policyOption<ToolPolicy>Tool exposure filtering
FieldTypeDescription
exposeVec<String>Allowlist of tool names (empty = expose all)
denyVec<String>Denylist (takes precedence over expose)
TransportConfig triggerWASMNativeBackend
Stdiocommand is setNoYesNativeMcpBackend (spawns child process)
Remoteurl is setYesYesWasmMcpBackend (WASM) / NativeMcpBackend (native)

MCP tools are registered with the naming pattern mcp_<server_id>_<tool_name>. Underscores are used instead of dots because LLM providers like OpenAI restrict tool names to ^[a-zA-Z0-9_-]+$.

TypeModulePurpose
McpToolAdapteragent_sdk::mcp_tools::adapterRegisters MCP server tools into a ToolRegistry
McpServersConfigagent_sdk::mcp_tools::configTop-level config: from_file(), from_json(), enabled_servers()
McpServerEntryagent_sdk::mcp_tools::configSingle server config with transport_type()
McpTransportTypeagent_sdk::mcp_tools::configStdio, Remote, or Unknown
ToolPolicyagent_sdk::mcp_tools::configAllowlist / denylist filtering with is_exposed()
NativeMcpBackendagent_sdk::mcp_tools::nativeNative backend wrapping rmcp
WasmMcpBackendagent_sdk::mcp_tools::wasmWASM backend wrapping mcp_protocol + Spin HTTP
McpToolSourceagent_sdk::mcp_tools::typesTrait: list_tools(), call_tool(), health_check()