Repository navigation
feat(mcp): list each token's own tools, with hints that state their effects (#2252, part 3) - #2257
Merged
Merged
Conversation
…ey keep Every MCP tool says readOnlyHint: true, but an inspect_schema call can resume a billed Databend Cloud warehouse, or open a LibreDB file and hold its exclusive lock for 30 minutes. MCP_METADATA_READ_CHANGES_STATE records those engines per engine, beside the other MCP records and in the registries. It is not derived from resumesBilledCompute, which Snowflake declares though it browses with no warehouse and Databend declares per connection, while the list is decided before any provider exists. metadataReadAnnotations answers readOnlyHint: false and destructiveHint: false for a reach holding such an engine, and the read-only hints otherwise. McpReach names a token's reach as the listing's own connection type, as the availability helper does.
…hints from it listedStatementArms keeps the serving arms that serve a reached engine, a registry read. The registrations take an optional reach, and without one register exactly today's set and hints, which the full handler keeps. listedMcpToolNames gives the tests one token's names from the same records.
… file with -32603 Every token got every statement tool of the build, whatever engines its connections use. A tools/list now goes to a list-only handler whose factory reads the seed file through its cache, keeps the engines the caller can read by the rule list_connections uses, and registers the metadata tools and the statement tools that serve them; it builds no provider and reads no Vault reference. Every other method keeps the full handler, so a call to a tool the list leaves out still meets Studio's checks and audit, never the SDK's unknown-tool answer. A seed file that cannot be read or parsed answers tools/list with -32603 and the sentence every tool answers, never a shorter or a fuller list. Discovery never throws and opts nothing in, so a failing export changes no answer. The harness takes the production dispatcher, and the tests that pinned the build's list now pin the token's.
…e server A Redis read deletes a key whose time to live has passed, and where notify-keyspace-events asks it publishes a keymiss event for a missing key. The tool keeps readOnlyHint: true, so its description now states both effects, as docs/MCP.md does.
The guide said every tool is annotated read-only and every token lists every tool. It now says what a token lists, when a seed edit reaches the list, what an unreadable seed file answers, which engines make inspect_schema change state, and that a Redis keyspace walk can delete an expired key and publish an event, its hint unchanged. The Databend and LibreDB docs state the hint, and tests hold the engines the docs name to the record.
Three defects found while building the per-token list and outside it: an in-memory SQLite or DuckDB seed lists a read tool every open refuses, a not-served refusal names run_read_query for a SQLite seed no open serves, and ADDING_A_PROVIDER.md says only DuckDB reads the file-access posture.
…ls do A seed edit reaches tools/list once the seed cache's time to live has passed, the bookkeeping sentence covers the statement tools and points inspect_schema at its own entry, and docs/ARCHITECTURE.md names both module-scope handlers.
…sed parameter The mocks in the test of an arm that serves no engine named a parameter only to type their calls, which ESLint reports as unused; they now pass the signature to mock as other tests do.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
5 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Every token got the same
tools/list, every statement tool of the build, and every tool saidreadOnlyHint: true, though aninspect_schemacall can resume a billed Databend Cloud warehouse or hold a LibreDB file's lock for 30 minutes.A
tools/listnow goes to a list-only handler registering the metadata tools and only the statement tools serving engines the token can read, bylist_connections' availability rule, building no provider and reading no Vault reference. Every other method keeps the full handler, so a call to an unlisted tool still gets Studio's audited refusal. An unreadable or invalid seed file answerstools/listwith-32603. A new record makesinspect_schemasayreadOnlyHint: falseanddestructiveHint: falseto tokens reaching Databend or LibreDB, andrun_redis_read's description states a read's server-side effects.Through the route's
POSTin process, with an admin token and a seed of every served engine,tools/listtook a median of 1.4 ms with the seed cache emptied first and 1.1 ms warm, over 200 calls each; main's took 0.97 ms.New tests cover each listing case, in both protocol eras where both apply; MCP24, MCP25 and DOC37 are filed. The local gate passed with 100% line coverage.
Part of #2252.