Resources

Examples

Copy-paste connection snippets for the most common MCP clients, plus end-to-end agent examples in TypeScript and Python. All examples target the local dev URL; swap the host for the production URL when it goes live July 20, 2026.

Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\\Claude\\claude_desktop_config.json (Windows):

jsonclaude_desktop_config.json
{
  "mcpServers": {
    "cortex": {
      "url": "http://localhost:3002/mcp",
      "headers": {
        "Authorization": "Bearer dev-mcp-token-CHANGE-ME"
      }
    }
  }
}

Restart Claude Desktop. Cortex tools appear in the slash-command picker.

Cursor

In Cursor → Settings → MCPAdd new MCP server:

jsonCursor MCP settings
{
  "cortex": {
    "url": "http://localhost:3002/mcp",
    "headers": {
      "Authorization": "Bearer dev-mcp-token-CHANGE-ME"
    }
  }
}

Continue (VS Code / JetBrains)

yamlcontinue config.yaml
mcpServers:
  - name: cortex
    transport:
      type: streamable-http
      url: http://localhost:3002/mcp
    headers:
      Authorization: Bearer dev-mcp-token-CHANGE-ME

MCP Inspector

The fastest way to debug a misbehaving client is to bypass the client entirely:

bash
npx @modelcontextprotocol/inspector \
  --transport streamable-http \
  --server-url http://localhost:3002/mcp \
  --header "Authorization: Bearer dev-mcp-token-CHANGE-ME"

The inspector renders every tool with its schema, lets you call them one at a time, and shows the raw JSON-RPC payloads on both sides.

TypeScript — full agent

typescriptcortex-agent.ts
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';

const URL = 'http://localhost:3002/mcp';
const TOKEN = process.env.CORTEX_TOKEN ?? '';

async function main(): Promise<void> {
  const transport = new StreamableHTTPClientTransport(new URL(URL), {
    requestInit: {
      headers: { Authorization: `Bearer ${TOKEN}` },
    },
  });

  const client = new Client(
    { name: 'cortex-example-agent', version: '0.1.0' },
    { capabilities: {} },
  );
  await client.connect(transport);

  // 1. Recall recent memory about Sarah
  const recall = await client.callTool({
    name: 'memory.recall',
    arguments: { query: "what's sarah's current role?", topK: 3 },
  });
  console.log('recall:', recall);

  // 2. Check current trust level for outreach to Sarah
  const trust = await client.callTool({
    name: 'trust.check',
    arguments: {
      action_class: 'communicate',
      counterparty_id: 'entity_01HXSARAH',
    },
  });
  console.log('trust:', trust);

  // 3. Draft an outreach message (returns pending_approval in Phase 0)
  const draft = await client.callTool({
    name: 'action.communicate',
    arguments: {
      to: 'entity_01HXSARAH',
      message: 'Quick check — does Tuesday 2pm still work?',
      tone: 'warm',
    },
  });
  console.log('draft:', draft);

  await client.close();
}

main().catch((err) => {
  console.error(err);
  process.exit(1);
});

Python — full agent

pythoncortex_agent.py
import asyncio
import os
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

URL = "http://localhost:3002/mcp"
TOKEN = os.environ["CORTEX_TOKEN"]
HEADERS = {"Authorization": f"Bearer {TOKEN}"}

async def main() -> None:
    async with streamablehttp_client(URL, headers=HEADERS) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()

            # 1. Recall recent memory about Sarah
            recall = await session.call_tool(
                "memory.recall",
                {"query": "what's sarah's current role?", "topK": 3},
            )
            print("recall:", recall)

            # 2. Check trust for outreach
            trust = await session.call_tool(
                "trust.check",
                {
                    "action_class": "communicate",
                    "counterparty_id": "entity_01HXSARAH",
                },
            )
            print("trust:", trust)

            # 3. Draft an outreach message
            draft = await session.call_tool(
                "action.communicate",
                {
                    "to": "entity_01HXSARAH",
                    "message": "Quick check — does Tuesday 2pm still work?",
                    "tone": "warm",
                },
            )
            print("draft:", draft)

asyncio.run(main())

cURL — the JSON-RPC underneath

Helpful when you want to confirm the wire shape independent of any SDK. This invokes memory.recall in stateless mode:

bash
# Step 1: initialize (no mcp-session-id header — server assigns one)
curl -s http://localhost:3002/mcp \
  -H "Authorization: Bearer dev-mcp-token-CHANGE-ME" \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2025-03-26" \
  -d '{
    "jsonrpc":"2.0","id":1,"method":"initialize",
    "params":{
      "protocolVersion":"2025-03-26",
      "capabilities":{},
      "clientInfo":{"name":"curl","version":"0"}
    }
  }' -i

# Step 2: call memory.recall using the session id from step 1's response header
curl -s http://localhost:3002/mcp \
  -H "Authorization: Bearer dev-mcp-token-CHANGE-ME" \
  -H "Content-Type: application/json" \
  -H "mcp-session-id: <PASTE_SESSION_ID_HERE>" \
  -d '{
    "jsonrpc":"2.0","id":2,"method":"tools/call",
    "params":{
      "name":"memory.recall",
      "arguments":{"query":"sarah","topK":3}
    }
  }'

TypeScript — handler that verifies and calls back

The minimum-viable handler: an Express endpoint that verifies the Cortex signature, executes the action through your own channel, and calls back trigger.complete (or trigger.reverse later if the user undoes). Drop into any Node 22+ project; swap the channel implementation for Slack, email, SMS, whatever your app owns.

