Skip to content

[Feature]: MCP get_context cannot produce an audit trail - no receipt requested, no receipt id and no provenance returned #450

Open

Description

@fm1960hamburg

Feature Area

Backend API / Server

Problem Statement

Statewave's audit story works over the HTTP API and not over MCP, which is how most people first use it.

In statewave-connectors, packages/mcp-server/src/client.ts:

  • getContext() sends only subject_id, task and max_tokens. It never sends emit_receipt, and the server default is on_request, so no receipt is written for a call made through the MCP tool.
  • RawContextBundle declares neither receipt_id nor receipt_emitted, so both fields are discarded at parse time even when a receipt was written (for example under tenant config receipts: always).
  • RawMemory does not declare source_episode_ids, and toMemorySearchResult() keeps only id, subject, kind, text and score. Provenance never reaches the agent.
  • toMemorySearchResult() is shared with searchMemories(), so statewave_search_memories drops provenance the same way.

Observed: after recording a demo through Claude Code, GET /v1/receipts?subject_id=… held exactly one receipt, written by a manual curl call — none from the agent's statewave_get_context calls.

The server side is complete: /v1/context accepts emit_receipt and returns receipt_id plus receipt_emitted.

Proposed Solution

  1. Add an optional emit_receipt boolean to the statewave_get_context input schema and pass it through. The tool's schema sets additionalProperties: false, so it has to be declared, not only forwarded.
  2. Widen RawContextBundle with receipt_id and receipt_emitted, and return both in the tool result. Both are needed: without receipt_emitted, an agent cannot tell "no receipt was requested" from "a receipt was requested and emission failed".
  3. Add source_episode_ids to RawMemory and carry it through toMemorySearchResult(), so both statewave_get_context and statewave_search_memories return provenance per memory.
  4. Keep the default off. Tenants that want a receipt for every call set receipts: always; this change makes that setting visible to the agent. Revisit the default once receipt erasure ([Bug]: Receipts keep the subject's task text after subject deletion and after retention expiry #423, [Feature]: Record key destruction as its own receipt, and restrict who can read a subject key #425) has shipped — until then, a receipt keeps the caller's task text and cannot be erased.
  5. The types to widen (MemorySearchResult, ContextBundle, RawContextBundle, RawMemory) are all declared inside packages/mcp-server/src/client.ts, so the change stays inside that package.

Checked against statewave-connectors@a120673 (mcp-server 0.4.8) and statewave main.

API Design (if applicable)

Alternatives Considered

  • Tenant config receipts: always alone: makes the receipt exist, but the agent still never sees its id, so nothing can cite it.
  • Defaulting emit_receipt to true in the MCP server: produces an audit trail nobody asked for, and writes the caller's task text into records that currently cannot be erased.

Priority to You

High - Major improvement needed

Additional Context

No response

Contribution

  • I would be interested in contributing this feature
  • I would be interested in testing this feature

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions