koala73/worldmonitor · error · MCPError

-32001

-32001

Error message

MCP error %d: %s%s

What it means

Raised as MCPError inside _rpc() when the MCP server's JSON-RPC response contains an 'error' object (line 287-289); the JSON-RPC error wins over the HTTP status because some transports pair auth failures with HTTP 200. The metadata code -32001 equals MCP_AUTH_ERROR_CODE (line 42), the server's signal that the tools/call invocation needs a user API key that was absent, invalid, expired, or tier-insufficient. The message appends AUTH_HINT when code == -32001 (line 72). MCPError exposes .code and .data.

Source

Thrown at sdk/python/src/worldmonitor_sdk/__init__.py:289

        if params is not None:
            rpc["params"] = params
        headers = self._headers(accept="application/json, text/event-stream")
        headers["content-type"] = "application/json"
        status, content_type, text = self._transport(
            {
                "url": self.mcp_url,
                "method": "POST",
                "headers": headers,
                "body": json.dumps(rpc).encode("utf-8"),
            },
            self.timeout,
        )
        value = 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 isinstance(value, dict) and isinstance(value.get("error"), dict):
            err = value["error"]
            raise MCPError(err.get("code", 0), err.get("message", ""), err.get("data"))
        if status < 200 or status >= 300:
            raise APIError(status, value)
        if isinstance(value, dict) and "result" in value:
            return value["result"]
        return value


def _stringify(value):
    if value is True:
        return "true"
    if value is False:
        return "false"
    return str(value)


__all__ = [
    "API_KEY_HEADER",
    "AUTH_HINT",

View on GitHub (pinned to ffec79ac33)

Solutions

  1. Set the key explicitly: Client(api_key='wm_...') or export WORLDMONITOR_API_KEY; verify with client.health() first (health is public, so a separate failure isolates connectivity).
  2. Inspect e.code: only -32001 is auth — other codes indicate a malformed tool call or server-side tool error; for those, fix the arguments instead of the key.
  3. Confirm the key is active and tier-appropriate at https://worldmonitor.app/pro.
  4. Ensure no leading/trailing whitespace or quote characters in the env value.

Example fix

# before
client = worldmonitor_sdk.Client()  # no key
brief = client.world_brief()  # raises MCPError(-32001)
# after
import os
client = worldmonitor_sdk.Client(api_key=os.environ['WORLDMONITOR_API_KEY'])
brief = client.world_brief()
Defensive patterns

Strategy: validation

Validate before calling

# Validate the key is present BEFORE any tools/call to get a clear local error.
import os
from worldmonitor_sdk import MCP_AUTH_ERROR_CODE

api_key = os.environ.get('WORLDMONITOR_API_KEY') or os.environ.get('WM_API_KEY')
if not api_key:
    raise SystemExit('WORLDMONITOR_API_KEY is required for tools/call; get one at https://worldmonitor.app/pro')
if api_key != api_key.strip():
    raise SystemExit('WORLDMONITOR_API_KEY has surrounding whitespace — strip it')

client = worldmonitor_sdk.Client(api_key=api_key.strip())

Type guard

from worldmonitor_sdk import MCPError, MCP_AUTH_ERROR_CODE

def is_auth_error(exc: Exception) -> bool:
    return isinstance(exc, MCPError) and exc.code == MCP_AUTH_ERROR_CODE

Try / catch

from worldmonitor_sdk import MCPError, MCP_AUTH_ERROR_CODE, WorldMonitorError

try:
    brief = client.world_brief()
except MCPError as e:
    if e.code == MCP_AUTH_ERROR_CODE:
        raise SystemExit('Missing/invalid API key for tools/call. Set WORLDMONITOR_API_KEY.') from e
    raise  # non-auth JSON-RPC error — do not retry blindly
except WorldMonitorError:
    raise

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 setting api_key or WORLDMONITOR_API_KEY/WM_API_KEY. Also fires when a previously valid key is revoked, when a sandbox key is used against production, or when a free-tier key calls a Pro-gated tool. Public methods list_tools()/list_prompts()/list_resources() do NOT trigger it (they are unauthenticated).

Common situations: Local script runs fine but CI lacks the WORLDMONITOR_API_KEY env var. Key value has trailing whitespace or surrounding quotes from a .env loader. Staging key pointed at the production MCP endpoint. A notebook created the Client before os.environ was populated.

Related errors


AI-assisted analysis of koala73/worldmonitor@ffec79ac33 (2026-08-12). Data as JSON: /api/errors/ebb30a311e0869cd. Report an issue: GitHub.