Skip to content

mcp-server-fetch: fetch prompt returns JSON-RPC error code 0 with the raw exception text for an invalid URL #4914

Closed

Description

@ShipItFrog

Describe the bug

The fetch tool validates url through the Fetch model, so a malformed URL comes back as a normal isError: true result. The fetch prompt passes arguments["url"] straight to fetch_url (server.py:262-265) and catches only McpError (server.py:267). fetch_url converts only httpx.HTTPError (server.py:127), and httpx.InvalidURL is not an HTTPError, so it escapes both handlers. With raise_exceptions=False (server.py:288), the SDK's low-level server then answers with a JSON-RPC error whose code is 0 and whose message is the raw exception text.

To Reproduce

mcp-server-fetch 0.6.3 (commit f46d957), mcp 1.29.0 (as in uv.lock), Python 3.14, Windows 11. After initialize, send over stdio:

{"jsonrpc": "2.0", "id": 3, "method": "prompts/get", "params": {"name": "fetch", "arguments": {"url": "http://[::1"}}}

Response:

{"jsonrpc": "2.0", "id": 3, "error": {"code": 0, "message": "Invalid port: ':1'"}}

The same URL through the tool is handled cleanly:

{"jsonrpc": "2.0", "id": 4, "method": "tools/call", "params": {"name": "fetch", "arguments": {"url": "http://[::1"}}}
isError: true — "1 validation error for Fetch\nurl\n  Input should be a valid URL, invalid IPv6 address ..."

Expected behavior

An invalid prompt argument should produce a proper parameter error (-32602, INVALID_PARAMS) with a clear message, consistent with the tool. Code 0 is the SDK's generic fallback for unhandled exceptions, so a client can't tell a bad argument from a server fault.

Suggested fix

Validate the prompt's url the same way the tool does before fetching:

url = arguments["url"]  # current code; replace with:
try:
    url = str(Fetch(url=arguments["url"]).url)
except ValueError as e:
    raise McpError(ErrorData(code=INVALID_PARAMS, message=str(e)))

With this change, the request above returns -32602 with the validation message, and a valid URL still returns the page content (checked locally).

Additional context

Related: #3359 / #3515 (malformed input handling). I found this while testing a static checker for MCP error handling, then reproduced it by hand with a raw JSON-RPC client (no MCP client library involved). Happy to open a PR with this change if that's useful.

Activity

  1. SuparvaCode commented on Oct 8, 2026

    @SuparvaCode

    Confirmed end-to-end against main (commit 5abed86).

    When a prompt argument fails validation, passing it into fetch_url allows httpx.InvalidURL to escape unhandled because fetch_url only handles httpx.HTTPError. With raise_exceptions=False on the stdio server, the low-level server catches the unhandled exception and answers with JSON-RPC error code 0 and the raw exception text.

    Validating arguments["url"] in get_prompt via the existing Fetch model:

    try:
        args = Fetch(url=arguments["url"])
    except ValueError as e:
        raise McpError(ErrorData(code=INVALID_PARAMS, message=str(e)))

    properly rejects malformed URLs with -32602 (INVALID_PARAMS). Additionally, catching httpx.InvalidURL alongside httpx.HTTPError in fetch_url ensures that if an invalid URL reaches fetch_url directly, it is caught as an McpError rather than escaping.

    I've pushed the fix and regression tests on SuparvaCode/servers:fix/fetch-prompt-invalid-url-params. All 24 tests in tests/test_server.py and ruff check pass cleanly.

  2. added
    bugSomething isn't working
    server-fetchReference implementation for the Fetch MCP server - src/fetch
    on Oct 19, 2026
  3. cliffhall commented on Oct 19, 2026

    @cliffhall
    Member

    Triage: Priority Low (total 5)

    • Severity 2: An invalid URL given to the fetch prompt still escapes as an unhandled exception, answered as a JSON-RPC error with code 0 ('Error rendering prompt fetch') rather than INVALID_PARAMS or the prompt's own error text; the message no longer leaks the raw exception after the MCPServer migration, but the code is still wrong.
    • Urgency 2: wanted eventually
    • Bonuses: +1 bug label

    Still present on v2 (checked by a local reproduction against the current code).

    Board: Servers V2 (#43), Status Incoming, awaiting maintainer review (no milestone yet). Part of the backlog triage in #4875.

  4. added this to the v2.3.0 milestone on Oct 25, 2026
  5. self-assigned this
    on Oct 28, 2026
  6. cliffhall commented on Oct 29, 2026

    @cliffhall
    Member

    Shipped in #5358 (merged into v2/main), after the #5271 rollup proved the six fetch v2.3.0 PRs combine with no conflicts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingserver-fetchReference implementation for the Fetch MCP server - src/fetchv2

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions