modelcontextprotocol / modelcontextprotocol/typescript-sdk

prompts/get rejects omitted `arguments` when all argsSchema fields are optional; tools fix (#1404) not in 1.x

Open
#1,869 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug fix proposed P2 ready for work
Dominant language
TypeScript
Stars
13.4k
Forks
2.2k
Avg merge
3d 15h
Merged PRs (30d)
4

Description

Describe the bug

The same "missing arguments rejected when all schema fields are optional" pattern fixed for tools in #1404 still affects prompts, and #1404 itself is not in any 1.x release.

Two distinct gaps:

  1. Prompts handler is unfixed (all versions, including main). prompts/get calls safeParseAsync(argsObj, request.params.arguments) without the ?? {} defensive pattern that #1404 introduced for tools. A prompt registered with argsSchema: { context: z.string().optional() } and called with arguments omitted returns MCP error -32602: Invalid arguments for prompt <name>: [{ "code": "invalid_type", "expected": "object", "received": "undefined" }].

  2. Tools fix (#1404) is not in the 1.x line. The fix landed on main on 2026-01-23 but none of the v1.x backport releases (1.27.0, 1.27.1, 1.28.0, 1.29.0 — all tagged as "[v1.x backport]") include it. Users on @modelcontextprotocol/sdk@^1.27.0 still hit the tools-side bug.

To Reproduce

Server (using 1.27.0 or any 1.x):

import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod';

const server = new McpServer({ name: 'test', version: '1.0.0' }, {
  capabilities: { prompts: {}, tools: {} },
});

server.registerPrompt(
  'echo',
  {
    title: 'Echo',
    description: 'Echoes optional context',
    argsSchema: { context: z.string().optional() },
  },
  async (args) => ({
    messages: [{
      role: 'user',
      content: { type: 'text', text: `context: ${args.context ?? 'none'}` },
    }],
  }),
);

Client — any of these fail in the same way:

// Fails: arguments omitted
await client.getPrompt({ name: 'echo' });

// Fails: arguments explicitly undefined
await client.getPrompt({ name: 'echo', arguments: undefined });

Client workaround that succeeds:

await client.getPrompt({ name: 'echo', arguments: {} });

Expected behavior

Per the MCP spec, arguments on prompts/get is OPTIONAL at the request level. A registered prompt where every declared argument is optional should accept a request that omits arguments entirely. The same applies to tools/call (addressed upstream by #1404 on main).

Actual behavior

safeParseAsync(argsObj, undefined) fails because argsObj is the non-optional z.object(...) returned by objectFromShape(), which rejects undefined at the top level. The error propagates to the client as JSON-RPC -32602 "Invalid params".

Root cause is _createRegisteredPrompt in src/server/mcp.ts (around line 567):

argsSchema: argsSchema === undefined ? undefined : objectFromShape(argsSchema),

Wrapped once, the top-level object is never optional, and there's no ?? {} coercion at the parse site (unlike tools, where #1404 added it).

Proposed fix

Mirror #1404 in the prompts handler:

- const parseResult = await safeParseAsync(argsObj, request.params.arguments);
+ const parseResult = await safeParseAsync(argsObj, request.params.arguments ?? {});

Plus backport both the tools fix (#1404) and this prompts fix to the v1.x branch so users on @modelcontextprotocol/sdk@^1.x get consistent behavior.

Affected versions

  • Prompts: 1.27.0 confirmed; the prompt handler bug is present on main as well (PR #1404 only touched the tools path).
  • Tools: 1.27.0, 1.27.1, 1.28.0, 1.29.0 confirmed. Fixed on main by #1404 but not yet in any 1.x release.

Workaround we're using

Transport-layer normalization that sets req.body.params.arguments ??= {} before the request reaches the SDK, for both prompts/get and tools/call. Works across all 1.x versions but is obviously a wart we'd like to drop.

Related

  • #400 — tools side of the same pattern (closed by #1404)
  • #1404 — tools fix, not backported to 1.x, does not cover prompts

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/server/mcp.ts at _createRegisteredPrompt and the prompts/get handler, then compare the corresponding tools path changed by #1404. Verify that omitted arguments are accepted for prompts with entirely optional schemas, and backport both the prompt and tools behavior to the v1.x branch. Done means the documented prompts/get and tools/call cases no longer require transport-layer normalization.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, backend-api-design
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.