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

  1. 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.
  2. Verify the key is active at https://worldmonitor.app/pro.
  3. Strip whitespace and quotes from the env value before passing it.
  4. 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

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.