Strict-schema OpenAI-compatible endpoints (LM Studio) reject all requests when an MCP tool schema lacks properties
Summary
When any configured MCP server exposes a tool whose input schema is a bare {"type": "object"} (no properties field — common for no-argument tools), every chat/completions request against a strict-schema OpenAI-compatible endpoint fails with HTTP 400. LM Studio is the primary example: its request validator requires properties to be present on object schemas inside tools[].function.parameters.
Since jcode sends the full tool array on every request, a single sloppy MCP tool schema makes the provider completely unusable.
Environment
- jcode v0.35.1 (e701dc3)
- LM Studio (local server,
http://localhost:1234/v1), model qwen/qwen3.6-35b-a3b
- Named provider profile
[providers.<name>] with type = "openai-compatible"
- MCP server whose tools have no-arg schemas (observed with the wiremock MCP server:
get_recording_status, stop_recording, who_am_i)
Reproduction
- Configure an
openai-compatible provider profile pointing at LM Studio.
- Configure any MCP server that declares at least one tool with
inputSchema: {"type": "object"} and no properties key (e.g. wiremock MCP).
jcode --provider-profile <name> run 'hello'
Result: HTTP 400 from LM Studio. The error payload points at tools[<i>].function.parameters.properties being undefined ("expected": "object", "received": "undefined") for each offending tool index.
Root cause
crates/jcode-base/src/provider/openrouter_provider_impl.rs builds the OpenAI-format tool array by passing t.input_schema through verbatim:
"parameters": t.input_schema,
There is no normalization of third-party MCP schemas, so whatever the MCP server emits is sent to the endpoint as-is. The OpenAI spec examples always include properties on object schemas, and strict validators (LM Studio) enforce it.
Proposed fix
Normalize object schemas before building the tools array: if parameters is an object schema ("type": "object") without a properties key, inject an empty "properties": {}. This is a no-op for well-formed schemas and semantically identical for no-arg tools.
Patch (12 lines) tested end-to-end against LM Studio: PR to follow.
Strict-schema OpenAI-compatible endpoints (LM Studio) reject all requests when an MCP tool schema lacks
propertiesSummary
When any configured MCP server exposes a tool whose input schema is a bare
{"type": "object"}(nopropertiesfield — common for no-argument tools), everychat/completionsrequest against a strict-schema OpenAI-compatible endpoint fails with HTTP 400. LM Studio is the primary example: its request validator requirespropertiesto be present on object schemas insidetools[].function.parameters.Since jcode sends the full tool array on every request, a single sloppy MCP tool schema makes the provider completely unusable.
Environment
http://localhost:1234/v1), modelqwen/qwen3.6-35b-a3b[providers.<name>]withtype = "openai-compatible"get_recording_status,stop_recording,who_am_i)Reproduction
openai-compatibleprovider profile pointing at LM Studio.inputSchema: {"type": "object"}and nopropertieskey (e.g. wiremock MCP).jcode --provider-profile <name> run 'hello'Result: HTTP 400 from LM Studio. The error payload points at
tools[<i>].function.parameters.propertiesbeingundefined("expected": "object", "received": "undefined") for each offending tool index.Root cause
crates/jcode-base/src/provider/openrouter_provider_impl.rsbuilds the OpenAI-format tool array by passingt.input_schemathrough verbatim:There is no normalization of third-party MCP schemas, so whatever the MCP server emits is sent to the endpoint as-is. The OpenAI spec examples always include
propertieson object schemas, and strict validators (LM Studio) enforce it.Proposed fix
Normalize object schemas before building the tools array: if
parametersis an object schema ("type": "object") without apropertieskey, inject an empty"properties": {}. This is a no-op for well-formed schemas and semantically identical for no-arg tools.Patch (12 lines) tested end-to-end against LM Studio: PR to follow.