-
Notifications
You must be signed in to change notification settings - Fork 705
fix(skill-mcp): handle arguments passed as object instead of JSON string #532
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(skill-mcp): handle arguments passed as object instead of JSON string #532
Conversation
When LLMs invoke skill_mcp tools, some tool-calling interfaces pass the 'arguments' parameter as a JavaScript object instead of a JSON string. This caused parseArguments() to fail with 'Invalid arguments JSON' error because calling JSON.parse() on an object coerces it to '[object Object]' string first. The fix updates parseArguments() to check if arguments is already an object and return it directly, falling back to JSON.parse() only for string inputs. This fixes issues with Playwright MCP and other skill-embedded MCPs that were failing with the error: 'Invalid arguments JSON: Unexpected identifier "object"' 'Received: [object Object]'
|
All contributors have signed the CLA. Thank you! ✅ |
Greptile SummaryFixed
Confidence Score: 4/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant LLM
participant SkillMcpTool
participant parseArguments
participant Manager
Note over LLM: LLM passes arguments as object<br/>instead of JSON string
LLM->>SkillMcpTool: execute({mcp_name, tool_name, arguments: {action: "list"}})
SkillMcpTool->>parseArguments: parseArguments({action: "list"})
alt arguments is object
parseArguments->>parseArguments: typeof argsJson === "object"
parseArguments-->>SkillMcpTool: return argsJson (as-is)
else arguments is string
parseArguments->>parseArguments: JSON.parse(argsJson)
parseArguments-->>SkillMcpTool: return parsed object
end
SkillMcpTool->>Manager: callTool(info, context, tool_name, parsedArgs)
Manager-->>SkillMcpTool: result
SkillMcpTool-->>LLM: formatted output
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additional Comments (1)
-
src/tools/skill-mcp/tools.ts, line 117 (link)logic: schema definition still declares
argumentsas string-only, but the type definition and implementation now accept objects. update the schema to match:
3 files reviewed, 1 comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No issues found across 3 files
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
|
I have read the CLA Document and I hereby sign the CLA |
@sisyphus-dev-ai hey please fix this, commit and push on here |
✅ Schema Mismatch FixedI've fixed the schema mismatch issue identified by Greptile. The changes include: What Was Fixed
Changes Made- arguments: tool.schema.string().optional().describe("JSON string of arguments"),
+ arguments: tool.schema.any().optional().describe("JSON string or object of arguments"),Verification✅ All tests passing (12 tests, 16 expect() calls) The schema now properly accepts both string and object arguments, resolving the type mismatch between the schema definition and the actual implementation. Commit: 83839cd |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1 issue found across 1 file (changes from recent commits).
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="src/tools/skill-mcp/tools.ts">
<violation number="1" location="src/tools/skill-mcp/tools.ts:117">
P2: Using `any()` is overly permissive - it allows arrays and primitives to bypass schema validation. Since `typeof []` returns `"object"`, arrays would pass through `parseArguments` and be incorrectly cast to `Record<string, unknown>`. Consider using a union type schema if available (e.g., `tool.schema.union([tool.schema.string(), tool.schema.record(...)])`) or add an `!Array.isArray()` check in `parseArguments`.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| resource_name: tool.schema.string().optional().describe("MCP resource URI to read"), | ||
| prompt_name: tool.schema.string().optional().describe("MCP prompt to get"), | ||
| arguments: tool.schema.string().optional().describe("JSON string of arguments"), | ||
| arguments: tool.schema.any().optional().describe("JSON string or object of arguments"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: Using any() is overly permissive - it allows arrays and primitives to bypass schema validation. Since typeof [] returns "object", arrays would pass through parseArguments and be incorrectly cast to Record<string, unknown>. Consider using a union type schema if available (e.g., tool.schema.union([tool.schema.string(), tool.schema.record(...)])) or add an !Array.isArray() check in parseArguments.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/tools/skill-mcp/tools.ts, line 117:
<comment>Using `any()` is overly permissive - it allows arrays and primitives to bypass schema validation. Since `typeof []` returns `"object"`, arrays would pass through `parseArguments` and be incorrectly cast to `Record<string, unknown>`. Consider using a union type schema if available (e.g., `tool.schema.union([tool.schema.string(), tool.schema.record(...)])`) or add an `!Array.isArray()` check in `parseArguments`.</comment>
<file context>
@@ -114,7 +114,7 @@ export function createSkillMcpTool(options: SkillMcpToolOptions): ToolDefinition
resource_name: tool.schema.string().optional().describe("MCP resource URI to read"),
prompt_name: tool.schema.string().optional().describe("MCP prompt to get"),
- arguments: tool.schema.string().optional().describe("JSON string of arguments"),
+ arguments: tool.schema.any().optional().describe("JSON string or object of arguments"),
grep: tool.schema.string().optional().describe("Regex pattern to filter output lines (only matching lines returned)"),
},
</file context>
Summary
skill_mcptool failing with "Invalid arguments JSON" error when LLMs pass arguments as an object instead of a JSON stringparseArguments()to handle both object and string inputsProblem
When invoking
skill_mcptools (like Playwright MCP), some LLM tool-calling interfaces pass theargumentsparameter as a JavaScript object instead of a JSON string. This caused failures like:The root cause: when
JSON.parse()is called on an object, the object is first coerced to a string via.toString(), resulting in"[object Object]"which is invalid JSON.Solution
Update
parseArguments()to check if the input is already an object and return it directly, only falling back toJSON.parse()for string inputs.Test Plan
Summary by cubic
Fixes skill_mcp tools failing with “Invalid arguments JSON” when LLMs pass arguments as objects. parseArguments now accepts both object and JSON string, restoring compatibility with Playwright MCP and similar tools.
Written for commit 83839cd. Summary will update on new commits.