Used for feedback · quests · score card
Poke around the existing system with curl. Understand how MCP's tools/list and tools/call work in practice.
Before building anything, let's understand how the existing system works by talking directly to the MCP server
and agent using curl.
This will help you understand the exact protocol you'll implement in Modules 4 and 5.
Both the MCP server and agent expose health endpoints. Check that they're running:
# MCP Server health curl http://localhost:8000/health | python3 -m json.tool # Agent health curl http://localhost:8001/health | python3 -m json.tool
Both should return {"status": "ok"} with some metadata.
This is the MCP discovery call. The agent does this at startup to learn what tools are available:
curl -X POST http://localhost:8000/message \
-H "Content-Type: application/json" \
-H "MCP-Protocol-Version: 2026-07-28" \
-H "Mcp-Method: tools/list" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}' \
| python3 -m json.tool
Study the response. You'll see a JSON-RPC response with a result.tools array.
Each tool has:
name — unique identifierdescription — what the tool does (the LLM reads this!)inputSchema — JSON Schema defining expected argumentsKey insight: The agent never hardcodes tool definitions. It reads them from this endpoint. When you add a new tool to the MCP server, the agent discovers it automatically.
Now call the weather tool directly, bypassing the agent. This is exactly what the agent does internally:
curl -X POST http://localhost:8000/message \
-H "Content-Type: application/json" \
-H "MCP-Protocol-Version: 2026-07-28" \
-H "Mcp-Method: tools/call" \
-H "Mcp-Name: get_weather_forecast" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"get_weather_forecast","arguments":{"location":"Bergen"},"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}' \
| python3 -m json.tool
Study the response structure. The MCP response has:
content — array of content blocks (text, images, etc.)structuredContent — machine-readable JSON dataisError — whether the tool execution failedNow talk to the agent in natural language. The agent will decide which tools to use:
curl -X POST http://localhost:8001/query \
-H "Content-Type: application/json" \
-d '{"query": "What is the weather like in Oslo?"}' \
| python3 -m json.tool
Behind the scenes, the agent: (1) sent your query to the LLM, (2) the LLM decided to call
get_weather_forecast, (3) the agent called the MCP server,
(4) the LLM synthesized the result into natural language.
Understanding error cases is important. Try these and observe the responses:
# Call a tool that doesn't exist curl -X POST http://localhost:8000/message \ -H "Content-Type: application/json" \ -H "MCP-Protocol-Version: 2026-07-28" \ -H "Mcp-Method: tools/call" \ -H "Mcp-Name: nonexistent_tool" \ -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"nonexistent_tool","arguments":{},"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}' # Call a method that doesn't exist curl -X POST http://localhost:8000/message \ -H "Content-Type: application/json" \ -H "MCP-Protocol-Version: 2026-07-28" \ -H "Mcp-Method: does/not/exist" \ -d '{"jsonrpc":"2.0","id":4,"method":"does/not/exist","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}' # Ask the agent something that doesn't need tools curl -X POST http://localhost:8001/query \ -H "Content-Type: application/json" \ -d '{"query": "What is 2+2?"}'
Notice: The MCP server returns proper JSON-RPC error codes for invalid requests. The agent gracefully handles questions that don't need tools by just answering directly.
Open a separate terminal and watch what happens under the hood:
# Watch all logs make logs # Or just the MCP server make logs-mcp # Or just the agent make logs-agent
Now send a query in another terminal and watch the logs. You'll see the JSON-RPC requests and responses flowing between agent and MCP server in real time.
tools/list and tools/call
content, structuredContent, and isError
Your feedback helps us improve the workshop.
Your handle is sent with this feedback; leave it blank in the header and the submission stays anonymous. Please keep personal data out of the comment too — no name, e-mail address or employer, yours or anyone else's.