v1 · design partnersoc · console
managed agent + pledge
§ integrations / mcp

MCP, with scope and audit attached.

Model Context Protocol is the agent-to-tools layer the rest of the ecosystem is converging on. Console's MCP adapter makes every tool call enforce the live OC Agent delegation, then emits a signed agent-action envelope as the receipt — content-addressed, scope-bound, and anchored to Bitcoin via the OC Stamp pipeline (OpenTimestamps under the hood).

· v0.1.0 · on npm· published from oc-packages/agent-mcp · MIT

What it does

@orangecheck/agent-mcp wraps an MCP client. Every outgoing tools/call is canonicalized over a minimal { server, tool, arguments } tuple, hashed (SHA-256), and stamped as an agent-action envelope citing the active delegation. Server-side, an MCP server can refuse the call unless the envelope verifies — see the verifying-mcp-server example.

The envelope reuses OC Stamp's canonical envelope structure (BIP-322 authorship, content hash, OpenTimestamps proof) and lives on Nostr kind 30084 with a oc-agent-act:<id> d-tag. It verifies offline with @orangecheck/agent-core against Bitcoin headers — no console.ochk.io reachability required, ever.

What it gives your compliance team

For each agent action: who (Bitcoin address, BIP-322 signed), what (typed scope + canonical tool-call message), when (Bitcoin block height via the OC Stamp pipeline), under what authority (delegation envelope id), and verifiable proof that this combination held at the time the action ran.

What ships today (v0.1.0)

  • canonicalizeInvocation(inv) — RFC 8785 canonical bytes for an MCP invocation, byte-identical across implementations.
  • invocationHash(inv)sha256:-prefixed content hash for the action envelope's content.hash.
  • stampInvocation(input) — sign the envelope without executing the call (pre-authorization or batch stamping flows).
  • invokeWithStamp(input) — stamp first, execute call, return both result and signed action envelope.
  • Sub-scope pre-flight: the helper checks that the exercised scope is admissible against the granted delegation before producing the envelope.

Working examples in the wild

Two complementary references in oc-agent-examples:

  • mcp-wrap — Node CLI that reads a .delegation file, prints the canonical message for the agent to BIP-322-sign, and emits a .action envelope. Private keys never leave the wallet.
  • verifying-mcp-server — stdio MCP-style server that refuses tool calls unless each one carries a valid _oc_agent.{delegation, action} bundle. End-to-end authority loop.

What console adds on top of the package

Console operates the OC Stamp anchor pipeline (the same OpenTimestamps aggregation the family uses), the Nostr relay redundancy, the audit-bundle assembly, and the operator dashboard. The package is open MIT and runnable standalone — Console is the managed tier on top of it.

install · @orangecheck/agent-mcp@^0.1.0
# in your existing mcp client repo
yarn add @orangecheck/agent-mcp \
         @orangecheck/agent-core \
         @orangecheck/agent-signer

# wire env (consumer-only — no private keys)
OC_AUTH_PUBLIC_JWK=…   # public ed25519 jwk (served by ochk.io)
OC_AUTH_ISSUER=https://ochk.io
OC_CONSOLE_PROJECT_ID=…  # design-partner project id
client.ts · invokeWithStamp
import { invokeWithStamp } from '@orangecheck/agent-mcp';

// You already have a SignerRef and a DelegationEnvelope from
// @orangecheck/agent-signer. The delegation grants something like
//   mcp:invoke(server=https://mcp.example.com,tool=invoice.create)

const { result, action } = await invokeWithStamp({
  agent,
  delegation,
  invocation: {
    server:    'https://mcp.example.com',
    tool:      'invoice.create',
    arguments: { customer: 'acme', amount: 14.20 },
  },
  call: async (inv) => myMcpClient.invoke(inv.server, inv.tool, inv.arguments),
});

// `result` is whatever the MCP server returned.
// `action` is the signed envelope — ship it alongside the result, publish
// to Nostr kind 30084, anchor through console.ochk.io's pipeline, etc.
verify.ts · offline · no console.ochk.io
import { verifyAction } from '@orangecheck/agent-core';
import { readFileSync } from 'node:fs';

const action     = JSON.parse(readFileSync('./action.json',     'utf8'));
const delegation = JSON.parse(readFileSync('./delegation.json', 'utf8'));

// no network. no console.ochk.io. just btc headers + math.
const result = await verifyAction(action, {
  delegation,
  btcHeaders: './btc.headers',
});

console.log(result.ok ? 'action verifies' : 'action FAILS');
console.log('agent:',          result.agent);
console.log('scope exercised:', result.scopeExercised);
console.log('anchored block:',  result.anchoredAtBlock);

Already using the package?

If you're running @orangecheck/agent-mcp against your own MCP server today and want Console's managed pipeline (OTS aggregation, Nostr publishing, audit-bundle assembly, the operator dashboard), the design-partner cohort is the path. We pair an OrangeCheck engineer with your team for a half-day to wire it in.