Model Context Protocol lets you expose tools once and have them work across any host that speaks it. The protocol work is small; the design work is choosing what to expose and how to describe it.
The shape of a server
01tools/listReturn every tool with a complete JSON schema — required fields, types, enums. The host validates against this before anything runs.
02tools/callExecute and return content. Failures come back as a result with an error flag, never as a thrown exception.
03Transportstdio for local hosts, HTTP for remote. Neither is where interesting problems happen.
Design choices that decide accuracy
- —Keep the tool count low — selection accuracy degrades noticeably past roughly 15–20 tools.
- —Name tools for the intent they serve (orders.lookup), not the endpoint they wrap (get_v2_order_by_id).
- —Write descriptions that say when not to use the tool; the negative case prevents more misfires than the positive one.
- —Mark required arguments in the schema so the host rejects malformed calls before execution.
- —Rate limit per session so a confused model fails cheaply.
What to test
01Schema validityEvery tool lists with a schema a host can actually validate against.
02Missing argumentsA call without a required field is rejected, not half-executed.
03Unknown toolsReturns a structured error rather than raising.
04Rate limitingEnforced per session, verified by test rather than assumed.
05Round tripA real client completes list → call → result over the transport.




