Skip to content

agent_spawn MCP tool fails with 'type: Required' β€” SpawnAgentSchema/validate-input field mismatchΒ #1567

@yosefzonana

Description

@yosefzonana

Summary

mcp__ruflo__agent_spawn (and mcp__claude-flow__agent_spawn) always fail with "Input validation failed: type: Required", even when the caller passes the agentType parameter documented in the MCP tool schema. The failure silently cascades: agent_list then returns an empty array because no agent is ever persisted.

The root cause is a field name mismatch between the Zod schema in @claude-flow/security and the caller in @claude-flow/cli.

Affected versions

  • ruflo@3.5.78 (and earlier 3.5.x)
  • @claude-flow/cli@latest
  • @claude-flow/security@3.0.0-alpha.1

Steps to reproduce

  1. Install ruflo: npx -y ruflo mcp start
  2. Register in Claude Code via .mcp.json or .claude.json
  3. In a Claude Code session, call mcp__ruflo__agent_spawn with agentType: "tester"
  4. Observe the error response

Expected behavior

Agent is spawned, response includes success: true, agent appears in agent_list.

Actual behavior

{
  "success": false,
  "error": "Input validation failed: type: Required"
}

And agent_list returns {"agents": [], "total": 0} afterwards.

The error also affects the CLI path β€” npx -y ruflo agent spawn -t coder --name test reports "success" but the output table shows empty ID/Type/Status fields because the CLI internally calls the same broken MCP tool (callMCPTool('agent_spawn', ...) in commands/agent.js:135-147).

Root cause

There's a field name mismatch between three files:

  1. @claude-flow/cli/dist/src/mcp-tools/agent-tools.js:142 β€” exposes the MCP schema as:

    agentType: { type: 'string', description: 'Type of agent to spawn' }
    // required: ['agentType']
  2. @claude-flow/cli/dist/src/mcp-tools/validate-input.js:120-123 β€” calls the security validator:

    sec.SpawnAgentSchema.parse({
        agentType: input.agentType,
        name: input.agentId,
    });
  3. @claude-flow/security/dist/input-validator.js:230-235 β€” defines the schema as:

    export const SpawnAgentSchema = z.object({
        type: AgentTypeSchema,           // ← expects "type" NOT "agentType"
        id: IdentifierSchema.optional(),
        config: z.record(z.unknown()).optional(),
        timeout: z.number().positive().optional(),
    });

The caller in step 2 sends { agentType, name } but the schema in step 3 requires type and doesn't allow name. Zod fails fast with "type: Required".

Proposed fix

Align SpawnAgentSchema with the caller and the exposed MCP schema. Rename type to agentType and add an optional name field:

 export const SpawnAgentSchema = z.object({
-    type: AgentTypeSchema,
+    agentType: AgentTypeSchema,
+    name: SafeStringSchema.max(200, 'Name too long').optional(),
     id: IdentifierSchema.optional(),
     config: z.record(z.unknown()).optional(),
     timeout: z.number().positive().optional(),
 });

Apply to:

  • @claude-flow/security/src/input-validator.ts (source)
  • @claude-flow/security/dist/input-validator.js (built output)
  • @claude-flow/security/dist/input-validator.d.ts (type declaration)

Alternative fixes considered

  • Change the caller to send type instead of agentType β€” rejected because it would break the MCP exposed schema (which is the public contract) and several other callers in agent-tools.js that use agentType consistently.
  • Add a translation layer in validate-input.js β€” rejected as a hack; better to make the schema consistent with the rest of the codebase.

Verification I performed locally

After applying the patch to my local npx cache copy:

// call
mcp__ruflo__agent_spawn({ agentType: "tester", agentId: "patch-verify-1" })

// response (success!)
{
  "success": true,
  "agentId": "patch-verify-1",
  "agentType": "tester",
  "model": "sonnet",
  "modelRoutedBy": "default",
  "status": "registered",
  "createdAt": "2026-04-08T15:44:52.841Z"
}

Follow-up call:

mcp__ruflo__agent_list()
// response
{
  "agents": [
    {
      "agentId": "patch-verify-1",
      "agentType": "tester",
      "status": "idle",
      "health": 1,
      "taskCount": 0,
      "createdAt": "2026-04-08T15:44:52.841Z"
    }
  ],
  "total": 1
}

Both agent_spawn and agent_list work correctly after the patch. agent_terminate and swarm_shutdown also tested clean.

Additional context

  • This bug blocks ALL MCP-based agent lifecycle operations, including CLI paths that internally use callMCPTool('agent_spawn', ...).
  • There is no user-level workaround because agent_list returns empty regardless of how the agent was attempted to be spawned.
  • The bug has been present since @claude-flow/security@3.0.0-alpha.1 shipped (unconfirmed start date).
  • I have a local patch running in production as of 2026-04-08.

Environment

  • OS: macOS (Darwin 25.3.0, arm64)
  • Node: v20+ (via Claude Code extension)
  • Claude Code extension: 2.1.92 (VS Code) + 2.1.77 (Antigravity)
  • Ruflo: 3.5.78

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions