Skip to content

mcp-server 1.5.0: optional params normalize; schemas declare fields (RT #1505) - #31

Merged
fatherlinux merged 3 commits into
mainfrom
mcp-optional-params
Sep 26, 2026
Merged

fatherlinux merged 3 commits into
mainfrom
mcp-optional-params

Conversation

@fatherlinux

Copy link
Copy Markdown
Member

Adds four Layer 2 rules to the MCP Server profile, plus the matching test requirements. They come from RT #1505, where every Metsuke gather failed after Kagetora moved to openai/gpt-6-luna.

  • Optional parameters normalize, they don't reject: ""/whitespace, null, and non-positive IDs become None. Required parameters stay strict.
  • No free-form object parameters: a bare list[dict] payload got [{}, {}, {}, {}] from Luna.
  • description on every field.
  • Constraints in the published schema (ge=1 on IDs, length, format), so Trentina's schema-driven normalization (Schema-driven argument normalization for optional tool parameters mcp-trentina#241) can act on them.
  • Tests: optional-field normalization, and assertions against the registered tool schema.

mcp-metsuke 1.0.0/1.1.0 and mcp-feed-reader 0.2.2 already comply. Other servers adopt the rules as they're touched.

🤖 Generated with Claude Code

https://claude.ai/code/session_01ReQxcDTpbWp8dzyPYf5bMp

…RT #1505)

Luna fills every optional tool parameter with 0 or ""; servers that
rejected those produced tool errors, and three in a row lock an agent out
of the whole MCP server. Normalize optional blanks to None, keep required
params strict, forbid free-form object params (they yield {} from strict
tool-calling models), describe every field, and put constraints in the
published schema so a gateway can tell valid from invalid.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ReQxcDTpbWp8dzyPYf5bMp

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gatehouse found 4 issues (3 medium, 1 low)

Comment thread profiles/mcp-server.md
- Pydantic models enforce strict data types with `extra="forbid"`
- Allowlists for permitted values (states, scopes, statuses)
- Resource identifiers validated against injection patterns
- **Optional parameters normalize, they don't reject.** An optional value of `""` (or whitespace only), `null`, or a non-positive ID means "not given" and becomes `None`. Required parameters keep rejecting empty values. Models from the OpenAI family send every optional parameter rather than omitting it, and each rejection is a tool error an agent's client may count against the whole server (RT #1505).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MEDIUM (Bug Hunter): The requirements conflict for optional ID fields. Line 36 says non-positive IDs normalize to None, which means those inputs are accepted; line 39 requires ge=1 in the published schema, which marks them invalid. The same mismatch applies to empty strings for typed ID fields. A gateway relying on the schema may reject inputs before the normalization rule can run.

Suggestion: Make the requirements consistent: either have the published schema represent all accepted normalization inputs, or clarify that gateways must allow these inputs through to server-side normalization and that ge=1 applies only after normalization.

Evidence:

“An optional value of `""` (or whitespace only), `null`, or a non-positive ID means 'not given' and becomes `None`.” … “ID fields declare `ge=1` … so the published `inputSchema` is enough for a gateway to tell a valid value from an invalid one.”

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in a22d565

Comment thread profiles/mcp-server.md Outdated
- Valid full input
- Invalid/rejected inputs (empty strings, too-long values, extra fields)
- Invalid/rejected inputs (empty required strings, too-long values, extra fields)
- Every optional field: `""` and `null` normalize to `None` (and `0` for ID fields)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MEDIUM (Test Coverage): The required optional-field tests do not cover all normalization cases specified above. The behavior includes whitespace-only values and non-positive IDs, but the checklist names only the empty string, null, and zero. Tests could therefore omit whitespace-only and negative-ID cases while still satisfying this requirement.

Suggestion: Require tests for whitespace-only optional strings and negative IDs, in addition to empty strings, null values, and zero for ID fields.

Evidence:

Line 36 says optional whitespace-only values normalize to None and non-positive IDs mean “not given”; line 287 requires testing only `""` and `null` (and `0` for ID fields).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in a22d565

Comment thread profiles/mcp-server.md Outdated
- Valid full input
- Invalid/rejected inputs (empty strings, too-long values, extra fields)
- Invalid/rejected inputs (empty required strings, too-long values, extra fields)
- Every optional field: `""` and `null` normalize to `None` (and `0` for ID fields)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LOW (Consistency Check): The test requirement covers 0 for ID fields, but the profile says all non-positive optional IDs normalize to None. This leaves negative IDs unspecified in the required test coverage.

Suggestion: Change the test requirement to cover non-positive ID values, or explicitly narrow the normalization rule to zero.

Evidence:

`- Every optional field: `""` and `null` normalize to `None` (and `0` for ID fields)` contrasts with line 36: `a non-positive ID means "not given" and becomes `None``.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in a22d565

Comment thread profiles/mcp-server.md
- Pydantic models enforce strict data types with `extra="forbid"`
- Allowlists for permitted values (states, scopes, statuses)
- Resource identifiers validated against injection patterns
- **Optional parameters normalize, they don't reject.** An optional value of `""` (or whitespace only), `null`, or a non-positive ID means "not given" and becomes `None`. Required parameters keep rejecting empty values. Models from the OpenAI family send every optional parameter rather than omitting it, and each rejection is a tool error an agent's client may count against the whole server (RT #1505).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MEDIUM (General Review): The input contract gives conflicting requirements for optional ID fields: non-positive values, including 0, normalize to None, but ID fields must declare ge=1 and the published schema is said to identify valid inputs. A caller following the schema would treat 0 as invalid even though the profile says it should be accepted and normalized.

Suggestion: Clarify whether the schema describes raw inputs or normalized values, and make the ID constraint guidance consistent with the intended treatment of 0 and other non-positive values.

Evidence:

`An optional value of ... a non-positive ID means "not given" and becomes None` (line 36); `ID fields declare ge=1` and the schema should tell a gateway a valid value from an invalid one (line 39).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in a22d565

…yer; full test matrix

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ReQxcDTpbWp8dzyPYf5bMp

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gatehouse found 1 issues (1 low)

Comment thread CHANGELOG.md Outdated

### Added
- **MCP Server profile 1.5.0** — Layer 2 tool-input rules from RT #1505:
optional parameters normalize `""`/`null`/non-positive IDs to `None`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LOW (Consistency Check): The changelog summarizes optional-value normalization but omits whitespace-only strings, which the updated MCP profile explicitly includes as values normalized to None.

Suggestion: Include whitespace-only strings in the changelog summary so it matches the profile's stated behavior.

Evidence:

Changelog: `optional parameters normalize ""/null/non-positive IDs to None`; profile: `An optional value of "" (or whitespace only), null, or a non-positive ID means "not given"`.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in 4c98239

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ReQxcDTpbWp8dzyPYf5bMp

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gatehouse found no issues.

@fatherlinux
fatherlinux merged commit fbeb789 into main Sep 26, 2026
12 checks passed
@fatherlinux
fatherlinux deleted the mcp-optional-params branch September 26, 2026 22:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant