On this page
How the two transports work
euno works in two modes depending on what the client supports:
| Mode | How it works | Clients |
|---|---|---|
| stdio | The MCP client launches euno as a child process (via command + args). euno wraps the upstream server. |
Claude Desktop, Cursor, Windsurf, VS Code |
| HTTP / SSE | You run euno as a persistent HTTP server; the client connects by URL. | JetBrains, web clients, CLI tools, Python/LangChain |
--policy and euno runs as a transparent pass-through that still writes a full OCSF audit log. Add rules once you've seen what traffic looks like.
Claude Desktop
Config file location:
- macOS —
~/Library/Application Support/Claude/claude_desktop_config.json - Windows —
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"filesystem-governed": {
"command": "npx",
"args": [
"-y", "@euno/mcp", "proxy",
"--policy", "/absolute/path/to/euno.policy.yaml",
"--",
"npx", "-y", "@modelcontextprotocol/server-filesystem", "/data"
]
}
}
}
Use an absolute path for --policy — Claude Desktop sets its working directory to a system path, so relative paths won't resolve correctly. Restart Claude Desktop after saving.
Cursor
Global config: ~/.cursor/mcp.json | Project config: .cursor/mcp.json
{
"mcpServers": {
"filesystem-governed": {
"command": "npx",
"args": [
"-y", "@euno/mcp", "proxy",
"--policy", "${workspaceFolder}/euno.policy.yaml",
"--",
"npx", "-y", "@modelcontextprotocol/server-filesystem", "/data"
]
}
}
}
Cursor expands ${workspaceFolder} in the project-level file. Reload the window (Cmd/Ctrl+Shift+P → Developer: Reload Window) to pick up changes.
Windsurf
Config file: ~/.codeium/windsurf/mcp_config.json
{
"mcpServers": {
"filesystem-governed": {
"command": "npx",
"args": [
"-y", "@euno/mcp", "proxy",
"--policy", "/absolute/path/to/euno.policy.yaml",
"--",
"npx", "-y", "@modelcontextprotocol/server-filesystem", "/data"
]
}
}
}
Restart Windsurf or reload the Cascade panel after saving.
VS Code — GitHub Copilot agent mode
VS Code uses a different JSON schema from the mcpServers convention. Create or edit .vscode/mcp.json in your project root:
{
"servers": {
"filesystem-governed": {
"type": "stdio",
"command": "npx",
"args": [
"-y", "@euno/mcp", "proxy",
"--policy", "${workspaceFolder}/euno.policy.yaml",
"--",
"npx", "-y", "@modelcontextprotocol/server-filesystem", "/data"
]
}
}
}
Key differences from the mcpServers format:
- The top-level key is
"servers", not"mcpServers". - Each entry requires
"type": "stdio"explicitly. ${workspaceFolder}is expanded by VS Code at runtime.
For a user-global config, add the entry under "mcp.servers" in your VS Code settings.json with the same shape. Reload the VS Code window to apply changes.
Starting the HTTP proxy
All clients in this section connect to an already-running euno process. Start it once and leave it running:
npx -y @euno/mcp proxy \
--transport http \
--port 7391 \
--policy ./euno.policy.yaml \
-- npx -y @modelcontextprotocol/server-filesystem /data
The proxy listens on http://127.0.0.1:7391/mcp. Use --host 0.0.0.0 if you need to reach it from another machine.
ipRange condition to your policy to restrict which source IPs are allowed to call each tool.
JetBrains AI Assistant
IntelliJ IDEA 2024.3+ and other JetBrains IDEs with the AI Assistant plugin support MCP servers.
Option A — HTTP (recommended)
After starting the HTTP proxy above, open Settings → Tools → AI Assistant → Model Context Protocol (MCP) and add a new server with URL http://127.0.0.1:7391/mcp. No restart required.
Option B — stdio via project mcp.json
Create .ai/mcp.json in your project root:
{
"mcpServers": {
"filesystem-governed": {
"command": "npx",
"args": [
"-y", "@euno/mcp", "proxy",
"--policy", "$PROJECT_DIR$/euno.policy.yaml",
"--",
"npx", "-y", "@modelcontextprotocol/server-filesystem", "/data"
]
}
}
}
$PROJECT_DIR$ is expanded by the JetBrains IDE to the project root. Reload the AI Assistant panel after saving.
Web clients and browser-based agents
Browser-based agents and custom chat UIs that support MCP over SSE connect to the running HTTP proxy. After starting the HTTP proxy, enter:
- Streamable HTTP endpoint:
http://127.0.0.1:7391/mcp - SSE endpoint (for clients that require it explicitly):
http://127.0.0.1:7391/sse
Paste whichever URL the client's MCP server configuration field expects.
CLI tools
MCP Inspector
npx @modelcontextprotocol/inspector --url http://127.0.0.1:7391/mcp
Passing the proxy command inline
For any CLI tool that accepts a --mcp-command style flag:
my-mcp-cli \
--mcp-command "npx -y @euno/mcp proxy --policy ./euno.policy.yaml -- npx -y @modelcontextprotocol/server-filesystem /data"
Shell scripts
# Start the HTTP proxy in the background
npx -y @euno/mcp proxy \
--transport http --port 7391 \
--policy ./euno.policy.yaml \
-- npx -y @modelcontextprotocol/server-filesystem /data &
# Connect with curl (SSE stream)
curl -N http://127.0.0.1:7391/sse
LangChain.js — in-process (no proxy process)
@euno/langchain runs the same enforcement engine inside the LangChain.js tool wrapper — no HTTP hop, no separate process, same YAML policy.
npm install @euno/langchain
import { createLocalRuntime, wrapAsLangChainTool } from '@euno/langchain';
const runtime = await createLocalRuntime({ policyFile: './euno.policy.yaml' });
const queryTool = wrapAsLangChainTool(runtime, {
name: 'query_db',
description: 'Run a read-only SQL query',
schema: {
type: 'object',
required: ['sql'],
properties: { sql: { type: 'string' } },
},
handler: async ({ sql }) => db.query(String(sql)),
});
LangChain.js — HTTP transport
If your LangChain.js agent lives in a different process, start the HTTP proxy (see above) and connect via the MCP SDK:
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
const transport = new StreamableHTTPClientTransport(
new URL('http://127.0.0.1:7391/mcp')
);
const client = new Client({ name: 'my-agent', version: '1.0.0' });
await client.connect(transport);
Python and other language SDKs
Any MCP client SDK can connect to the HTTP proxy. Python example using the official Python MCP SDK:
pip install mcp
from mcp.client.http import HttpClientTransport
from mcp import ClientSession
async with HttpClientTransport("http://127.0.0.1:7391/mcp") as transport:
async with ClientSession(transport) as session:
await session.initialize()
result = await session.call_tool(
"read_file", {"path": "/data/report.csv"}
)
Choosing between stdio and HTTP
| stdio | HTTP | |
|---|---|---|
| Client manages the proxy lifecycle | ✅ | ❌ |
| Multiple clients share one proxy | ❌ | ✅ |
| Works from a browser or remote agent | ❌ | ✅ |
ipRange conditions are enforceable | ❌ | ✅ |
| Zero extra process to manage | ✅ | ❌ |
Use stdio for desktop IDE clients (Claude Desktop, Cursor, Windsurf, VS Code) where the client manages the proxy lifecycle automatically.
Use HTTP for browser-based agents, multi-client deployments, remote workloads (containers, VMs), and any non-Node SDK.
Running without a policy
Omitting --policy makes euno a transparent pass-through that still writes a full OCSF audit log. Use this during initial deployment to observe traffic before writing rules:
npx -y @euno/mcp proxy -- npx -y @modelcontextprotocol/server-filesystem /data
Once you've seen what tools are being called and with what arguments, run:
tail -F ~/.euno/audit.jsonl | jq
Then author a policy based on the actual traffic — see the reference policies for ready-made starting points.
Next steps
- Quick start — 60-second walkthrough including policy authoring and audit log inspection.
- Features — the full condition matrix (
maxCalls,allowedExtensions,ipRange, …) with worked demos. - Reference policies — drop-in YAML for filesystem, Postgres, GitHub, Slack, and fetch.
- Docs — full documentation index including the CLI reference and deployment guide.