Repository navigation
Commit cce3ca5
authored
* feat(mcp): give inspect_schema a timeout_ms that bounds every provider call
inspect_schema took no time limit, so a slow acquisition, container listing or table description held the call for as long as the provider took.
It now takes timeout_ms, 500 to 30000 and 30000 by default. The bounds are one constant, MCP_TIMEOUT_BOUNDS_MS, which the statement tools' timeout_ms and their timeout answer read too.
Every provider call of a call, from the acquisition to each table's description, runs through raceDeadline, so none starts after the deadline; one already started runs on, the acquisition included, and the next call on the connection joins an acquisition a timed-out call left, as MCP16 records. A timeout answers mcp_timeout in a sentence of its own, which offers more time only below 30000, and a cancel answers mcp_cancelled at once.
The tests that abort a held step now let it finish before the provider cache is cleared, since the answer no longer waits for it.
* feat(mcp): return each table's foreign keys from inspect_schema on request
describeObject already returns a table's foreign keys, and inspect_schema dropped them.
With include_foreign_keys each table carries up to 25 as column, referenced_table and referenced_column, with foreign_keys_omitted counting the rest. Where the provider declares that its engine has no foreign keys, each table answers unavailable instead, and asking for foreign keys alone describes no table there.
The input's description says that a composite key comes back as one row per column pair, since no constraint name is returned, and that an empty list may also mean the connection's login cannot see the keys.
* feat(mcp): return the schema names inspect_schema reads on request
chooseContainer lists every container level it walks, yet a client could not learn which other schemas a connection holds.
It now also returns what its last listing answered, and with include_schema_names the page carries schema_names after schema: those names in the provider's order, at most 100 and 4,096 bytes of JSON with no name cut, and schema_names_omitted counting the rest, on every page and inside the 32 KiB result limit. A connection with no container level answers unavailable, and the field sends no request of its own.
The schema-not-found refusal now points at include_schema_names, and the first-table-over-the-limit refusal names every include flag to turn off.
* fix(mcp): say that inspect_schema's operations profile proves no login on some engines
inspect_schema opens under Studio's operations profile, which sends no statement, so where an engine proves its login only for a connection that sends statements, it can list a connection whose statement tool refuses that login.
Its description and docs/MCP.md now say so, the docs naming agent-operations and MongoDB as one such engine. The profile itself is unchanged.
* test(mcp): clear the acquisition environment for every inspect_schema test
isolateAcquisitionEnvironment() runs once at file level, right after pinMcpTestEnvironment().
Each test of the file clears GOVERNANCE_SOURCE and LIBREDB_ENABLED_PROVIDERS and restores them exactly afterwards; the deadline block still pins LIBREDB_SQLITE_WORKER of its own.
Before this, most tests that predate this change failed with either variable exported.
With GOVERNANCE_SOURCE=postgres and LIBREDB_ENABLED_PROVIDERS=postgres exported, every test of the file passes, as it does with neither set.
* test(mcp): clear the acquisition environment for the Sparkplug B schema names test
The test of inspect_schema's schema names on Sparkplug B acquires a real connection, so its block clears GOVERNANCE_SOURCE and LIBREDB_ENABLED_PROVIDERS for each test and restores them exactly afterwards.
It now passes with GOVERNANCE_SOURCE=postgres exported; the file's older tests still read that variable, as they do on main.
* docs(mcp): name Milvus among the engines inspect_schema opens unproved
The sentence on inspect_schema's operations profile said that Opting connections in names each engine whose provider proves its login only for a connection that sends statements.
That section names most of them but not Milvus or InfluxDB (InfluxQL), so the sentence now names Milvus beside MongoDB and says the section names more such engines, without claiming it names all of them.
The documentation test pins the new sentence.
* test(mcp): hold inspect_schema's database choice to the deadline, and the foreign keys flag to the size refusal
A server-level connection whose database choice is held past timeout_ms 500 now answers the timeout, and no listing on the chosen database's session starts after it.
The test that counts the include flags before the first-table size refusal now also sets include_foreign_keys alone beside include_columns false, which must answer the refusal that advises limit 1.
Each test fails when its line in inspect_schema is undone: the race of the database choice against the deadline, or the include_foreign_keys term of the bare check.
* test(mcp): pin inspect_schema's unavailable foreign keys beside columns, and schema names past the first page
On an engine that reads no foreign keys, a table answers foreign_keys unavailable also when the default include_columns describes it.
That test fails when foreignKeysOf is handed the description regardless of whether the engine reads foreign keys.
schema_names come back on a page with offset 1 too.
That test fails when the names are kept to the first page.
* docs(mcp): say that inspect_schema lets a step holding Studio's own thread finish past the deadline
The steps of an inspect_schema call start only before its deadline, and a call still waiting on one when it passes is answered with the timeout, never a partial page.
A step that holds Studio's own thread, as a LibreDB read does, cannot be interrupted, so it is let finish and only the steps after it are refused.
The documentation test pins the bullet with its new line.
* test(mcp): count the comma between schema names toward their 4 KiB bound
A list of 100 names of 38 characters crosses the bound between two names, so the answer keeps 99 and counts one omitted; with the comma left out of the count it would keep all 100 in 4,101 bytes of JSON, which the test refuses.
* test(mcp): pin schema_names' 4,096-byte bound to the byte
Two lists end at exactly 4,096 and at 4,097 bytes of JSON: the first keeps its last name and the second leaves it, so a count that drops the brackets, charges a comma to the first name or refuses a list of exactly 4,096 bytes fails.
1 parent 4f9bcb0 commit cce3ca5
11 files changed
Lines changed: 891 additions & 34 deletions
File tree
- docs
- src/lib/mcp/tools
- tests
- integration/mcp
- security
- unit
- mcp
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9728 | 9728 | | |
9729 | 9729 | | |
9730 | 9730 | | |
| 9731 | + | |
9731 | 9732 | | |
9732 | 9733 | | |
9733 | 9734 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
27 | 34 | | |
28 | 35 | | |
29 | 36 | | |
| |||
637 | 644 | | |
638 | 645 | | |
639 | 646 | | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
640 | 650 | | |
641 | 651 | | |
642 | 652 | | |
| |||
0 commit comments