Skip to main content

Module mcp

Module mcp 

Source
Expand description

MCP client configuration and optional independent server support. MCP client construction and independently owned server lifecycle.

McpClientConfig selects stdio or Streamable HTTP plus naming and interaction policy. Construction is passive; crate::Toolset::mcp connects. The optional mcp-server feature adds a server whose consuming shutdown settles serving work while the caller retains separate toolset shutdown authority.

§Invoke an explicitly configured service

This example requires a running Streamable HTTP server at the configured URL, with an echo tool accepting {"text":"hello"} and returning that text. MCP invocation arguments must be JSON objects. Supply any required authentication through the explicit header map. Namespaces affect public selection; they do not rename the native tool. Never infer a server endpoint from a Toolset. A request timeout bounds calls, not a whole application scenario.

use std::time::Duration;
use tools_kit::{Toolset, ToolsetBackend, ToolHandlerBackend, ToolError};
use tools_kit::declaration::ToolName;
use tools_kit::execution::{ToolContent, ToolHandlerInput, ToolHandlerOutput, ToolInvocation};
use tools_kit::mcp::{McpClientConfig, McpConnectionConfig};
let config = McpClientConfig::new(McpConnectionConfig::StreamableHttp {
    endpoint: "http://127.0.0.1:8000/mcp".parse().unwrap(),
    headers: Default::default(),
}).with_request_timeout(Duration::from_secs(30))?;
let tools = Toolset::mcp(config).await?;
let work = async {
    let name = ToolName::new("echo")?;
    let inventory = tools.list_tools().await?;
    assert!(inventory.iter().any(|info| info.name == name));
    let mut handler = tools.tool_handler(name).await?;
    let output = handler.step(ToolHandlerInput::Invoke(ToolInvocation {
        call_id: Some("owned-call".into()), arguments: serde_json::json!({"text":"hello"}),
    })).await?;
    let ToolHandlerOutput::Completed(result) = output else {
        return Err(ToolError::Protocol { message: "configured echo unexpectedly interacted".into() });
    };
    assert!(!result.is_error);
    assert!(matches!(result.content.as_slice(), [ToolContent::Text { text, .. }] if text == "hello"));
    Ok::<(), ToolError>(())
}.await;
let cleanup = tools.shutdown().await;
work?;
cleanup?;

With mcp-server, the McpServer type’s complete example starts a separately owned loopback server, invokes it through a client, then settles the client, server, and underlying Toolset in that order. Without that feature only client construction is available. A server does not own the caller’s underlying source.

Structs§

McpClientConfig
Validated MCP client Toolset configuration. Configuration construction does not connect or spawn a process; crate::Toolset::mcp performs that work. Discovered names may be namespaced without exposing native routing.
McpServer
Independently owned MCP server serving any concrete ToolsetBackend.
McpServerConfig
Validated independent MCP server configuration. Available with the mcp-server feature. Constructing this value does not bind a socket.

Enums§

McpConnectionConfig
Connection to one MCP server.
McpServerInteractionPolicy
Policy for resolving interactions while serving a Toolset over MCP.