Back to buildsBUILD RECORD

Research MCP Service / Local MCP server package / 2026

Research tools with validated requests and responses.

One versioned schema registry keeps MCP clients and direct callers on the same validated operations, with controlled failures and recorded retries.

Confidential work. Names and identifying business details have been changed.

THE WORK

The project.

Research MCP Service exposes Research Workflow Engine through typed tools. A shared registry defines what each call accepts and returns, and a callable service checks both sides before passing work between the protocol and the parent's packages. Clients get a consistent result or a controlled error without taking ownership of research rules or storage.

IMPLEMENTATION

Design choices.

  1. One callable service sits behind the protocol and direct tests. Both callers get the same validation and handlers, while protocol tests still check registration and transport behavior that a direct call can't exercise.
  2. Output validation makes the tool's promise two-sided. A handler can't silently return a new shape just because its input was valid; the response must still match the versioned schema the client expects.
  3. Tool schemas have their own versions, separate from the package version. A change to one operation can be represented without treating every unrelated schema as a new interface.
  4. Errors need enough detail to guide a retry without exposing arbitrary exceptions. Controlled categories retain that guidance, while the fixed fallback handles failures the service doesn't recognise.
  5. Conflicting retries don't add another failed-write audit event. The service can refuse changed input under a used key without making that refusal look like another original operation.
  6. A single local bundle makes distribution straightforward, but SQLite's native binding is still part of what must run. Packaging and lifecycle tests remain necessary alongside handler tests.

HOW IT FITS TOGETHER

Architecture.

  • The registry supplies tool versions, strict Zod input and output schemas, and annotations to MCP SDK registration. The same operations are available through a directly callable service, so tests and protocol clients don't need separate implementations.
  • The service parses raw input before dispatch, including direct calls that didn't pass through the SDK. It also bounds nested JSON, then delegates research rules and calculations to the parent's domain packages. The shared storage package owns transactions, immutable revisions, retry receipts and audit events.
  • A successful handler result goes back through its declared output schema before reaching the client. Known failures map to controlled categories and retry guidance; unexpected exceptions return a fixed internal error. Eligible failed writes are recorded, while an idempotency conflict doesn't add another failure event for the same attempt.
  • The server uses STDOUT only for protocol messages and STDERR for lifecycle logs. Those logs identify configuration choices without printing data paths or environment values, keeping diagnostics out of both the protocol stream and the request payload.
  • The distributable Node process includes the native SQLite binding and migrations. Startup keeps mutable data away from installed code, and shutdown closes the server and database. This package is part of Research Workflow Engine, not an independently hosted service.
Explore the architecture map9 components · 12 connections

Research MCP Service package boundary

The package owns transport, contracts and dispatch; sibling packages supply domain policy and durable storage.

Direct callResponse / return
MCP host
Research MCP Service
Workspace dependencies

Scroll or drag the background to move. Use the zoom buttons to resize.Arrow keys move between components. Enter selects.

Choose a component to explore

Select a numbered component on the map or use the component menu. Its details and connections will appear here.

No component selected.

All connections (12)
  1. 01 · Codex or MCP client02 · SDK server and STDIO transportSTDIO tool call · Direct call
  2. 03 · Versioned contract registry02 · SDK server and STDIO transportRegister declared surface · Direct call
  3. 02 · SDK server and STDIO transport04 · Core serviceInvoke registered tool · Direct call
  4. 04 · Core service03 · Versioned contract registryCheck input and output · Direct call
  5. 04 · Core service05 · Domain, calculation and source packagesDelegate policy and calculations · Direct call
  6. 04 · Core service06 · Storage package and external data rootRead or write exact records · Direct call
  7. 04 · Core service07 · Controlled error mappingMap operational failure · Direct call
  8. 04 · Core service02 · SDK server and STDIO transportValidated execution result · Response / return
  9. 07 · Controlled error mapping04 · Core serviceControlled error payload · Response / return
  10. 02 · SDK server and STDIO transport08 · Structured tool resultMCP response · Response / return
  11. 09 · Runtime lifecycle02 · SDK server and STDIO transportClose protocol server · Direct call
  12. 09 · Runtime lifecycle06 · Storage package and external data rootClose SQLite handle · Direct call