typescripthandler.ts — Express + @cortex/sdk-ts
import express from 'express';
import { createHmac, timingSafeEqual } from 'node:crypto';

const app = express();
app.use(express.json({
  verify: (req, _res, buf) => { (req as any).rawBody = buf.toString('utf8'); },
}));

const WEBHOOK_SECRET = process.env.CORTEX_WEBHOOK_SECRET!;
const PRINCIPAL_TOKEN = process.env.CORTEX_PRINCIPAL_TOKEN!;
const CORTEX_HOST = 'https://mcp.cortex.jakeselby.com';
const FIVE_MIN = 5 * 60 * 1000;

function verifyCortexDispatch(req: express.Request): { ok: true } | { ok: false; reason: string } {
  const sig = String(req.headers['x-cortex-signature'] ?? '').replace(/^sha256=/, '');
  const ts  = String(req.headers['x-cortex-timestamp'] ?? '');
  if (!sig || !ts) return { ok: false, reason: 'missing_headers' };

  const tsMs = Date.parse(ts);
  if (Number.isNaN(tsMs)) return { ok: false, reason: 'bad_timestamp' };
  if (Math.abs(Date.now() - tsMs) > FIVE_MIN) return { ok: false, reason: 'stale' };

  const expected = createHmac('sha256', WEBHOOK_SECRET)
    .update(ts + '.' + (req as any).rawBody, 'utf8')
    .digest('hex');

  const a = Buffer.from(expected, 'hex');
  const b = Buffer.from(sig, 'hex');
  if (a.length !== b.length || !timingSafeEqual(a, b)) {
    return { ok: false, reason: 'signature_invalid' };
  }
  return { ok: true };
}

app.post('/cortex', async (req, res) => {
  const verified = verifyCortexDispatch(req);
  if (!verified.ok) return res.status(401).json({ error: verified.reason });

  const trigger = req.body as {
    trigger_id: string;
    action_class: string;
    mode: 'act' | 'notify_after' | 'ask' | 'test';
    payload: { body?: string; preview?: { body: string } };
    counterparty?: { id: string; display_name: string };
  };

  // Ack within 30s — return 200 quickly, do the work async.
  res.status(200).end();

  // ... execute through your own channel (Slack / email / in-app / SMS / etc) ...
  const externalRef = await sendThroughYourChannel(trigger);

  // Close the loop with trigger.complete
  await fetch(`${CORTEX_HOST}/v1/triggers/${trigger.trigger_id}/complete`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${PRINCIPAL_TOKEN}`,
      'Content-Type': 'application/json',
      'Idempotency-Key': `cb_${trigger.trigger_id}`,
    },
    body: JSON.stringify({
      outcome:      trigger.mode === 'ask' ? 'approved' : 'executed',
      external_ref: externalRef,
      executed_at:  new Date().toISOString(),
    }),
  });
});

async function sendThroughYourChannel(trigger: {
  counterparty?: { display_name: string };
  payload: { body?: string };
}): Promise<string> {
  // Replace with your real channel send. Returns an external reference your app can resolve.
  console.log('sending to', trigger.counterparty?.display_name, ':', trigger.payload.body);
  return 'msg_' + Math.random().toString(36).slice(2);
}

app.listen(3000, () => console.log('Cortex handler listening on :3000'));

cURL — mock an inbound dispatch against your handler

Useful during local development before Cortex can dispatch for real. Below: sign a fake envelope with a chosen secret and POST it to your handler. The headers and canonical string match what Cortex sends in production.

bash
# Configure
HANDLER_URL="http://localhost:3000/cortex"
WEBHOOK_SECRET="whsec_test_replace_me"
TS=$(date -u +%Y-%m-%dT%H:%M:%SZ)

# Build the trigger body (one JSON line, no surrounding whitespace in signature)
BODY='{
  "trigger_id":"trg_TESTHANDLER",
  "decision_id":"dec_TEST",
  "action_class":"communicate",
  "mode":"ask",
  "counterparty":{"id":"entity_test","display_name":"Test Recipient"},
  "payload":{"body":"Hello from a mock dispatch","preview":{"mime":"text/plain","body":"..."}},
  "reasoning":"Mock for handler integration",
  "reversal":{"path":"undo in app within 60min","window_sec":3600,"callback_url":"https://mcp.cortex.jakeselby.com/v1/triggers/trg_TESTHANDLER/reverse"},
  "expires_at":"2026-12-31T00:00:00Z",
  "schema_version":"2026-07-20",
  "links":{"decision_url":"https://app.cortex.jakeselby.com/decisions/dec_TEST","ledger_url":"https://app.cortex.jakeselby.com/ledger/led_TEST"}
}'

# Compute HMAC-SHA256 over (timestamp + "." + body)
SIG=$(printf "%s.%s" "$TS" "$BODY" | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET" -binary | xxd -p -c 999)

curl -s "$HANDLER_URL" \
  -H "X-Cortex-Signature: sha256=$SIG" \
  -H "X-Cortex-Trigger-Id: trg_TESTHANDLER" \
  -H "X-Cortex-Idempotency-Key: trg_TESTHANDLER" \
  -H "X-Cortex-Schema-Version: 2026-07-20" \
  -H "X-Cortex-Timestamp: $TS" \
  -H "Content-Type: application/json" \
  -d "$BODY" -i