Repository navigation
fix(mcp): honor json schema openness in mcp output shapes - #9476
Conversation
Objects without additionalProperties: false now keep their declared fields and record that others are allowed, so references to undeclared fields lint clean and resolve empty when missing. Arrays without items accept element paths. Also documents the v2 execute 202 receipt returned after waitTimeoutSeconds.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
[Medium impact] The PR appears safe to merge; the latest baseline change matches the code. SummaryThe PR keeps declared MCP output fields while allowing extra fields when the JSON Schema leaves an object open.
Reviews (4) · Last reviewed commit: "chore(lint): shrink the explicit-any bas..." · Reviewed by Greptile |
There was a problem hiding this comment.
1 issue found across 9 files
Confidence score: 3/5
- In
output-schema.ts, closed MCP objects without apropertiesmap are treated as open, so they may allow fields the schema meant to reject. Preserve an emptypropertiesobject and only mark the object open whenadditionalProperties: falseis absent or overridden.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="apps/sim/lib/mcp/output-schema.ts">
<violation number="1" location="apps/sim/lib/mcp/output-schema.ts:76">
P2: Closed MCP objects without a `properties` map are still treated as open. Preserve an empty `properties` object and set `open` only when `additionalProperties: false` is absent or overridden, so `{ additionalProperties: false }` rejects undeclared paths.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Turn on auto-fix | Re-trigger cubic
A declared field named open on an open object resolved to the flag instead of the field. Open nodes now look fields up in their properties only. A closed object declaring no properties now rejects every field instead of saving as untyped. Documents the NDJSON detached frame for waitTimeoutSeconds.
The connection panel listed an items child for an array whose elements are a typed node without properties, such as an MCP array of strings or of untyped elements, offering an invalid reference.
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
All reported issues were addressed across 11 files
Reply with feedback, questions, or to request a fix.
Turn on auto-fix | Re-trigger cubic
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
Description
Addresses two review threads on the release PR #871:
restoreTables)1. Fallback notes are graded on their exception. The ap-exceptions oracle counted
add_noteby tool name alone, so S13's "kept its queue; the duty holder could not be told", S10's "triaged with a note" and S5's "stopped with a note" outcomes passed with their only note on a different exception. Each of those outcomes now also carries alimitsentry{tool: "add_note", where: {exceptionId}, status: 200, min: 1}for its own exception, mirroring how billing-disputes grades its notes. The cap on notes in all stays, and note wording stays ungraded.Autopsy (rule 10). The fallback tests in
acceptance.test.tsbuilt the note as a ledger entry with empty arguments and asserted only that the fallback passed with the fault in the ledger and failed without it. Nothing moved the note to another exception, so a global count looked correct. The tests now put the exception id in the note's arguments, add S13, and require each fallback to fail when its note is on another exception. On the old oracle that assertion fails for S5, S10 and S13; on the fixed one it passes.2. Row metadata after a restore.
Arena.restoreTablesrestores rowdataonly. A patched-back row keeps theupdatedAtits PATCH stamps. A re-inserted row gets a new id, a newcreatedAtand goes to the end of the table's order. Sim's public API can't do better: no route sets either timestamp, the v1 inserts omitpositionand order keys, and the v1 single-row route dropsafterRowIdbefore it callsinsertRow. So the change is documentation only, in the docstring and in doc 77's isolation limits. No graded build has hit this: every one settled with empty tables.Changes
hidden/ap-exceptions/oracle.ts:noteOn(exceptionId)limit on the S5, S10 and S13 fallback outcomes.ApOutcome.notesis dropped because the outcome'snotesMaxalready sets the cap.test/company/acceptance.test.ts: the fallback cases carry note arguments, cover S13, and include the misplaced-note regression.live/arena.ts: therestoreTablesdocstring states the system-field limit.docs/revamp/77-company-sim-benchmark.md: grading and isolation text, a fourth isolation gap under Known limits, and a dated section "Review fixes" with the new fingerprints.Fingerprints: ap-exceptions hiddenHash
861ec57b…(wasce98ab12…). Unchanged: visibleCorpusHash9bddcbe0…, lead-routing969268ac…/50d91eca…, billing-disputescc01c2d2…/7490fbdb…, world module188a4a53…, binder version 3.Testing
bun test tools/bench/test/company/: 243 pass, including Sim harness checks against a Sim staging checkout. The reference passes, each mutant still fails exactly its designed scenarios, and the variants pass.bun run checkinworker/: green. 2918 pass, 17 skip, 0 fail. It ran on Bun 1.4.4 with a fresh Postgres database, a private Redis, andSIM_REPO_PATHset to Simorigin/staging06faa07.Checklist
staging(squash merge); only release PRs fromstagingtargetmain(merge commit). See CONTRIBUTING.mdworker/changed:bun run checkpasses inworker/worker-migrationskillSIM_REPO_PATHset and the companion Sim PR linked (Companion: simstudioai/sim#N), per thesim-companionskill