MADE WITH

TypeScript · Node.js · MCP SDK · Zod · SQLite · esbuild · Vitest

ACCESS & INPUT

Security controls.

  • The tools receive browser observations as data. They don't open a browser, acquire a signed-in session or perform external business actions, and accepting an observation doesn't establish that it is accurate.
  • Strict schemas reject unknown fields, while size, depth, item-count and string-length limits bound nested JSON before dispatch. Malformed writes stop before a handler runs.
  • Unknown exceptions lose their original text in the response. Known errors retain useful messages and remediation, so their constructors still need to avoid including private details; the fallback isn't a sanitizer for every application string.
  • MCP frames and logs use different output streams. Lifecycle messages describe how configuration was selected without exposing actual directory paths or environment values.
  • A valid write that fails can receive a failure audit record. A conflicting retry skips that extra event, preserving the distinction between a recorded attempt and another request to replay it.
  • Startup checks keep mutable data out of protected installation files. Tool annotations describe operations for clients; input checks, domain rules and storage transactions enforce what the operations can do.
Explore the security map9 components · 14 connections

Checks around a local MCP request

Requests are checked before a handler runs. Shared storage manages transactions, and the error mapper chooses which failure details reach the caller.

Direct callResponse / returnBlocked / denied
Local MCP host
Service boundary
Storage dependency

Scroll or drag the background to move. Use the zoom buttons to resize.Arrow keys move between components. Enter selects.

Choose a component to explore

Select a numbered component on the map or use the component menu. Its details and connections will appear here.

No component selected.

All connections (14)
  1. 01 · Local caller and supplied observations02 · Strict bounded input contractTool name and raw input · Direct call
  2. 02 · Strict bounded input contract09 · Protocol result to the callerSchema-invalid response; no handler · Blocked / denied
  3. 02 · Strict bounded input contract03 · Validated service dispatchValidated input · Direct call
  4. 03 · Validated service dispatch04 · Local persistence controlsScoped operation and revision metadata · Direct call
  5. 04 · Local persistence controls05 · External local SQLite dataCommit accepted records and receipts · Direct call
  6. 05 · External local SQLite data03 · Validated service dispatchStored result or exact replay · Response / return
  7. 03 · Validated service dispatch07 · Successful output-schema checkSuccessful handler result · Direct call
  8. 07 · Successful output-schema check09 · Protocol result to the callerDeclared output shape accepted · Response / return
  9. 03 · Validated service dispatch08 · Controlled exception mappingOperational exception · Response / return
  10. 04 · Local persistence controls08 · Controlled exception mappingFailed write or conflicting retry · Blocked / denied
  11. 07 · Successful output-schema check08 · Controlled exception mappingResponse-contract failure · Blocked / denied
  12. 08 · Controlled exception mapping06 · Separate failed-write auditOnly eligible failed writes · Direct call
  13. 06 · Separate failed-write audit08 · Controlled exception mappingAudit recorded or fixed fallback on audit failure · Response / return
  14. 08 · Controlled exception mapping09 · Protocol result to the callerControlled failure; fixed fallback if audit fails · Response / return

CHECKS & RESULTS

What was checked.

A source review shows what the code does. It is not a fresh test of the running app.

  1. Code and development records reviewedReviewed

    The code, tests and available development records were checked. Reported test results keep their original scope. No fresh app or live deployment check was run for this write-up.

    Scope of this check
    Code review, not a fresh run of the app

NEXT

Still to work through.

The service's checks make tool behavior explicit, but direct tests alone don't cover the packaged process or protocol. Those tests were inspected, not rerun, and the installed plugin wasn't compared with this worktree. The server also can't prove the truth of observations supplied by its caller.