Use S2SP Servers in Claude
This tutorial shows how to connect two S2SP-enabled MCP servers to Claude Desktop and use natural language to generate weather alert statistics — with the S2SP protocol automatically splitting data between the control plane (what Claude sees) and the data plane (what flows directly between servers).
Demo Video
Watch Claude orchestrate the weather server and stats server in real time. Claude decides which fields to request as abstract domains, filters the alerts, and tells the stats server to generate a chart — all from a single natural language prompt.
Prerequisites
- Claude Desktop installed
- Python 3.10+ with the project's virtual environment set up
- The S2SP repository cloned and installed:
$ git clone <repo-url> $ cd S2S_protocol $ pip install -e ".[demos]"
Setup
Find your Python path
You need the absolute path to the project's Python interpreter:
$ cd /path/to/S2S_protocol $ echo "$(pwd)/.venv/bin/python" # Example: /Users/you/S2S_protocol/.venv/bin/python
Configure Claude Desktop
Open the Claude Desktop configuration file:
# macOS $ open ~/Library/Application\ Support/Claude/claude_desktop_config.json # Or create it if it doesn't exist $ mkdir -p ~/Library/Application\ Support/Claude $ nano ~/Library/Application\ Support/Claude/claude_desktop_config.json
Add the two MCP servers. Replace the Python path with your own:
claude_desktop_config.json
{
"mcpServers": {
"weather": {
"command": "/path/to/S2S_protocol/.venv/bin/python",
"args": ["/path/to/S2S_protocol/demos/weather_agent/weather_server.py"]
},
"stats": {
"command": "/path/to/S2S_protocol/.venv/bin/python",
"args": ["/path/to/S2S_protocol/demos/weather_agent/stats_server.py"]
}
}
}
Restart Claude Desktop
Quit and reopen Claude Desktop. You should see the two servers in the tools panel (click the hammer icon):
- weather —
get_alerts,get_forecast - stats —
draw_chart
Usage
Ask Claude in natural language
Just ask what you want. Claude will figure out which fields to request, how to filter, and when to call the stats server:
# Try these prompts: "Can you get the weather alert statistics about the wind in California?" "Show me severe weather alerts in Texas and generate a chart" "What urgent alerts are active in Florida? Draw statistics." "Get all weather alerts for New York and chart them by event type"
What Happens Behind the Scenes
When you ask "Get wind alert statistics for California", Claude:
Chooses abstract domains
Claude reads your prompt and decides it needs the event field
to filter for wind alerts, plus severity for context. It calls:
get_alerts(area="CA", abstract_domains="event,severity")
The weather server returns only those 2 fields + _row_id per alert
(~600 tokens), plus a resource_url
pointing to the full cached data (~9,000 tokens, not sent to Claude).
Filters on the control plane
Claude examines the abstract rows and selects those where
event contains "Wind":
# Claude sees (control plane): [{"_row_id": 0, "event": "Wind Advisory", "severity": "Moderate"}, {"_row_id": 1, "event": "Flood Watch", "severity": "Minor"}, # skipped {"_row_id": 2, "event": "High Wind Warning", "severity": "Severe"}, ...]
Calls draw_chart with resource reference
Claude passes the filtered abstract rows and the resource reference to the stats server:
draw_chart( abstract_data='[{"_row_id":0,"event":"Wind Advisory","severity":"Moderate"}, ...]', resource_url="http://127.0.0.1:54321/s2sp/data/dK7x_..." )
Stats server fetches body data (data plane)
The stats server connects directly to the weather server's
data plane — POST /s2sp/data/dK7x_...45 — and gets the
full alert data (description, instruction, sender, parameters, etc.) for the
selected rows. Claude never sees this data.
Chart displayed inline
The stats server generates an 8-panel chart and returns it as an image. Claude Desktop displays it directly in the conversation alongside a text summary of the statistics.
More
For MCP Inspector debugging, scripted demos, and implementation details, see Agent Development with S2SP.