Build an agent with the Claude API
The Claude API can connect to remote MCP servers for you: pass the Zonio server in mcp_servers, reference it from tools, and Claude calls Zonio tools during the request, with no MCP client code on your side.
Minimal example
import os
import anthropic
client = anthropic.Anthropic()
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://mcp.zonio.tech/mcp",
"name": "zonio",
"authorization_token": os.environ["ZONIO_API_KEY"],
}],
tools=[{"type": "mcp_toolset", "mcp_server_name": "zonio"}],
messages=[{
"role": "user",
"content": "Find vacant plots over 1 ha zoned for housing in Wieliczka within 800 m of a bus stop.",
}],
)
for block in response.content:
if block.type == "text":
print(block.text)import Anthropic from '@anthropic-ai/sdk'
const client = new Anthropic()
const response = await client.beta.messages.create({
model: 'claude-opus-5-5',
max_tokens: 16000,
betas: ['mcp-client-2025-11-20'],
mcp_servers: [
{
type: 'url',
url: 'https://mcp.zonio.tech/mcp',
name: 'zonio',
authorization_token: process.env.ZONIO_API_KEY,
},
],
tools: [{ type: 'mcp_toolset', mcp_server_name: 'zonio' }],
messages: [
{
role: 'user',
content: 'Find vacant plots over 1 ha zoned for housing in Wieliczka within 800 m of a bus stop.',
},
],
})
for (const block of response.content) {
if (block.type === 'text') console.log(block.text)
}curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: mcp-client-2025-11-20" \
-H "content-type: application/json" \
-d '{
"model": "claude-opus-5-5",
"max_tokens": 16000,
"mcp_servers": [{
"type": "url",
"url": "https://mcp.zonio.tech/mcp",
"name": "zonio",
"authorization_token": "'"$ZONIO_API_KEY"'"
}],
"tools": [{ "type": "mcp_toolset", "mcp_server_name": "zonio" }],
"messages": [{ "role": "user", "content": "What is the zoning of parcel 126101_1.0018.AR_1.100/1?" }]
}'Allow only some tools
Use the toolset's default_config and configs to expose an allowlist. For example, a public chatbot that may search and read but never create reports:
tools=[{
"type": "mcp_toolset",
"mcp_server_name": "zonio",
"default_config": {"enabled": False},
"configs": {
"search_parcels": {"enabled": True},
"locate_parcel": {"enabled": True},
"get_parcel": {"enabled": True},
"check_regulations": {"enabled": True},
"check_constraints": {"enabled": True},
},
}]A key with only parcels:read and search:read scopes enforces the same limit server-side.
A system prompt that works
You are a land-acquisition assistant for Poland, backed by Zonio's national parcel data.
- Use Zonio tools for every factual claim about a parcel, zoning, constraint or distance.
- When a tool returns coverage entries with status "missing", tell the user which criteria
could not be checked in that region. Never describe an unchecked parcel as clean.
- Quote parcel ids exactly and include the map_url for every parcel you recommend.
- Give areas in m² under 1 ha and in ha above; distances in m under 1 km and km above.
- Reply in the user's language (Polish or English).Production checklist
- Use one Zonio key per deployment with only the scopes you need, and rotate it like any secret.
- Stream long answers. Site-selection runs call several tools; use
client.beta.messages.stream(...)so users see progress. - Log
Zonio-Request-Id. MCP tool results include it in_metaso you can trace any answer back to the data that produced it. - Cache the system prompt and tool list with prompt caching; both are stable across requests.