Edison Watch
Developers

Claude Agent SDK

Connect Anthropic's Claude Agent SDK (Python or TypeScript) to Edison Watch as a streamable-HTTP MCP server, and keep a stable session per conversation so data-leak protection holds across every turn.

Anthropic's Claude Agent SDK (the SDK behind Claude Code) has no dedicated MCP class - you declare servers in an mcpServers map with type: "http". Your connection URL carries your API key, so no auth header is needed.

MCP tools must be explicitly allowed or Claude will see them but never call them. Add mcp__<server-name>__* to allowedTools / allowed_tools - here the server is named edison, so allow mcp__edison__*. A connection that "does nothing" is almost always a missing-allowed-tools problem, not an auth problem.

pip install claude-agent-sdk
import asyncio
import os

from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage

async def main() -> None:
    options = ClaudeAgentOptions(
        mcp_servers={
            "edison": {
                "type": "http",
                "url": os.environ["EDISON_MCP_URL"],
            }
        },
        allowed_tools=["mcp__edison__*"],
    )
    async for message in query(prompt="List my available tools.", options=options):
        if isinstance(message, ResultMessage) and message.subtype == "success":
            print(message.result)

asyncio.run(main())

Set EDISON_MCP_URL to your connection URL, e.g. https://mcp.edison.watch/mcp/<your-api-key>/?client=claude-agent.

npm install @anthropic-ai/claude-agent-sdk
import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
  prompt: "List my available tools.",
  options: {
    mcpServers: {
      edison: {
        type: "http",
        url: process.env.EDISON_MCP_URL!,
      },
    },
    allowedTools: ["mcp__edison__*"],
  },
})) {
  if (message.type === "result" && message.subtype === "success") {
    console.log(message.result);
  }
}

Keep a stable session across turns to preserve data-leak protection

Send a stable x-edison-conversation-id header on every turn of the same conversation. That header is what keeps Edison's data-leak protection intact across a multi-turn run: Edison tracks lethal-trifecta risk per session, so if each turn looks like a brand-new session, that protection resets - and a later turn can leak data that the accumulated risk should have blocked.

Hosted clients (Claude Code, VS Code) send it automatically. For a custom agent, set the header yourself on the server entry, keyed to your own conversation or thread id - and reuse that id on every turn:

"edison": {
    "type": "http",
    "url": os.environ["EDISON_MCP_URL"],
    "headers": {"x-edison-conversation-id": conversation_id},
}
edison: {
  type: "http",
  url: process.env.EDISON_MCP_URL!,
  headers: { "x-edison-conversation-id": conversationId },
}

Without a stable x-edison-conversation-id, each connection is treated as a fresh session that starts with empty risk state - so risk accumulated on an earlier turn won't be there to block a later exfiltration. The ?client= label is only a dashboard tag, not a session key. Use a unique id per conversation (a UUID is ideal); ids are scoped to your API key, so don't reuse one string for two different conversations.

Optional: the encrypted-secrets header

For servers with zero-knowledge-encrypted secrets, add an x-edison-secret-key header to the server entry, alongside x-edison-conversation-id:

"edison": {
    "type": "http",
    "url": os.environ["EDISON_MCP_URL"],
    "headers": {
        "x-edison-conversation-id": conversation_id,
        "x-edison-secret-key": os.environ["EDISON_SECRET_KEY"],
    },
}
edison: {
  type: "http",
  url: process.env.EDISON_MCP_URL!,
  headers: {
    "x-edison-conversation-id": conversationId,
    "x-edison-secret-key": process.env.EDISON_SECRET_KEY!,
  },
}