quickstart-resources/weather-server-ruby/README.md
olaservo 4d79997120 Correct README claims that do not match the repo
The License section named MIT. LICENSE is a transition file: new code
contributions are Apache-2.0, documentation excluding specifications is
CC-BY-4.0, and only earlier contributions without relicensing consent
stay MIT.

"Rust (stable)" understates the floor. rmcp, darling and time declare
rust-version 1.88, and cargo metadata resolves both crates to 1.88.

The Ruby aside said 3.3 also satisfies the gems. anthropic requires
>= 3.2.0 and mcp >= 2.7.0, so the gem floor was 3.2, and 3.2 reached EOL
on 2026-03-31. CI runs 3.4, which is what the READMEs now state.

The Go and Rust clients take a command plus arguments, not a path to a
server script.

Removed the commit-message convention, which is attributed to the MCP
contributing guidelines but does not appear in them. Added the
AI_POLICY.md link that CONTRIBUTING.md points to.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GdvHa5MzDw33PEz3DbTaJD
2026-08-28 10:51:08 -07:00

46 lines
2.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# A Simple MCP Weather Server written in Ruby
A minimal MCP server that exposes US weather data from the [National Weather Service API](https://www.weather.gov/documentation/services-web-api) as two tools:
- `get_forecast` – get the forecast for a location (takes `latitude` and `longitude`)
- `get_alerts` – get active weather alerts for a US state (takes a two-letter state code)
This example accompanies the [Build an MCP server](https://modelcontextprotocol.io/docs/develop/build-server) tutorial.
## Prerequisites
- Ruby 3.4+
- Bundler
## Setup and run
```bash
bundle install
bundle exec ruby weather.rb
```
The server communicates over stdio, so running it directly just waits for a client on stdin. To see it in action, launch it from the Ruby client example in this repository:
```bash
cd ../mcp-client-ruby
bundle install
bundle exec ruby client.rb ../weather-server-ruby/weather.rb
```
## Structured content
Both tools declare an `output_schema` and return `structured_content`. `get_forecast` returns an object; `get_alerts` returns a top-level JSON array, which protocol revision `2026-07-28` is the first to allow — see [Structured Content](https://modelcontextprotocol.io/specification/2026-07-28/server/tools#structured-content) in the spec.
Declaring `type:` at the root of an `output_schema` is what makes the array case work. The SDK applies a `type: "object"` default only when the schema declares no root keyword, so `output_schema(type: "array", items: {...})` is taken as written.
Because a tool that declares an `output_schema` MUST return conforming structured content, the failure paths return an error result rather than a bare text one — error results are exempt from that requirement. "No alerts" is an empty array, not an error.
The tools also return a human-readable `content` block. When you pass your own `content`, the SDK leaves it alone; if you omit it entirely, the SDK serializes non-object structured content into a text block for you.
## Known limitation: strict `2026-07-28` clients reject this server
The `mcp` gem never emits the `resultType` field on results. The 2026-07-28 schema makes it mandatory — "Servers implementing this protocol version MUST include this field" — so a client that enforces the revision rejects every response, including `tools/list`, before it ever reaches the structured content.
There is no way to set it from user code: `MCP::Server` accepts `ttl_ms:` and `cache_scope:` for the SEP-2549 cache hints, but nothing for `resultType`. The gem's own client does not check the field, so the gap is invisible when a Ruby client talks to a Ruby server, and only appears cross-SDK.
Until the gem emits `resultType`, this example is verified only against the Ruby client. Note also that an array-rooted schema requires a `2026-07-28` client regardless: the gem sends it as written rather than projecting it down, so a `2025-11-25` client rejects the tool list.