Chapter 06 · 6 min read
Connect your real systems with MCP
Use the Model Context Protocol to reach your CRM, database or booking system, read-only first.
The tools in the last chapter were functions inside your worker. That is fine for one worker. Once several workers (or ChatGPT, Claude Desktop and your own scripts) need the same systems, write the connection once as an MCP server and let every client use it.
What MCP is
The Model Context Protocol is an open standard for exposing tools and data to AI models. An MCP server wraps one of your systems (a CRM, a database, a booking calendar) and publishes a list of tools with names, descriptions and schemas. Any MCP-capable client can connect and use them. You write the integration once, and you control exactly what it exposes.
Two ways to use an MCP server from Claude
1. Let Anthropic connect to a remote server
If your MCP server is reachable over HTTPS, the API can connect to it directly. Both halves are required: the server in mcp_servers, and an mcp_toolset entry in tools with the same name.
response = client.beta.messages.create(
model="claude-opus-5-5",
max_tokens=16000,
betas=["mcp-client-2025-11-20"],
mcp_servers=[{
"type": "url",
"url": "https://crm-mcp.example.com/mcp",
"name": "crm",
"authorization_token": CRM_MCP_TOKEN, # from your settings, never hard-coded
}],
tools=[{"type": "mcp_toolset", "mcp_server_name": "crm"}],
messages=[{"role": "user", "content": "Which open deals have not been touched in 30 days?"}],
)
To allow only some of the server's tools, give the toolset a default_config of {"enabled": false} and switch individual tools on in configs.
2. Connect from your own code
For a local MCP server, or when you want full control of the connection, the Python SDK converts MCP tools for the tool runner (install anthropic[mcp]):
from anthropic import AsyncAnthropic
from anthropic.lib.tools.mcp import async_mcp_tool
from mcp import ClientSession
from mcp.client.stdio import stdio_client, StdioServerParameters
client = AsyncAnthropic()
async with stdio_client(StdioServerParameters(command="crm-mcp-server")) as (read, write):
async with ClientSession(read, write) as mcp:
await mcp.initialize()
tools = (await mcp.list_tools()).tools
runner = client.beta.messages.tool_runner(
model="claude-opus-5-5",
max_tokens=16000,
tools=[async_mcp_tool(t, mcp) for t in tools],
messages=[{"role": "user", "content": "Summarise this week's new leads."}],
)
async for message in runner:
print(message)
Read-only first
The safest way to connect a business system is in stages:
- Read-only. The server exposes lookups and searches only. Nothing it does can change your data. Run it like this for a few weeks and read the logs.
- Safe writes. Add actions that are easy to undo: create a draft, add a note, tag a record.
- Gated writes. Actions that are hard to undo (send, refund, delete) go through an approval step, described in the next chapter.
Designing the server
- Use a dedicated account for the MCP server with only the permissions its tools need. Never the admin account.
- Expose tasks, not tables.
find_overdue_invoicesis safer and easier for the model than a rawrun_sql. - Log every call: which tool, which inputs, which client, and the result. When something goes wrong, the log is how you find out what happened.
- Treat its output as data. Text that comes back from your systems (a customer note, an email body) can contain instructions someone planted. The next chapter covers why that matters.