Skip to content

Latest commit

 

History

History
45 lines (35 loc) · 3.77 KB

File metadata and controls

45 lines (35 loc) · 3.77 KB

Architecture

mcp-tool-provenance is a small, zero-dependency library with two independent capabilities — result stamping and surface triage — that share nothing but the vendored envelope types. No I/O, no global state, no framework coupling, no MCP SDK dependency.

Module map

Module Responsibility
mcp_tool_provenance/envelope.py stamp() — wrap a tool result with a _toulmin (5-key) + _tags (4-key) envelope, non-destructively. is_stamped() — predicate that an envelope is present and complete. _coerce_toulmin / _coerce_tags normalize either a vendored value object or a plain dict to the canonical envelope dict. TOULMIN_KEYS, TAG_KEYS.
mcp_tool_provenance/triage.py triage() — build a MECE surface map {real_dispatch, read_only, native_only}. drift_check() / assert_no_drift() — the anti-inflation gate (report / raise). surface_summary() — the honest reportable split. DriftReport, DriftError, BUCKETS, classified_set().
mcp_tool_provenance/_vendor/toulmin_argument/ Vendored toulmin-argument v1.0.0 — the ToulminArgument value object used in the envelope.
mcp_tool_provenance/_vendor/provenance_tags/ Vendored provenance-tags v1.0.0 — the ArtifactTags four-dimension tag block used in the envelope.
mcp_tool_provenance/__init__.py Re-exports the public API (incl. the vendored value objects) + __version__.

Data flow

# Stamping
tool handler ──► result dict ──► stamp(result, toulmin=…, tags=…) ──► {**result, _tool?, _toulmin, _tags}
                                       (result unchanged; new dict returned)

# Triage / gate
tool registry (source of truth) ─┐
                                 ├─► drift_check(registry, classification) ──► DriftReport(ok, unclassified, multiply_classified, …)
classification = triage(...) ────┘                                                    │
                                                                  surface_summary(...) ──► honest counts (executes_server_side, native_only_count)

Seams (injection points)

Seam How to use it
Envelope inputs stamp(..., toulmin=, tags=) each accept either the vendored value object (ToulminArgument / ArtifactTags) or a plain dict — build the envelope however your code prefers.
Tool name stamp(..., tool_name=) — optional; recorded under _tool only when non-empty.
The registry drift_check(registry, ...) takes the caller's source-of-truth tool list (e.g. the keys of your adapter dict). The buckets are fixed; the tools are yours.
Report vs. raise drift_check() reports drift (returns a DriftReport); assert_no_drift() raises DriftError carrying that report — pick per call site (runtime probe vs. CI gate).
Runtime dependencies None. The envelope types are vendored (pure stdlib) — see KERNEL_SYNC.md.
Persistence / transport Caller-owned — the library only produces dicts and reports; it never talks to a DB or an MCP socket.

Design invariants

  • Stamping is non-destructive. The input payload is never mutated; a fresh dict is returned with the original keys verbatim plus the envelope.
  • The envelope shape is fixed. _toulmin always has exactly the five argument keys; _tags always has exactly the four tag keys.
  • Triage is MECE or it fails. A classification is valid only when every registry tool is in exactly one of the three fixed buckets — drift_check is the enforcement, not a convention.
  • Domain-neutral. No default value, bucket, or tool name references any industry or product. The buckets describe what a tool does (dispatch / read / guidance), not what domain it serves.