MoonshotAI / MoonshotAI/kimi-cli

MCP tool names & schemas rejected by Moonshot API (HTTP 400) — sanitize client-side before sending

Open
#2,531 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
11.4k
Forks
1.3k
Avg merge
9h 47m
Merged PRs (30d)
2

Description

Environment: kimi-cli 1.49.0 · macOS (arm64) · Model: K3 via Moonshot API

The API rejects such requests with:

Error: [provider.api_error] 400 tools.function.parameters is not a valid
moonshot flavored json schema, details: <At path 'root': when using anyOf,
type should be defined in anyOf items instead of the parent schema>

Summary

Several spec-valid MCP servers cannot be used with kimi-cli, because the Moonshot
chat-completions endpoint rejects their tool definitions with HTTP 400. The MCP
spec itself allows these names/schemas — other API consumers handle them fine.
kimi-cli (or the API) should normalize tool definitions before the request.

Problem 1: Tool names starting with a digit → HTTP 400

The MCP server @21st-dev/magic (a popular UI-component generator) exposes tools
named:

21st_magic_component_builder
21st_magic_component_inspiration
21st_magic_component_refiner
...

MCP places no constraint on the leading character of tool names. The Moonshot API,
however, rejects any request whose tools[].function.name begins with a digit:

  • Same session, same prompt, same tools — the call fails with HTTP 400 as long as
    the names start with 21st_….
  • Renaming the identical tools to m_21st_magic_* (letter first) makes the
    exact same calls succeed. No other change.

Ask: Either relax the API-side pattern (e.g. OpenAI-compatible
^[a-zA-Z0-9_-]{1,64}$, which permits leading digits), or have kimi-cli rewrite
non-conforming tool names client-side (with a stable mapping so results route back
to the correct MCP tool).

Problem 2: Strict JSON-Schema subset rejects valid MCP schemas

Example: gitnexus@1.6.9 (npx gitnexus mcp), tool api_impact, declares this
inputSchema — valid JSON Schema (2020-12):

{
  "type": "object",
  "properties": {
    "route":  { "type": "string", "description": "Route path (e.g., \"/api/grants\")" },
    "file":   { "type": "string", "description": "Handler file path (alternative to route)" },
    "method": { "type": "string" },
    "repo":   { "type": "string" },
    "branch": { "type": "string" }
  },
  "required": [],
  "anyOf": [
    { "required": ["route"] },
    { "required": ["file"] }
  ]
}

The API rejects it (HTTP 400). The offending constructs appear to be the root-level
anyOf with per-branch required, combined with the empty sibling "required": [].
Rewriting the schema to drop the empty required and resolve the anyOf (moving
the constraint into the description) makes the identical tool call succeed.

Related: some servers omit the root "type": "object" entirely; coercing it
client-side is trivial and harmless.

(For completeness: GitNexus fixed the anyOf part upstream in 1.6.10-rc via
PR #2489 — verified by auditing all 17 tool schemas on gitnexus@rc. The
client-side problem for kimi-cli remains: any spec-valid server can still hit
these rejections, e.g. digit-led tool names or other combinator patterns.)

Suggested fix (client-side, minimal)

Before sending tools to the API, kimi-cli could:

  1. Rewrite names to ^[A-Za-z][A-Za-z0-9_-]*$ (e.g. prefix m_ for leading
    digits, replace invalid chars with _), keeping a bidirectional map for the
    response path.
  2. Recursively coerce schemas: force root type: "object" when properties is
    present; when anyOf/oneOf appears alongside sibling keywords, either inline
    the siblings into each branch or drop the conflicting sibling with a note in
    description.

This is exactly what our local workaround does (a FastMCP stdio proxy between
kimi-cli and the upstream server). It works, but every user of these servers
shouldn't need to build their own proxy — the sanitization belongs in the client
(or the API validation should be relaxed).

Repro

# 1. magic (name problem)
kimi mcp add magic -- npx -y @21st-dev/magic@latest
# ask anything that loads tools -> HTTP 400

# 2. gitnexus (schema problem)
kimi mcp add gitnexus -- npx -y gitnexus@latest mcp
# ask anything that loads tools -> HTTP 400

Happy to provide the proxy source or test a fix.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the kimi-cli MCP tool serialization path before requests are sent to the Moonshot API, using the two kimi mcp add reproductions in the issue. Trace how tool names and schemas are forwarded and how tool results are routed back. Done means digit-led names and the shown schema forms no longer produce HTTP 400, while responses still reach the original MCP tools.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api, cli
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.