Hacktoberfest 2026: die Issues, die Maintainer für den Oktober markiert haben – offen und einsteigerfreundlich. Hacktoberfest-Issues durchsuchen

Default capabilities advertise listChanged, prompts, resources and logging on a tools-only stateless server

Offen
#619 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Maintainer antworten meist innerhalb von 1 Tag

@koic arbeitet bereits daran.

Seit 16.10.2026.

  • #620 von @koic — offen

Bewertung

Schwierigkeit
3/5
Geschätzter Aufwand
1-2 Tage
Anfängerfreundlichkeit
56/100
Issue-Typ
Bug
Klarheit
Klar beschrieben
Aktivitätsstatus
Aktiv
Tech-Stack
ruby

Rechercherichtung

Start by reading MCP::Server#default_capabilities and #discover_capabilities, then trace how the initialize response obtains its capabilities and how stateless transport handles notifications and logging. Compare the initialize and server/discover results for the supplied reproduction. Done means both lifecycles advertise capabilities the server and transport can provide, with tests covering the tools-only stateless case.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

bug

Describe the bug

When capabilities: is not passed, MCP::Server advertises Server#default_capabilities regardless of what the server has or what its transport can deliver:

{ tools: { listChanged: true }, prompts: { listChanged: true }, resources: { listChanged: true }, logging: {} }

On a server with one tool, no prompts, no resources, behind StreamableHTTPTransport.new(server, stateless: true, serve_subscriptions_listen: false), the initialize result still promises:

  • listChanged on tools, prompts and resources, although a stateless transport cannot send notifications/*/list_changed (the transports page says notifications are not supported in stateless mode);
  • prompts and resources, which the server does not have;
  • logging, although request-scoped log messages are skipped in stateless mode.

server/discover already strips listChanged/subscribe when the transport does not serve subscriptions/listen (Server#discover_capabilities, from #533), but initialize does not, so the same server describes itself differently on the two lifecycles. prompts, resources and logging are advertised on both.

To Reproduce

require "bundler/inline"

gemfile do
  source "https://rubygems.org"
  gem "mcp", "1.8.0"
  gem "rack"
end

require "json"

class EchoTool < MCP::Tool
  description "Echoes a message"
  input_schema(properties: { message: { type: "string" } }, required: ["message"])

  def self.call(message:, server_context:)
    MCP::Tool::Response.new([{ type: "text", text: message }])
  end
end

def post(body, headers = {})
  env = Rack::MockRequest.env_for(
    "http://localhost/mcp",
    method: "POST",
    input: JSON.generate(body),
    "CONTENT_TYPE" => "application/json",
    "HTTP_ACCEPT" => "application/json, text/event-stream",
  )
  headers.each { |k, v| env[k] = v }
  Rack::Request.new(env)
end

server = MCP::Server.new(name: "echo", version: "1.0.0", tools: [EchoTool])
transport = MCP::Server::Transports::StreamableHTTPTransport.new(
  server, stateless: true, serve_subscriptions_listen: false
)

_, _, body = transport.handle_request(post(
  jsonrpc: "2.0", id: 1, method: "initialize",
  params: { protocolVersion: "2025-11-25", capabilities: {}, clientInfo: { name: "c", version: "1" } },
))
puts "initialize:      #{JSON.parse(body.first).dig("result", "capabilities").to_json}"

_, _, body = transport.handle_request(post(
  { jsonrpc: "2.0", id: 2, method: "server/discover",
    params: { _meta: { "io.modelcontextprotocol/protocolVersion" => "2026-07-28",
                       "io.modelcontextprotocol/clientInfo" => { name: "c", version: "1" },
                       "io.modelcontextprotocol/clientCapabilities" => {} } } },
  { "HTTP_MCP_PROTOCOL_VERSION" => "2026-07-28", "HTTP_MCP_METHOD" => "server/discover" },
))
puts "server/discover: #{JSON.parse(body.first).dig("result", "capabilities").to_json}"

Output, the same on 1.8.0 and on main at 56af0c7:

initialize:      {"tools":{"listChanged":true},"prompts":{"listChanged":true},"resources":{"listChanged":true},"logging":{}}
server/discover: {"tools":{},"prompts":{},"resources":{},"logging":{}}

Expected behavior

Capabilities that describe what this server can do. The spec (lifecycle, Capability Negotiation) says capabilities "establish which optional protocol features will be available during the session", and tools defines listChanged as "whether the server will emit notifications when the list of available tools changes" (prompts and resources say the same). For the repro, that is {"tools":{}} on both lifecycles.

A client that takes the default at its word waits for a list_changed that cannot arrive and asks for prompts and resources that do not exist. Passing capabilities: { tools: {} } works around it, but the default is what most servers ship with.

Two possible shapes, either would fix it:

  1. Derive the default from the server: tools / prompts / resources only when some are registered (or a list handler is set), logging only when it can be delivered.
  2. At minimum, apply the same stripping discover_capabilities does to the initialize result, and drop listChanged in stateless: true.

I'm happy to send a PR for whichever shape you prefer.

Additional context

  • mcp 1.8.0 (latest release) and main 56af0c7
  • Ruby 3.4.10, rack 3.2.7, macOS
  • Related: #531 / #533 (the serve_subscriptions_listen: false flag and the discover-side stripping), #602 (methods of undeclared capabilities).
Vorherrschende Sprache
Ruby
Sterne
924
Forks
136
Ø Merge
1 T. 6 Std.
Gemergte PRs (30 T.)
39

Entwicklungsumgebung

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus modelcontextprotocol/ruby-sdk

Alle Issues in modelcontextprotocol/ruby-sdk

Ähnliche Issues

Weitere Issues zu Ruby

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.