-
Notifications
You must be signed in to change notification settings - Fork 210
Description
Context
This issue was discovered by v2nic using the pi coding agent while working with the Atlassian MCP server and the atlassian CLI generated by mcporter.
Problem
When an MCP tool schema declares a parameter with "type": "object" (e.g. editJiraIssue's fields parameter), the generated CLI passes the value as a raw string instead of parsing it as JSON. This causes MCP validation errors like:
MCP error -32602: Invalid arguments for tool editJiraIssue: [
{
"code": "invalid_type",
"expected": "object",
"received": "string",
"path": ["fields"],
"message": "Expected object, received string"
}
]
Root cause
Two places in the code generator silently drop object types:
1. src/cli/generate/tools.js — inferType()
The resolveType inner function only recognizes a whitelist of types:
const resolveType = (value) => {
if (value === "integer") return "number";
if (value === "string" || value === "number" || value === "boolean" || value === "array") {
return value;
}
return undefined; // ← "object" falls through here
};When the schema says "type": "object", resolveType returns undefined, and inferType returns "unknown".
2. src/cli/generate/template.js — optionParser()
The switch statement has no case for object:
function optionParser(option) {
switch (option.type) {
case "number": return "(value) => parseFloat(value)";
case "boolean": return "(value) => value !== 'false'";
case "array": return "(value) => value.split(',').map((v) => v.trim())";
default: return undefined; // ← unknown/object falls through
}
}So even if inferType returned "object", optionParser would still return undefined, generating:
.requiredOption("--fields <fields>", "Set fields.")
// no parser — value stays as a raw stringReproduction
- Generate a CLI from any MCP server with an object-type parameter:
npx mcporter generate-cli --server https://mcp.atlassian.com/v1/mcp --compile- The generated CLI will have:
.requiredOption("--fields <fields>", "Set fields.") // no JSON.parse- Running:
atlassian editJiraIssue --cloud-id <id> --issue-id-or-key NVR-526 --fields '{"description":"test"}'...sends fields as a string to the MCP server, which rejects it.
Fix
tools.js — add "object" to the whitelist:
const resolveType = (value) => {
if (value === "integer") return "number";
if (value === "string" || value === "number" || value === "boolean" || value === "array" || value === "object") {
return value;
}
return undefined;
};template.js — add case "object" to optionParser:
function optionParser(option) {
switch (option.type) {
case "number": return "(value) => parseFloat(value)";
case "boolean": return "(value) => value !== 'false'";
case "object": return "(value) => JSON.parse(value)"; // ← add this
case "array": return "(value) => value.split(',').map((v) => v.trim())";
default: return undefined;
}
}Related issues
- CLI argument parser fails to parse nested JSON objects in key:value parameters #74, CLI argument parser doesn't pass nested JSON objects to MCP tools #75 —
mcporter callkey:value parsing (different code path, same class of bug) - [bug] Generated CLI parsers can't actually utilize the
--rawflag if there are required flags for the call #102 —--rawflag blocked by required options - [bug] Generated CLI array parsing is broken if the array items are JSON objects #103 — array parsing splitting on commas inside JSON objects
Environment
- mcporter version: npx (latest as of 2026-03-16)
- MCP server: Atlassian (
https://mcp.atlassian.com/v1/mcp) - Generated CLI:
atlassian(Bun-compiled binary) - Node.js: v20.20.0
- macOS arm64