new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

MCP Server Development in Practice · all subjects

Debugging and testing

4 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

How do I test my server without wiring up a real agent?

Use the MCP Inspector: `npx @modelcontextprotocol/inspector <your-server-command-or-url>`. It gives you an interactive session against your server — initialize, browse tools/list, fire tools/call with hand-written arguments, and see the raw JSON-RPC both directions. It catches the failures clients hide: malformed schemas, wrong content types, missing fields in initialize. Before the Inspector, smoke-test the raw wire format with curl: POST an initialize, then a tools/list, then a tools/call, and confirm a bare request gets your 401 with WWW-Authenticate. Only after both pass should you connect a real client — debugging inside Claude Code conflates your server's bugs with the client's behavior and you cannot see the traffic.

Server connects but tools never fire — where do I look?

Work the pipeline in order. (1) Does tools/list actually reach the model? Connect the Inspector; if your tools appear there but the agent never calls them, the problem is descriptions (the model saw the menu and declined) or client approval settings (the user is being prompted and dismissing it). (2) If tools/list is empty or errors in the Inspector, your initialize handshake or schema serialization is broken — a single invalid JSON Schema field can make a client drop the whole tool list silently. (3) If tools fire but results look ignored, the response shape is wrong for that client (e.g. it expects content[0].type text and you sent only structuredContent). Logging every tools/call server-side settles which stage you are in within minutes.

What should I log on a production MCP server?

Every tools/call, with: tool name, caller identity, latency, success/failure, and enough of the arguments to debug (query text truncated to a few hundred chars — never auth headers or token values). This single table answers the three questions that matter: which tools are never called (description problem), which fail often (implementation problem), and who is hammering you (abuse or an agent in a retry loop). Also log initialize attempts with the client's protocol version — you will discover which client versions actually connect to you. Meter calls in the same table billing reads, including failed calls, or your numbers lie. What NOT to log: bearer tokens, OAuth codes, full request bodies from user data tools — your MCP logs become a secret store otherwise.

JSON-RPC batches and notifications — what bites in production?

Batches are legal JSON-RPC and some clients send them; silently dropping them is a confusing failure, so handle arrays explicitly — but cap the size and process sequentially if your rate limits read state per call (a parallel batch passes every quota check before the first call is recorded). Notifications (requests with no id, like notifications/initialized) must get NO response body — return HTTP 202 with an empty body; echoing a result to a notification violates the protocol and confuses strict clients. Also: some clients probe your endpoint with GET before initializing — answer with something informative (server name, protocol version, transport) rather than a bare 405, so debugging tools and health checks can tell your server is alive.

Give your agent this brain