Skip to content

Missing items definition for array parameters in generated tool schemas #9

@gambtho

Description

@gambtho

Description

When exporting tool schemas via GoMCP's built-in generator (either with --export-schemas or the HTTP /schema endpoint), any parameter declared as a Go slice or array (e.g. []string) produces a JSON Schema entry with:

{
  "type": "array",
  "description": ""
}

but no corresponding "items" definition. This violates the JSON Schema specification and breaks downstream validators (notably the GitHub Copilot extension), which refuse to load the schema:

Failed to validate tool xxx_tool:
Error: tool parameters array type must have items

Steps to Reproduce

1. Define a tool with an array field:

type ToolArgs struct {
  SomeSlice []string `json:"some_slice"`
  // …
}

server.Tool(
  "mcp_xxx_tool",
  "Some Tool",
  ToolArgs{},
  ToolResult{},
  handlerFunc,
)

2. Build and export schemas:

go build -o mcp-server
./mcp-server --export-schemas

3. Inspect the output for some_slice:

"some_slice": {
  "type": "array",
  "description": "List of strings…"
  // ← missing "items": { "type": "string" }
}

4. Observe that a JSON Schema validator (e.g. GitHub Copilot) rejects it:

Error: tool parameters array type must have items

Expected Behavior

Every parameter with "type": "array" in the generated schema must include an "items" property that accurately describes the element type. For example:

"some_slice": {
  "type": "array",
  "items": {
    "type": "string"
  },
  "description": "List of srings…"
}

Proposed Solutions

Option 1: Post-processing approach

Post-process exported schemas in cmd/mcp-server/main.go (and the HTTP handler) to walk the raw map[string]interface{} and inject missing "items" blocks.

Option 2: Core integration

Integrate the fix into GoMCP's core generator so that slice and array types always emit an items schema entry by default—eliminating the need for external post-processing.

Implementation sketch (post-processor approach):

// util/schema_utils.go
func AddMissingArrayItems(schema map[string]interface{}) {
  // Recursively traverse schema maps/arrays…
  // When encountering {"type":"array"} with no "items", inject:
  schema["items"] = map[string]interface{}{"type":"string"}
}

Environment

  • GoMCP version: main (commit SHA…)
  • Go version: go1.24

Please let me know if you'd like additional context and if you're open to a PR for this. Thank you!

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