- JavaScript 19.6%
- Rust 17.3%
- Go 16.6%
- TypeScript 13.2%
- Ruby 11.8%
- Other 21.5%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
Some checks failed
Smoke Tests / test (push) Has been cancelled
* Fix the tool-use loop in the Go, Rust, and Ruby clients and add a tool-loop smoke test ## Motivation and Context Only the Python and TypeScript clients implemented a correct tool-use loop. The other three had bugs that break ordinary multi-step requests: - **Go, Rust, Ruby** did a single tool round and then called Claude once more *without* `tools`, so any request that needs a second tool call stalled. Go silently dropped `tool_use` blocks from that final response. - **Ruby** called Claude once per `tool_use` block, each time with a single `tool_result`. Parallel tool calls produced a malformed message sequence and an API 400. - **max_tokens** was 1000 in TypeScript and Ruby, 1024 in Go, and unset in Rust. Sonnet 5 thinks adaptively, so 1000 tokens is regularly exhausted mid-thought. Python already used 10000 with a comment explaining why. - **Ruby** never forwarded MCP `isError` as `is_error`, so the model could not tell a failed tool call from a successful one. Rust cannot set the flag either (see below). - **TypeScript** forwarded raw MCP content blocks to Anthropic. The two block shapes differ, so a non-text result would have failed. The existing smoke test never noticed because it only checks that each client calls `tools/list`. None of these bugs was reachable without an API key. ### What changed All five clients now run the same loop: call tools until Claude answers without one, send every `tool_result` of a turn in one user message, pass `tools` on every call, and stop after `MAX_TOOL_TURNS = 10`. `max_tokens` is 10000 everywhere, with the same comment. Python and TypeScript also keep the last response's text when the turn cap is hit; it used to be dropped. Rust keeps the `genai` crate. Its tool-response type has no `is_error` field, so an error result is marked with an `Error:` prefix in the text and the limitation is commented. ### New smoke test `tests/helpers/tool-loop-test.ts` starts a fake Anthropic Messages API on a loopback port, points a client at it through `ANTHROPIC_BASE_URL`, pipes in one query, and checks every request the client sends. It scripts two parallel tool calls, then a call to a tool the mock server lacks (an `isError` result), then a final answer, and asserts that tools are passed each time, `max_tokens` is 10000, all `tool_result`s arrive in one message with matching ids, and the error is forwarded. `smoke-test.sh` runs it for Python, TypeScript, Go, and Ruby. The Rust client is excluded for now: `genai` reads no endpoint variable, and the client negotiates protocol `2025-11-25`, under which the mock's array-rooted tool is refused at call time. Both will be addressed in a follow-up that brings all examples to current SDK versions. ## How Has This Been Tested? - `./tests/smoke-test.sh` passes for every example. - The new tool-loop test passes all 19 checks for Python, TypeScript, Go, and Ruby. - The Rust client was driven through the same scripted conversation with a temporary endpoint resolver (not committed) and passes. - As a negative check, the Ruby client from `main` was run through the new test. It fails 10 of 19 checks, on exactly the bugs listed above. - Go and Ruby were built and run in `golang:1.25` and `ruby:3.4` containers. ## Breaking Changes None. The clients' command lines, output format, and no-key behavior are unchanged. ## Types of changes - [x] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [x] Documentation update ## Checklist - [x] I have read the [MCP Documentation](https://modelcontextprotocol.io) - [x] My code follows the repository's style guidelines - [x] New and existing tests pass locally - [x] I have added appropriate error handling - [x] I have added or updated documentation as needed ## Additional context Two pre-existing issues surfaced while testing and are left for a follow-up: - The Rust client (rmcp 3.1.2) negotiates `2025-11-25`. The TypeScript mock server and the Python weather server both reject its calls to array-rooted tools under that revision. Even current rmcp defaults to `2025-11-25`, so the client must request `2026-07-28` explicitly. - The Go SDK's tool-result helper sends content as a list of text blocks rather than a string. The API accepts both, so it is unchanged. AI assistance: the analysis, code changes, test helper, and this description were prepared partially manually, partially with Claude Code and reviewed by me. * Improvements * Address comments |
||
| .github/workflows | ||
| mcp-client-go | ||
| mcp-client-python | ||
| mcp-client-ruby | ||
| mcp-client-rust | ||
| mcp-client-typescript | ||
| tests | ||
| weather-server-go | ||
| weather-server-python | ||
| weather-server-ruby | ||
| weather-server-rust | ||
| weather-server-typescript | ||
| .gitattributes | ||
| .gitignore | ||
| LICENSE | ||
| README.md | ||
| SECURITY.md | ||
MCP Quickstart Resources
Example servers and clients for the Model Context Protocol (MCP), in five languages. These are companion examples for two official tutorials:
- Build an MCP server – a simple MCP weather server exposing two tools backed by the US National Weather Service API
- Build an MCP client – an LLM-powered chatbot MCP client that connects to any stdio server and lets Claude call its tools
What's in this repository
Each example lives in its own directory with its own README covering prerequisites, setup, and how to run it:
| Language | Weather server (MCP server) | Chatbot (MCP client) |
|---|---|---|
| Python | weather-server-python |
mcp-client-python |
| TypeScript | weather-server-typescript |
mcp-client-typescript |
| Go | weather-server-go |
mcp-client-go |
| Rust | weather-server-rust |
mcp-client-rust |
| Ruby | weather-server-ruby |
mcp-client-ruby |
All servers communicate over stdio and expose the same two tools: get_forecast and get_alerts (or get-forecast and get-alerts in TypeScript).
All clients launch a server, list its tools, and start an interactive chat loop in which Claude can call those tools. The Python, TypeScript, and Ruby clients take a path to a server script; the Go and Rust clients take the command to run, plus any arguments.
Note: These example clients need an ANTHROPIC_API_KEY to operate. Without a key, each client still connects and lists the server's tools before exiting, so you can verify the MCP wiring without credentials.
You can mix and match across languages: for example, the Python client can drive the TypeScript server. Each client's README lists which server launch forms it supports.
The tests directory contains the smoke tests that run in CI against these examples. See tests/README.md for how they work.
Prerequisites
Each example only needs its own language toolchain. To work across the whole repository (for example, to run the smoke tests) you need:
- Node.js 24+ and npm
- Python 3.10+ and uv
- Go 1.25+
- Rust 1.88+ and Cargo
- Ruby 3.4+ and Bundler
Running the tests
./tests/smoke-test.sh
The smoke tests verify that every server starts and answers MCP requests (including validating structured tool results against the schemas each tool advertises), and that every client can connect to a mock server and list tools. They run automatically on every pull request via GitHub Actions.
Contributing
Contributions are welcome. To submit a change:
- Fork the repository and create a branch from
main. - Make your change. Keep the examples minimal - they exist to teach the protocol, not to be production services.
- If you change an example's behavior, setup, or dependencies, update that example's README to match.
- Run
./tests/smoke-test.shand make sure it passes. - Open a pull request against
maindescribing what changed and why.
A few conventions to follow, in line with the broader Model Context Protocol contributing guidelines:
- Keep documentation clear, concise, and technically accurate. Include code examples where appropriate, and test the commands and links you add.
- Disclose AI assistance. If you used any kind of AI assistance to prepare your contribution, say so in the pull request or issue. See AI_POLICY.md for what the disclosure should cover.
- Be respectful. This project follows the MCP community's Code of Conduct. Concerns can be reported to mcp-coc@anthropic.com.
Security note
These examples are intentionally minimal. If you expose an MCP server over a network (HTTP/SSE/WebSocket), add authentication and basic hardening (CORS allowlist, request size limits, timeouts, rate limits, and log redaction). See SECURITY.md.
License
The MCP project is transitioning from the MIT License to Apache-2.0. New code contributions are licensed under Apache-2.0, and documentation (excluding specifications) under CC-BY-4.0. Earlier contributions whose authors have not consented to relicensing remain under the MIT License. See LICENSE for the full terms.