[Bug] MCP read.uri retains array items after string override, causing Gemini-compatible API 400
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 1/5
- Estimated time
- Under an hour
- Newbie friendliness
- 25/100
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
mainat226892efcabe99d08b7b7ed3f7c72c3379377b96(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/listresponse, 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:
readacceptsstr | list[str] | Nonefor both argument names._portable_schema()prioritizes the array branch when collapsinganyOf, retainingitems._PORTABLE_PROPERTY_OVERRIDESpins singularread.urito{"type": "string"}._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
- Ships a Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from volcengine/OpenViking
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
volcengine/OpenViking#7485 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 80/100
volcengine/OpenViking#7210 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
volcengine/OpenViking#7205 · 1 comment ·
Maintainers usually reply within 1 day
-
[Bug]: Retrieval rerank fallback statistics stay zero after provider failurePossibly taken @97Three claimed this 8 days ago. Openbug kernel
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
volcengine/OpenViking#7014 ·
Maintainers usually reply within 1 day
-
[Bug]: memory.prefetch_search_topn is inert above 5 (call site omits limit), plus two docstrings state the wrong defaultsPossibly taken @peterzhang987723 claimed this 8 days ago. Openkernel
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
volcengine/OpenViking#6923 · 2 comments ·
Maintainers usually reply within 1 day
All issues in volcengine/OpenViking
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
FinanceFlash/unvibecode#699 ·
Maintainers usually reply within 1 day
-
enhancement Website
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
OWASP/OWASP-Hunting#96 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
micropython/micropython#19942 ·
Maintainers usually reply within 1 day
-
A rebuild posts "not part of this build" success to the commit's failed `nix-build` gate and effectsPossibly taken @Padraic-O-Mhuiris claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
`epoch.Integer` raises a raw OverflowError for integers too large to convert to a floatPossibly taken @arindam77 claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
pydantic/pydantic-extra-types#479 ·
Maintainers usually reply within 1 day