Skip to content

MCP tools cannot receive a document's dependencies from a remote client #122

Open

Description

@LukasOro

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.

Raised from review of #114 (#114 (comment)).

Activity

  1. simontaurus commented on Aug 19, 2026

    @simontaurus
    Contributor

    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.

  2. LukasOro commented on Aug 20, 2026

    @LukasOro
    ContributorAuthor

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions