Quick start

Ship a governed agent in 60 seconds

Three commands and a YAML file. The proxy runs locally, wraps any MCP server, and enforces policy before the upstream is ever contacted.

On this page

Prerequisites

1. Install

You can run @euno/mcp directly with npx — no global install required:

npx -y @euno/mcp --version

Or install once for repeated use:

npm install -g @euno/mcp

2. Author a policy

A policy is a single YAML file describing which tools are allowed and the conditions on each call. Save the following as euno.policy.yaml:

agentId: filesystem-agent
name:    Filesystem Agent
version: 0.1.0

requiredCapabilities:
  - resource: read_file
    actions: [call]
    conditions:
      - type: allowedExtensions
        extensions: [".csv", ".json", ".txt", ".md"]
      - type: maxCalls
        count: 50
        windowSeconds: 60

  - resource: list_directory
    actions: [call]

The schema is a literal subset of AgentCapabilityManifest from @euno/common-core — there is exactly one shape, no drift between proxy and the rest of the system.

3. Validate the policy

npx -y @euno/mcp validate ./euno.policy.yaml

Validation runs without contacting any server and rejects unknown condition types and malformed YAML up front.

4. Run the proxy

Wrap any MCP server with the proxy. Everything after -- is the upstream command:

npx -y @euno/mcp proxy \
  --policy ./euno.policy.yaml \
  -- npx -y @modelcontextprotocol/server-filesystem /data

The proxy speaks MCP on stdio in both directions and is transparent to clients.

5. Try it from a host

Point your MCP host (or any client) at the proxy command above. From Claude Desktop, attempt to read /data/keys.pem — the proxy denies it before the upstream is contacted, and the agent receives a structured CapabilityDenied error.

6. Inspect the audit log

Every decision — allow or deny — is recorded as a signed OCSF API Activity event:

tail -F ~/.euno/audit.jsonl | jq

For aggregated denial counts, run:

npx -y @euno/mcp stats

This prints an ASCII histogram grouped by condition type and denial code, including rotated log files.

Connect a client

How you point a client at the proxy depends on whether it launches the server itself (stdio) or connects to a running process over HTTP. The full guide covering Claude Desktop, Cursor, Windsurf, VS Code, JetBrains, web clients, CLI tools, and LangChain is on the client setup page. A quick reference for the most common stdio clients is below.

Claude Desktop / Cursor / Windsurf

Add the proxy as an mcpServers entry in the client's config file (e.g. claude_desktop_config.json for Claude Desktop, ~/.cursor/mcp.json for Cursor, ~/.codeium/windsurf/mcp_config.json for Windsurf):

{
  "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 — these clients set the working directory to a system path. Restart or reload the client after saving.

VS Code (GitHub Copilot agent mode)

VS Code uses a different schema. Create .vscode/mcp.json in your project:

{
  "servers": {
    "filesystem-governed": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y", "@euno/mcp", "proxy",
        "--policy", "${workspaceFolder}/euno.policy.yaml",
        "--",
        "npx", "-y", "@modelcontextprotocol/server-filesystem", "/data"
      ]
    }
  }
}

Note "servers" (not "mcpServers") and the required "type": "stdio" field. VS Code expands ${workspaceFolder} at runtime.

For JetBrains, web clients, CLI tools, and programmatic SDKs see the full client setup guide →

Without --policy the proxy is transparent — handy for capturing an audit trail before you write any rules.

HTTP transport · LangChain.js

For agents that connect over HTTP rather than stdio, run the proxy as an HTTP server:

npx -y @euno/mcp proxy \
  --transport http --port 7391 \
  --policy ./euno.policy.yaml \
  -- node ./my-mcp-server.js

Connect your client to http://127.0.0.1:7391/mcp. The same policy file works on both transports — and ipRange conditions become enforceable here.

In-process LangChain.js

If your agent runs LangChain tools in-process and you don't want a separate proxy process, install @euno/langchain and wrap your tool:

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)),
});

Same YAML, same conditions, same audit format — no transport hop.

Next steps