Bug
Relay::createHandlerFunction() checks hasNameParameter() (line 285-287) which matches any MCP tool whose input schema has a property called name. When matched, it routes to createNameBasedHandler() which hardcodes a handler accepting only ($name, $selector, $width, $height) — designed for browser automation tools like screenshot/resize.
This breaks all generic API tools that happen to have a name property (e.g. create_product, create_coupon, create_plan). The LLM's arguments get stuffed into the $name parameter as a single object, and all other tool params (site_id, address_required, etc.) are lost.
Reproduction
- Connect to any MCP server that exposes a tool with a
name property in its input schema:
{
"name": "create_product",
"inputSchema": {
"properties": {
"site_id": { "type": "number" },
"name": { "type": "string" },
"address_required": { "type": "boolean" }
},
"required": ["site_id", "name", "address_required"]
}
}
-
Ask the LLM to call the tool.
-
The JSON-RPC tools/call request sent to the MCP server has all arguments nested under "name" instead of flat:
Actual (broken):
{"name": "create_product", "arguments": {"name": {"site_id": 15, "name": "Test Product", "address_required": false}}}
Expected:
{"name": "create_product", "arguments": {"site_id": 15, "name": "Test Product", "address_required": false}}
- Tools without a
name property (e.g. create_customer with email, first_name, etc.) work correctly because they fall through to the generic handler at line 212.
Root cause
Relay.php lines 203-204 and 285-313:
// Line 285 - matches ANY tool with a "name" property
protected function hasNameParameter(array $definition): bool
{
return data_get($definition, 'inputSchema.properties.name') !== null;
}
// Line 298 - hardcoded for browser tools only
protected function createNameBasedHandler(string $toolName): callable
{
return function ($name = null, $selector = null, $width = null, $height = null) use ($toolName): string {
$params = ['name' => $name];
// ...only handles selector, width, height — all other params lost
};
}
Suggested fix
The hasNameParameter check is too broad. It should either:
- Be removed entirely (let all tools use the generic handler at line 212)
- Be narrowed to only match browser automation tools (e.g. check for
selector + name together)
- Check that the tool only has
name/selector/width/height properties before using the specialized handler
The generic handler at line 212 already handles named parameters correctly and works for all tool shapes.
Environment
prism-php/relay v1.8.0
echolabsdev/prism v0.99.22
- PHP 8.3
- MCP server: Cloudflare Worker with Streamable HTTP transport
Bug
Relay::createHandlerFunction()checkshasNameParameter()(line 285-287) which matches any MCP tool whose input schema has a property calledname. When matched, it routes tocreateNameBasedHandler()which hardcodes a handler accepting only($name, $selector, $width, $height)— designed for browser automation tools like screenshot/resize.This breaks all generic API tools that happen to have a
nameproperty (e.g.create_product,create_coupon,create_plan). The LLM's arguments get stuffed into the$nameparameter as a single object, and all other tool params (site_id,address_required, etc.) are lost.Reproduction
nameproperty in its input schema:{ "name": "create_product", "inputSchema": { "properties": { "site_id": { "type": "number" }, "name": { "type": "string" }, "address_required": { "type": "boolean" } }, "required": ["site_id", "name", "address_required"] } }Ask the LLM to call the tool.
The JSON-RPC
tools/callrequest sent to the MCP server has all arguments nested under"name"instead of flat:Actual (broken):
{"name": "create_product", "arguments": {"name": {"site_id": 15, "name": "Test Product", "address_required": false}}}Expected:
{"name": "create_product", "arguments": {"site_id": 15, "name": "Test Product", "address_required": false}}nameproperty (e.g.create_customerwithemail,first_name, etc.) work correctly because they fall through to the generic handler at line 212.Root cause
Relay.phplines 203-204 and 285-313:Suggested fix
The
hasNameParametercheck is too broad. It should either:selector+nametogether)name/selector/width/heightproperties before using the specialized handlerThe generic handler at line 212 already handles named parameters correctly and works for all tool shapes.
Environment
prism-php/relayv1.8.0echolabsdev/prismv0.99.22