In development

Oracle and MCP

The local MCP query and replacement-view polling subset, with unsupported Oracle operations.

12 October 2026 reconciliation (T-R106): the executable adapter configures exactly query and changes; the service harness checks that discovery pair and rejection of catalog, context, expand and transact. This is a source/evidence review, not a fresh runtime qualification; the T-R004 baseline records that native tests never launched because the build-guard lock write was denied.

rural mcp <profile-dir> <ordinary-collection> exposes query and process-local changes through newline JSON-RPC stdin/stdout. Start the sole service first. Launch configuration fixes branch 1 and one ordinary collection; the adapter never opens database files. It uses the trusted local owner credential rather than issuing a separately scoped service credential. Sources: local adapter and service harness.

Startup loads credentials once and verifies a one-record query through that session before accepting input. Store and session remain pinned; a service restart or disconnect requires restarting the adapter. No credential refresh or write dispatch occurs. Source: session preflight and dispatch.

Available tools versus the planned surface#

SurfaceEvidence-backed boundary
query, changesConfigured and dispatched by local.zig; check_mcp_service.py checks discovery, CLI query/view parity and polling refusals.
catalog, context, expandW13 freeze specifies future schemas and service prerequisites; local.zig supplies no dispatch for them.
transactDisabled in local.zig; the freeze leaves it outside read-only Oracle scope.
Reusable six-name catalogtools.zig defines names for generic dispatchers; server.zig uses available_tools for discovery and dispatch. Names alone do not establish executable availability.
Bounded Oracle contextcontext.zig owns facts and evidence strings with default limits of 32 facts, 16 handles and 64 KiB; the freeze explicitly says it is not an MCP route.

The gateway guide still says the executable configures only query; that conflicts with the current adapter and harness. The query-only 28 September Unit A statement in Oracle evidence is explicitly historical there; Sprint 41 Units C/D/E record the later two-tool surface and W13 freeze, while retaining O01/V09 as partial.

query#

Arguments may contain only predicates, projection, sort and limit. Limit is a canonical decimal string from "1" to "200"; default is 200. At most 32 predicates and 64 projection fields are accepted. Predicates use operator (exists, eq, ne, lt, lte, gt, gte) and field; comparisons require a scalar value, while exists omits it. Sort accepts field and optional boolean descending. Collection, branch, operation, credentials and every unknown field are rejected even if they match launch configuration. Sources: argument builder, input schema and local argument tests.

Each successful query returns two MCP text content parts: (1) the validated service response including view evidence; (2) a plan_id meta object {"plan_id":"<32-hex>","contract":"mcp-changes-v1"} for process-local changes polling. Plans are capped (32) and die with the adapter process. Sources: query result construction and saved-plan table.

changes#

Arguments: required plan_id; optional cursor; optional limit ("1"…"200", default "50"). Re-executes the saved plan against the live service. The outcomes below follow the polling implementation and the overflow/deletion/cursor checks in the service harness.

  • Unchanged stable result/view hash and coverage -> {"status":"unchanged"} only.

  • Changed and current query-page row count ≤ poll limit -> status: "changed" with entries equal to the complete current matching page (replacement view, not a CDC delta), next_cursor, and coverage stamps. An empty matching set after deletions is a valid changed replacement (entries: []); it is still not a CDC tombstone log.

  • Current query-page row count > poll limit -> error result; the poll cursor is not advanced (omitted rows must not become permanently unreachable through a truncated then-unchanged sequence). Caller may raise limit on the same plan_id or issue a new query. Error text may say "resnapshot with query" as the safe recovery path.

  • Unknown/stale plan or cursor, foreign plan_id embedded in an otherwise well-formed cursor, and authority mismatch -> fail closed with non-sensitive text. next_cursor always binds the saved plan identity (1:<plan_id>:…).

This is C11 process-local polling, not a durable feed and not Application /v1/changes. Sole-owner MCP does not implement a separate dynamic revoke API. Source: C11/W13 freeze.

The saved query's own limit remains in force when polling; raising the poll limit does not expand that query or prove complete collection coverage (buildQuery and changes).

Transport/session failures and invalid arguments return fixed, non-sensitive text content with isError: true. Framing is bounded to 64 KiB per line and 256 KiB buffering. Each request uses at most 16 MiB temporary allocator storage. Service exchanges use a ten-second timeout. Sources: adapter allocation, timeout and error paths and framing defaults.

Disabled tools and gateway admission/lifecycle errors instead return JSON-RPC errors; not every refusal is an MCP isError result (server.zig, harness).

Five-answer acceptance remains open#

The five-question test dispatches literal synthetic answers through Demo.call; P22 evidence limits that proof to protocol interoperability and transfer accounting, with no model, network, token counter or external source connected. The following acceptance mapping comes from the W13 freeze:

Golden planMissing sole-owner evidence or definition
island_signups_purchasesAuthorized catalog/schema/metric discovery and exact scalar evaluation; the service surface is absent.
compatible_conversion_per_millionOwner-defined formula, time window and compatible coverage; document query does not supply this metric.
changes_around_deploymentThe fixture deployment marker is not the saved-query replacement view supplied by local changes.
projects_on_older_governanceImplemented context and an owner-defined governance version/age relation.
revenue_after_refunds_by_assetA real evidence-handle issuance/expansion path and authorized asset/scale sum; fixture totals alone are insufficient.

The bundled owner question remains unresolved in the freeze. Oracle evidence retains O01/V09 as partial and leaves cost/latency/token claims outside its acceptance; the capability map likewise disclaims an accepted cold/warm/token/latency envelope. A matching current five-answer execution receipt and actual installed-client acceptance remain gaps in this reading set (backlog B04/ER01); no real Oracle walkthrough is established by the fixture test.

  • B19 remains separate: collection-feed polling describes bounded canonical transaction/tombstone polling, while NEXT-GEN R02 requires authorized snapshot-to-durable-feed handover; neither changes local MCP saved-plan semantics (W13 freeze).

  • B02 and B15 remain separate: embedded reconciliation retains PF10/PF11 qualification/status uncertainty, and formal refinement retains unknown current receipt-repair closure; local MCP source presence closes neither gate.

  • B17/B35 remain separate: UBI consumer preparation leaves actual corpus, live import/reopen/restore and native-host acceptance open; synthetic Oracle answers establish none of those prerequisites.

  • B42 link/evidence gaps remain explicit: Sprint 41 evidence names raw W12 logs under .local/change-checks/w12-mcp/, absent in this checkout; the collection-feed guide links to a missing pre-archive PROJECT-INTERNAL contract path. Matching raw logs and a public contract replacement remain gaps, without substituting private archive content or links (backlog reading boundary).