§ INTEGRATION · MODEL CONTEXT PROTOCOL
MCP client wrapper
One call wraps an MCP ClientSession (Python) or Client (JS). Every callTool runs through Execlave tool-allowlist enforcement before the MCP server is contacted.
Prerequisites
- Execlave account with an active API key — Settings → API keys.
- A registered agent in Execlave. Use its lowercase-kebab
agent_id. - MCP SDK: Python
mcp >=1.0, or JS@modelcontextprotocol/sdk.
Install
Instrumentation ships behind an optional extra (Python) and a subpath export (JS) so default installs do not pull the MCP SDK.
Python
pip install 'execlave-sdk[mcp]'JavaScript / TypeScript
npm install @execlave/sdk @modelcontextprotocol/sdkInstant setup with a copilot
Paste this prompt into your AI coding assistant.
You are adding Execlave (an AI agent governance platform) to an existing project that uses the Model Context Protocol (MCP) SDK. Do not rewrite the MCP server or transport — only attach instrumentation to the CLIENT session. Rules you MUST follow:1. Install the correct extra. Python: `pip install 'execlave-sdk[mcp]'`. JS/TS: `npm install @execlave/sdk @modelcontextprotocol/sdk`.2. Read `EXECLAVE_API_KEY` from environment variables. Never hardcode keys. Add it to `.env.example`.3. Create exactly ONE Execlave client per process and reuse it.4. Wrap the MCP client/session IMMEDIATELY AFTER construction, BEFORE the first `call_tool` / `callTool` invocation. Python: `instrument_mcp_session(session, exe, agent_id="<stable-kebab-id>")`. JS: `instrumentMcpClient(mcp, exe, { agentId: '<stable-kebab-id>' })`.5. `agent_id` is a stable kebab-case string identifying this MCP-using agent in the Execlave dashboard.6. The wrap is IDEMPOTENT — a `_execlave_instrumented` marker is set so calling it twice is a no-op. Do not add your own check.7. Wrap the `call_tool` / `callTool` invocation in try/except for `execlave.errors.PolicyBlockedError` (Python) or `PolicyBlockedError` from `@execlave/sdk` (JS). On block, return a structured 4xx response containing `exc.violations`. Do NOT swallow.8. Do NOT call `exe.enforce_policy` manually before `call_tool` — the wrapper runs tool-allowlist enforcement on the tool name and arguments.9. Both `call_tool(name, args)` and `call_tool({name, arguments})` shapes are handled by the wrapper — do not normalise the call site yourself.10. On process shutdown, call `exe.flush()` (sync) or `await exe.shutdown()` (JS). Deliverables:- One diff per file. Touch only the MCP client construction site and the call site for tool execution.- Add `EXECLAVE_API_KEY` and optional `EXECLAVE_BASE_URL` to `.env.example`. Reference: https://www.execlave.com/docs/integrations/mcpAPI reference: https://www.execlave.com/docs/sdk-referenceQuick start
Wrap the MCP client once; every tool call is governed.
Python
from mcp import ClientSessionfrom execlave import Execlavefrom execlave.integrations.mcp import instrument_mcp_session exe = Execlave(api_key="exe_prod_...") session = ClientSession(...) # your normal MCP setupinstrument_mcp_session(session, exe, agent_id="ops-agent") # Every call_tool now enforces tool-allowlist policies BEFORE the# request reaches the MCP server. A PolicyBlockedError aborts the# call and never contacts the server.result = await session.call_tool("filesystem.read", {"path": "/etc/passwd"})JavaScript / TypeScript
import { Client } from '@modelcontextprotocol/sdk/client/index.js';import { Execlave } from '@execlave/sdk';import { instrumentMcpClient } from '@execlave/sdk/integrations/mcp'; const exe = new Execlave({ apiKey: process.env.EXECLAVE_API_KEY! }); const mcp = new Client({ name: 'ops-app', version: '1.0' }, { capabilities: {} });instrumentMcpClient(mcp, exe, { agentId: 'ops-agent' }); const result = await mcp.callTool({ name: 'filesystem.read', arguments: { path: '/etc/passwd' },});Handling blocks
A blocked tool call raises PolicyBlockedError BEFORE the request reaches the MCP server, so blocked actions cannot leak side-effects.
Python
from execlave.errors import PolicyBlockedError try: result = await session.call_tool(name, arguments)except PolicyBlockedError as exc: return {"error": "blocked", "violations": exc.violations}JavaScript / TypeScript
import { PolicyBlockedError } from '@execlave/sdk'; try { await mcp.callTool({ name, arguments: args });} catch (err) { if (err instanceof PolicyBlockedError) { return { error: 'blocked', violations: err.violations }; } throw err;}What's next
Write your first policy
Tool-allowlist policies pair naturally with MCP servers.
SDK reference
Every Execlave class, method, and error type.
Other integrations
LangChain, OpenAI Agents SDK, CrewAI, LlamaIndex, AutoGen, and more.
OpenAI Chat Completions
Govern the LLM call itself in addition to the MCP tool calls.