MCP Integration
Purpose and Scope
Model Context Protocol, or MCP, is a way to expose external capabilities as tools that Claude can call. In this SDK, MCP appears in two related forms. The first is direct Messages API connector usage, where a request names remote MCP servers in mcp_servers. The second is a local helper layer for adapting MCP SDK objects into Anthropic tool and message shapes. This page focuses on those SDK integration points: how to attach a remote server to a streaming message request, how helper functions map MCP tools and content, and how to reason about unsupported MCP values before they become API payloads.
Sources: examples/mcp.ts, tests/helpers/beta/mcp.test.ts
The direct connector path is useful when the MCP server is already reachable over HTTP and the Anthropic API can connect to it. Official Claude docs describe this as connecting to remote MCP servers directly from the Messages API without implementing a separate MCP client, with tool calling, allowlists, per-server configuration, authorization tokens, and multiple servers in one request. The repository example follows that model by constructing anthropic.beta.messages.stream(...) with one URL-based MCP server, then consuming streamed text deltas from the response.
Sources: examples/mcp.ts
The helper path is useful when application code already has an MCP client object and wants the SDK to convert MCP concepts into Anthropic request parts. The test suite imports helper entry points such as mcpTool, mcpTools, mcpMessage, mcpMessages, mcpContent, mcpResourceToContent, and mcpResourceToFile, plus MCPClientLike for the minimal client contract. The tests assert that a Model Context Protocol Tool with a name, description, and inputSchema becomes an Anthropic tool definition with name, description, and input_schema in the outgoing request body.
Sources: tests/helpers/beta/mcp.test.ts
Relevant Source Files
examples/mcp.ts- Runnable example showingAnthropic,anthropic.beta.messages.stream,mcp_servers, URL server configuration, authorization token usage, tool configuration, per-request beta headers, and streamed event consumption.tests/helpers/beta/mcp.test.ts- Behavioral tests for MCP helper exports, including tool conversion, content conversion failures, helper collection/header support, and theMCPClientLikeadapter shape used by helper-driven tool execution.helpers.md- Public helper documentation for message streaming, includinganthropic.messages.stream, async iteration, stream event names, abort behavior, accumulated messages, and final message/text helper methods that inform MCP streaming consumption patterns.
Direct Messages API Connector Flow
The simplest integration is to attach mcp_servers to a beta Messages request. The example creates new Anthropic() and relies on normal SDK credential discovery, then calls anthropic.beta.messages.stream with model, max_tokens, messages, and an mcp_servers array. Each server entry in the example has type: 'url', a public server url, a human-readable name, an authorization_token, and a tool_configuration. That configuration demonstrates the allow-all default while also showing explicit enabled and allowed_tools fields for narrowing the tools Claude may use.
Sources: examples/mcp.ts
const stream = anthropic.beta.messages.stream(
{
model: 'claude-sonnet-5',
max_tokens: 1000,
mcp_servers: [
{
type: 'url',
url: 'http://example-server.modelcontextprotocol.io/sse',
name: 'example',
authorization_token: 'YOUR_TOKEN',
tool_configuration: {
enabled: true,
allowed_tools: ['echo', 'add'],
},
},
],
messages: [{ role: 'user', content: 'Calculate 1+2' }],
},
{ headers: { 'anthropic-beta': 'mcp-client-2025-04-04' } },
);The example consumes the stream with for await (const event of stream) and writes only text deltas when the event is a content_block_delta whose delta is a text_delta. That is intentionally narrower than logging every stream event: MCP tool use may produce non-text events, but the example is a minimal demonstration of presenting final assistant text as it arrives. The repository helper documentation explains the broader stream abstraction: stream helpers expose async iteration, event listeners, abort support, accumulated message state, and finalMessage() or finalText() convenience methods.
Sources: examples/mcp.ts, helpers.md
Helper API Components
The MCP helper tests define the public surface developers should look for when integrating an MCP client in process. mcpTool(tool, client) adapts a single MCP Tool and an object compatible with MCPClientLike. mcpTools(...) is the plural counterpart. mcpMessage and mcpMessages adapt MCP prompt/message data, while mcpContent converts individual MCP content values. Resource helpers, mcpResourceToContent and mcpResourceToFile, cover MCP resource results that need to become Anthropic content or file-like inputs. UnsupportedMCPValueError is the typed failure mode when a supplied MCP value cannot be represented safely.
Sources: tests/helpers/beta/mcp.test.ts
| Component | Role | Source-backed behavior |
|---|---|---|
mcpTool | Convert one MCP Tool into an Anthropic tool definition | Preserves name, description, and maps inputSchema to input_schema in the request body |
MCPClientLike | Minimal client adapter shape | Test doubles provide callTool returning MCP content such as text |
mcpContent | Convert MCP content blocks | Throws UnsupportedMCPValueError for unsupported audio and resource_link content |
mcpResourceToContent | Convert MCP resource output to message content | Exported by the helper module and covered by the MCP helper test suite |
mcpResourceToFile | Convert MCP resource output to file-like input | Exported by the helper module and covered by the MCP helper test suite |
collectStainlessHelpers and stainlessHelperHeader | Internal helper metadata support | Imported by tests to verify helper-aware request behavior |
Implementation and Request Mapping
The clearest source-backed mapping is the tool conversion test. The test constructs an MCP Tool named get_weather, gives it a description, and supplies a JSON Schema-style inputSchema with a required location string. It then creates an Anthropic client with a mocked fetch, sends anthropic.beta.messages.create with tools: [mcpTool(tool, mockClient)], captures the outgoing JSON body, and asserts that the body contains one tool with the same name and description plus input_schema. This proves the helper operates before the HTTP request and produces normal Anthropic tool payloads.
Sources: tests/helpers/beta/mcp.test.ts
const tool = {
name: 'get_weather',
description: 'Get the weather for a location',
inputSchema: {
type: 'object' as const,
properties: { location: { type: 'string', description: 'City name' } },
required: ['location'],
},
};
await anthropic.beta.messages.create({
model: 'claude-opus-4-8',
max_tokens: 1024,
messages: [{ role: 'user', content: 'What is the weather?' }],
tools: [mcpTool(tool, mockClient)],
});The same tests are also a useful boundary guide. They show mcpContent rejecting MCP audio content and resource_link content by throwing UnsupportedMCPValueError, with messages that include the unsupported type name. That means callers should not assume every value from the MCP TypeScript SDK can be forwarded directly to Anthropic APIs. Validate or convert content at the helper boundary, catch UnsupportedMCPValueError where appropriate, and decide whether to omit the unsupported value, replace it with text, or surface a developer-facing configuration error.
Sources: tests/helpers/beta/mcp.test.ts
Streaming, Headers, and Operational Notes
MCP connector requests are beta API requests, so the request options matter. The repository example passes an anthropic-beta header alongside the streaming call. Official docs identify MCP connector availability by a dated beta header and note that newer connector versions may replace older dates, so treat the example’s header as a pattern for where the SDK option belongs rather than as a permanent value. Keep the server URL, server name, authorization token, and allowlist configuration close together in code so reviews can verify which external tools Claude may call.
Sources: examples/mcp.ts
When choosing between the two integration styles, use mcp_servers for remote servers that the Anthropic API should contact directly, and use helper functions when your application owns an MCP client and wants to expose selected MCP tools as normal Anthropic tools. Remote server configuration centralizes connectivity in the API request; helper-based integration centralizes execution in your process through MCPClientLike.callTool. In both cases, tool descriptions and schemas are critical because Claude decides when a tool is relevant from the user request, system prompt, and tool metadata.
Sources: examples/mcp.ts, tests/helpers/beta/mcp.test.ts
Testing Signals and Next Steps
The repository’s MCP tests exercise behavior at the HTTP boundary rather than only checking TypeScript types. By mocking fetch and capturing the serialized body, they verify that helper-produced tools are indistinguishable from ordinary API tools by the time the SDK sends the request. The negative content tests protect the opposite boundary: values with no supported Anthropic representation fail early and explicitly. Together, those tests give maintainers confidence that helper integrations are request-compatible while still rejecting unsupported MCP content categories.
Sources: tests/helpers/beta/mcp.test.ts
To build an MCP integration, start with examples/mcp.ts if your server is remote and HTTP-accessible. Replace the placeholder URL, token, server name, allowed tools, prompt, and beta header with values from the current Claude documentation and your MCP server. If you already use the @modelcontextprotocol/sdk, start from the helper names covered in tests/helpers/beta/mcp.test.ts, wrap your client in the MCPClientLike shape, and add tests that capture outgoing Anthropic request bodies for your most important tool schemas.
Sources: examples/mcp.ts, tests/helpers/beta/mcp.test.ts