[Bug] MCP read.uri retains array items after string override, causing Gemini-compatible API 400

Open
#7,424 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@codinglemom is already working on this.

Since Nov 11, 2026.

  • #7425 by @codinglemom — open

Assessment

Difficulty
1/5
Estimated time
Under an hour
Newbie friendliness
25/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Stale
Tech stack
python
Domain
backend

Research direction

Read openviking/server/mcp_endpoint.py and the existing tests for portable MCP schemas. Reproduce the issue by checking the read.uri and read.uris properties; the report includes a standalone assertion. Done means uri is a string without items, uris remains an array with string items, and the existing runtime argument support is unchanged. Pull request #7425 is already open for this issue.

Written by the indexing model from the issue text.

Description

Environment

  • OpenViking server: 0.5.4, Windows, Python 3.13.
  • The same code is present on upstream main at 226892efcabe99d08b7b7ed3f7c72c3379377b96 (checked 2026-11-11).
  • Client: DSH desktop, using an OpenAI-compatible third-party endpoint serving a Gemini model.
  • The offending schema is already present in OpenViking's raw MCP tools/list response, before the client forwards it. This is not specific to a DSH schema rewrite.

Actual behavior

The read tool advertises its singular uri parameter as:

{
  "type": "string",
  "items": { "type": "string" },
  "description": "One viking:// file URI",
  "title": "Uri"
}

After portability normalization selects an array branch, the property override changes type to string but leaves the array's items behind. The tested Gemini-compatible endpoint rejects a request containing this tool definition with HTTP 400:

{"error":{"message":"Invalid request parameter","type":"invalid_request_error"}}

The failure occurs even when read is the only declared tool and the user prompt only requests OK; the tool does not need to be called. An unrelated title-generation request can succeed at the same time, making provider-side success records misleading.

This report concerns compatibility with the tested function-calling endpoint, not a claim that every JSON Schema validator or every Gemini endpoint rejects the schema.

Expected behavior

The singular uri is advertised as a string without items. The plural uris remains an array with string items. Existing runtime support for passing either string/list form should remain unchanged.

Reproduction without a model or API key

In a normal OpenViking development environment:

from openviking.server import mcp_endpoint

schema = mcp_endpoint.mcp._tool_manager.get_tool("read").parameters
uri = schema["properties"]["uri"]
assert uri["type"] == "string"
assert "items" not in uri  # Fails before this patch.
assert schema["properties"]["uris"]["items"]["type"] == "string"

The same property is observable in a raw MCP tools/list response; no real resource or memory content is required.

Root cause

In openviking/server/mcp_endpoint.py:

  1. read accepts str | list[str] | None for both argument names.
  2. _portable_schema() prioritizes the array branch when collapsing anyOf, retaining items.
  3. _PORTABLE_PROPERTY_OVERRIDES pins singular read.uri to {"type": "string"}.
  4. _apply_portable_schemas() merges this override without removing the obsolete array keyword.

Controlled external verification

Model, API key, reasoning level, prompt and request options were held fixed; only tool definitions changed. No tool was executed.

Request tool set Result
Previously working 50 tools 200 / complete SSE / OK
Full 92 tools, original schema 400 / Invalid request parameter
Only the original read tool 400 / same error, repeated
Full set minus read (91 tools) 200 / complete SSE / OK
Only read, with only uri.items removed 200 / complete SSE / OK
All 92 tools, with only uri.items removed 200 / complete SSE / OK
Restore the original 92 definitions 400 / same error
All 92 tools using schemas fetched from the restarted, patched server 200 / complete SSE / OK

Raw before/after MCP schema comparison confirmed that all 27 OpenViking tools were retained and the only change was removal of read.uri.items. The user subsequently confirmed normal DSH desktop question-answering after restarting the client. Desktop recovery is user-reported; API and MCP checks were performed directly.

Proposed fix

After applying a string property override, remove its obsolete items keyword. Strengthen the existing read-schema assertion and portability traversal to cover this regression. Do not change read argument validation, remove tools, or require a model/API-key change.

The proposed patch modifies two files with six added lines. It makes no data or configuration migrations. Provider identifiers, request IDs, credentials, private memory URIs and local paths are intentionally omitted from this public report.

Dominant language
Python
Stars
41.8k
Forks
3.4k
Avg merge
19h 29m
Merged PRs (30d)
500

Getting set up

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.

More from volcengine/OpenViking

All issues in volcengine/OpenViking

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.