Skip to content

fix(mcp): list a seed a load-time rule refuses at every open as unavailable (#2252, part 2) - #2255

Merged
cevheri merged 7 commits into
mainfrom
fix/mcp-unavailable-connections
Nov 5, 2026
Merged

cevheri merged 7 commits into
mainfrom
fix/mcp-unavailable-connections

Conversation

@cevheri

@cevheri cevheri commented Nov 5, 2026

Copy link
Copy Markdown
Member

A SQLite seed opens only with full file access, which Studio gives a seed only for an admin and only where no other role can use it, so MCP refused every open of a SQLite seed offered to every role, while list_connections still named run_read_query for it (MCP7).

list_connections now gives such a connection read_tool: null and unavailable, a sentence naming the operator's fix, and inspect_schema refuses it with that sentence before acquiring anything. Availability reads editorExecutionContext on the listed record, as every MCP open does, and a new static record, REFUSES_DENIED_FILE_ACCESS, true only for SQLite. Statement tools still answer SQLite's refusal at open.

A census holds the record to each posture engine's connect() under both MCP profiles. On one real SQLite file behind seeds offered to every role, to admin and user, to user and to admin alone, a test lists with an admin and a user token and acquires each row under both profiles: unavailable appears exactly where acquisition is refused. Other tests pin the refusal and the rows that keep their read tool. docs/MCP.md defines unavailable, and MCP7 leaves the backlog.

The local gate passed on the final commit, with 100% line coverage.

Part of #2252.

…cess denied

MCP must know before any provider exists that no open of a connection can succeed for its caller, and no provider declares it: SQLite's connect() refuses a handle opened with file access denied, because its drivers cannot confine a statement's file access, while DuckDB opens one with external access off.
REFUSES_DENIED_FILE_ACCESS records it beside READS_FILE_ACCESS_POSTURE, true for SQLite alone, and joins the registries.

A census builds each engine that reads the posture under the context each MCP profile gives a denied caller: SQLite rejects with its exact error before touching a path that does not exist, and DuckDB opens a real file.
…navailable

A SQLite seed offered to every role was listed with run_read_query although every open of it is refused, for an admin's token too.
mcpConnectionUnavailable asks editorExecutionContext for the posture of the caller's own copy, the call every MCP open makes, so the listing and the open agree.
Such a connection now lists read_tool: null and unavailable, a sentence that says why and what an operator changes, and the description says so.

Every other row lists as before, with one audit event per call.
…cquiring it

inspect_schema built a provider for such a connection and relayed SQLite's refusal behind the untrusted-data notice as the database's error.
It now refuses it once the connection resolves, with the sentence list_connections gives it and a decision event recorded as mcp_execution_failed, as it refuses an engine with no tables, and builds nothing.

Statement tools are unchanged and still answer the provider's refusal at open.
The guide said read_tool is null where inspect_schema is the only read and named no SQLite seed requirement, though a SQLite seed opens only for an admin's token on a seed offered to admins alone.
It now defines unavailable beside read_tool and states that requirement beside the PostgreSQL and SQL Server ones, the SQLite provider doc says how MCP lists and refuses such a seed, and tests pin each line.
…e seed cannot be read

MCP7's done-when holds: list_connections lists such a seed with unavailable, docs/MCP.md states the SQLite seed requirement, and tests pin both.
D460 also names the new census among the tests that pin SQLite's refusal.
…nection agreement test

The agreement test acquires real SQLite providers, and acquisition checks
LIBREDB_ENABLED_PROVIDERS first, so a developer's setting decided it.
…other role can use it

The sentence spoke of every SQLite connection, but an admin's own inline
SQLite connection opens with full file access. D460 now also names the
agreement test that pins the SQLite refusal.
@codecov

codecov Bot commented Nov 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@sonarqubecloud

sonarqubecloud Bot commented Nov 5, 2026

Copy link
Copy Markdown

@cevheri
cevheri merged commit c37042c into main Nov 5, 2026
39 checks passed
@cevheri
cevheri deleted the fix/mcp-unavailable-connections branch November 5, 2026 17:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant