feat(mcp): add MCP-029, PHP tool has no type-annotated parameters - #80
Open
eulestadt wants to merge 2 commits into
Open
feat(mcp): add MCP-029, PHP tool has no type-annotated parameters#80eulestadt wants to merge 2 commits into
eulestadt wants to merge 2 commits into
Conversation
PHP type hints are optional and discovery already captures HasTypedParams; this is the MCP-002 sibling the rulebook listed as a deliberate fast-follow. Co-authored-by: Cursor <cursoragent@cursor.com>
This was referenced Aug 24, 2026
Author
|
Companion PRs:
|
3 tasks
bradAGI's open PR stack claims MCP-023 through MCP-028. A duplicated rule ID is rejected by the loader at startup, so shipping both would break every scan rather than fail a test. MCP-029 is the first free ID above that stack. Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Renamed this from MCP-023 to MCP-029 before anything else, because #82, #85, #88 and #91 claim 023 through 028. I filed 023 about four minutes earlier, but that's not really the point — Brad's stack occupies the whole run above it, so yielding is one edit for me against five for him. A duplicate rule ID stops the loader at startup rather than failing a test, so two green PRs merging an hour apart would have broken every scan until someone sorted it out. The branch is still named
mcp-023; renaming it would close this PR, so I left it alone.The rule itself: nine of ten packs ship an untyped-parameters rule, and within MCP,
MCP-002covers Python while PHP had nothing. PHP is the only other MCP language where the gap can exist — Go, C# and Rust are statically typed, so the handler signature always constrains the published schema and there's nothing to detect. That's why this is a two-language rule and not a five-language one, and why wideningMCP-002would have been wrong: its fix text prescribes Python annotations.Mechanically, MCP builds the advertised input schema from the handler's parameter type hints. With no hints the schema is unconstrained, so the model sends whatever it infers from the description and the failure lands inside the server as a type error or a quiet coercion, instead of being rejected at the boundary where a schema would catch it.
medium/0.85, matching
MCP-002exactly — high for a heuristic because the signal is structural rather than name-based.I scanned a PHP MCP server with four handlers.
searchDocs($query, $limit)fires.fetchInvoice(string $invoiceId, int $version = 1): arraystays quiet, which covers the hinted-with-a-default shape most likely to trip a naive matcher.ping(): stringstays quiet becausehas_params: truegates it out — without that conjunct every no-arg health check in every PHP server would fire.The fourth handler is the honest part.
HasTypedParamsis set when any parameter carries a type, so one hint silences the whole signature —mixedHints(string $query, $limit)reports nothing despite$limitbeing bare. I checked that with a scan rather than assuming it from the code. It's the reason for 0.85, and tightening it would mean an all-params-typed predicate that changesMCP-002and eight other packs, so it belongs in its own PR. Schemas published outside the signature and#[McpResource]/#[McpPrompt]are out of scope too.has_paramsandhas_typed_paramsboth already ship, so no schema bump. Fixture mirror is trustabl#124 and the rationale is trustabl-rulebook#45; this one needs to merge first, sincerules-synccan't see a fork branch and the engine check stays red until it does.Made with Cursor