koala73/worldmonitor · error · MCPError
MCP error #{code}: #{message}
Error message
MCP error #{code}: #{message} What it means
Raised as WorldMonitor::MCPError inside rpc() when the MCP server's JSON-RPC response contains an 'error' hash (line 242-244); the JSON-RPC error takes precedence over the HTTP status because some transports pair auth failures with HTTP 200. The code field carries the JSON-RPC error code: -32001 (MCP_AUTH_ERROR_CODE) means the tools/call needs a valid user API key; other negative codes indicate malformed requests or server-side tool failures. The message appends AUTH_HINT when code == -32001 (line 68). MCPError exposes .code and .data readers.
Source
Thrown at sdk/ruby/lib/worldmonitor.rb:244
h[API_KEY_HEADER] = api_key if api_key
h
end
def rpc(method, params = nil)
body = { "jsonrpc" => "2.0", "id" => 1, "method" => method }
body["params"] = params if params
request_headers = headers(accept: "application/json, text/event-stream")
request_headers["content-type"] = "application/json"
status, content_type, text = @transport.call(
{ url: mcp_url, method: "POST", headers: request_headers, body: JSON.generate(body) },
timeout
)
value = self.class.parse_body(text, content_type)
# A JSON-RPC error object wins over the HTTP status (the server pairs
# auth errors with a 200 on some transports).
if value.is_a?(Hash) && value["error"].is_a?(Hash)
err = value["error"]
raise MCPError.new(err["code"] || 0, err["message"] || "", err["data"])
end
raise APIError.new(status, value) unless (200..299).cover?(status)
value.is_a?(Hash) && value.key?("result") ? value["result"] : value
end
def http_transport(request, timeout)
uri = URI.parse(request[:url])
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == "https"
http.open_timeout = timeout
http.read_timeout = timeout
klass = request[:method] == "POST" ? Net::HTTP::Post : Net::HTTP::Get
req = klass.new(uri.request_uri)
(request[:headers] || {}).each { |k, v| req[k] = v }
req.body = request[:body] if request[:body]
res = http.request(req)
[res.code.to_i, res["content-type"].to_s, res.body.to_s]View on GitHub (pinned to ffec79ac33)
Solutions
- Inspect e.code: -32001 is auth — set api_key: or WORLDMONITOR_API_KEY; other codes indicate a bad tool name or arguments — check them against client.list_tools output.
- Verify the key is active at https://worldmonitor.app/pro.
- Strip whitespace and quotes from the env value before passing it.
- Confirm tool names and required arguments with list_tools before calling unfamiliar tools.
Example fix
# before client = WorldMonitor::Client.new # no key brief = client.world_brief # raises MCPError(-32001) # after client = WorldMonitor::Client.new(api_key: ENV['WORLDMONITOR_API_KEY']) brief = client.world_brief
Defensive patterns
Strategy: validation
Validate before calling
# Validate the key is present BEFORE any tools/call. api_key = ENV['WORLDMONITOR_API_KEY'] || ENV['WM_API_KEY'] raise 'WORLDMONITOR_API_KEY is required for tools/call' if api_key.nil? || api_key.strip.empty? raise 'Key has surrounding whitespace' unless api_key == api_key.strip client = WorldMonitor::Client.new(api_key: api_key.strip)
Type guard
def auth_error?(exc) exc.is_a?(WorldMonitor::MCPError) && exc.code == WorldMonitor::MCP_AUTH_ERROR_CODE end
Try / catch
begin
brief = client.world_brief
rescue WorldMonitor::MCPError => e
if e.code == WorldMonitor::MCP_AUTH_ERROR_CODE
raise 'Missing/invalid API key for tools/call. Set WORLDMONITOR_API_KEY.'
end
raise # non-auth JSON-RPC error — do not retry without fixing the arguments
rescue WorldMonitor::Error
raise
end Prevention
- Pass api_key: or set WORLDMONITOR_API_KEY before the first tools/call in every environment.
- Call client.health right after constructing the Client to fail fast on connectivity.
- Strip whitespace and quotes when loading the key from a dotenv file.
- Branch on e.code: only -32001 is auth — confirm tool names and args with list_tools for other codes.
When it happens
Trigger: Calling any curated helper that maps to tools/call — world_brief, country_risk('IR'), market_data, conflict_events, call_tool('get_market_data', ...) — without api_key or WORLDMONITOR_API_KEY/WM_API_KEY set (yields code -32001). Also fires for non-auth JSON-RPC errors: calling an unknown tool name, passing wrong/missing arguments, or a server-side tool execution failure (codes other than -32001). Public methods list_tools/list_prompts/list_resources do NOT trigger auth errors.
Common situations: Works locally but CI lacks WORLDMONITOR_API_KEY. Key has trailing whitespace from a dotenv loader. Staging key against the production endpoint. A free-tier key calling a Pro-gated tool. Calling a tool name that was renamed in a server update (non-auth error code).
Related errors
AI-assisted analysis of koala73/worldmonitor@ffec79ac33 (2026-08-12).
Data as JSON: /api/errors/31248b192d1ac704.
Report an issue: GitHub.