You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
MCP tools cannot receive a document's dependencies from a remote client #122
The MCP tools take documents as filesystem paths, or (for some) as raw JSON. Neither form lets a remote caller supply a document's dependencies, so an HTTP-bound server cannot validate a realistic OO-LD schema.
Why one document is not enough
OO-LD schemas are relative-sibling-heavy by design: @context entries and $ref targets are usually files next to the schema. _materialise() in src/oold/validation/mcp_server.py says so itself:
A schema passed as raw JSON therefore has to be written somewhere before it can be validated, and it will only resolve if it has no relative references.
So inline JSON works for a self-contained document and fails for anything that references a sibling, which is most real schemas.
Options
Bundle parameter: accept a map of filename to document, materialise all of them into one temporary directory, and validate the named entry. Covers relative siblings with no network access.
Base URL: accept a base the resolver fetches relatives from. Reuses the existing remote resolution and cache, but requires network and makes results depend on a remote host.
The bundle form is likely the better default; the two are not exclusive.
Out of scope here
validate_oold_directory and run_oold_compliance take directories and are inherently filesystem-bound. A remote equivalent would be a bundle of many documents, which is the same design question.
Already done
Inline JSON is accepted consistently by the four single-document tools (validate_oold_schema, validate_oold_instance, generate_oold_instance, check_context_mapping). This issue is only about dependencies.
Agreed the single-document half is done and the bundle half is the real work.
The constraint is worth stating in the issue, since it decides the design: OO-LD schemas reference relative siblings by design, and an instance's $schema and @context normally point at the same URL. So a remote caller sending one document sends something that cannot resolve, and the failure is a resolution error rather than an obviously-missing-input error.
Two shapes, and they are not equivalent:
bundle: a filename to document map, materialised into one temporary directory. Handles relative siblings, which is the common case. Caller must know the closure up front.
base URL: the server fetches the dependencies itself. Handles any depth, but reintroduces network fetches into a tool call and needs the offline question answered.
The bundle covers the OO-LD-shaped case, so it is the one to build first, with the base URL as a later option rather than an alternative.
Agreed: bundle first, base URL later as an addition rather than an alternative.
The point worth pulling into the description is the failure mode, not just the missing capability. A remote caller sending one document does not get "missing input"; they get a resolution error naming a sibling they never mentioned, which reads like a bug in the schema rather than a limitation of the transport. Worth making the error say so explicitly whichever shape lands.
On "the caller must know the closure up front" - that is the bundle's real cost and it is not always payable. For a schema whose $ref chain is two or three hops of relative siblings the caller usually does know, because they are shipping the directory. For a chain that crosses into an https:// reference partway down, they cannot, and no bundle they can assemble is complete. That is the case the base URL exists for, and it is also why the two are complementary rather than one superseding the other.
Two things to settle when the bundle is built:
offline. A bundle is self-contained, so it should validate under offline=True and fail loudly rather than reaching for the network to patch a gap in the bundle. That keeps the two shapes distinguishable in the result.
Filename keys, not URLs. The map keys have to be what the relative references actually resolve against, so they are paths relative to the entry document, and the server materialises them under one root. A URL-keyed map would need rewriting on the way in.
Also related: #128. There is currently no fixture exercising a genuinely remote reference, so the base URL half has nothing to test against today.
Activity
simontaurus commentedon Aug 19, 2026
Agreed the single-document half is done and the bundle half is the real work.
The constraint is worth stating in the issue, since it decides the design: OO-LD schemas reference relative siblings by design, and an instance's
$schemaand@contextnormally point at the same URL. So a remote caller sending one document sends something that cannot resolve, and the failure is a resolution error rather than an obviously-missing-input error.Two shapes, and they are not equivalent:
offlinequestion answered.The bundle covers the OO-LD-shaped case, so it is the one to build first, with the base URL as a later option rather than an alternative.
LukasOro commentedon Aug 20, 2026
Agreed: bundle first, base URL later as an addition rather than an alternative.
The point worth pulling into the description is the failure mode, not just the missing capability. A remote caller sending one document does not get "missing input"; they get a resolution error naming a sibling they never mentioned, which reads like a bug in the schema rather than a limitation of the transport. Worth making the error say so explicitly whichever shape lands.
On "the caller must know the closure up front" - that is the bundle's real cost and it is not always payable. For a schema whose
$refchain is two or three hops of relative siblings the caller usually does know, because they are shipping the directory. For a chain that crosses into anhttps://reference partway down, they cannot, and no bundle they can assemble is complete. That is the case the base URL exists for, and it is also why the two are complementary rather than one superseding the other.Two things to settle when the bundle is built:
offline. A bundle is self-contained, so it should validate underoffline=Trueand fail loudly rather than reaching for the network to patch a gap in the bundle. That keeps the two shapes distinguishable in the result.Also related: #128. There is currently no fixture exercising a genuinely remote reference, so the base URL half has nothing to test against today.