MCP代理工具

mcp-relay是一个透明的MCP代理工具,用于安全研究和本地LLM工具调用的行为分析,支持拦截、记录和策略执行。

  • by BoilerToad
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 BoilerToad/mcp-relay

使用说明

mcp继电器

一个透明的MCP代理,用于本地LLM工具调用的安全研究和行为分析。

概述

mcp中继位于本地LLM和任何mcp服务器之间,在模型不知情的情况下拦截并记录每个工具调用。支持Ollama(所有平台)和mlx-lm(苹果硅)作为推理后端。它是专门为实证安全研究而构建的,专门研究LLM对齐是否能在代理部署中提供有意义的保护,防止工具滥用。

能力:

  • 完全呼叫拦截 --在MCP协议层捕获的每个工具调用,包括定时、有效载荷和参数
  • 政策执行 --具有SSRF保护、分配列表、阻止列表和模拟运行模式的中继层URL策略引擎
  • 行为测试语料库 --28个案例,5层提示套件,用于结构化跨模型比较
  • 多模型研究跑步者 --单个命令运行N个模型×M次运行,结果写入SQLite
  • 研究报告 --DB生成的汇总表和实证结果
  • 网络仿真 --降级/离线/重放传输配置文件

安装

git clone https://github.com/BoilerToad/mcp-relay
cd mcp-relay
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"

要求: Python>=3.13, uvx 为了 mcp-server-fetch,以及至少一个推理后端:

  • 奥拉玛 — localhost:11434
  • mlx lm (仅限苹果硅)-- python -m mlx_lm.server --model <name> --port 8080

快速开始

# Unit tests (no Ollama required)
pytest -m "not integration"

# LLM behavioral tests against a single model
pytest tests/test_llm_tool_calls.py -m integration --model qwen2.5:latest

# Multi-model study
python scripts/run_study.py

# Research report
python demo/research_report.py both

运行测试

单元和基础设施测试

pytest -m "not integration" --cov=mcp_relay --cov-report=term-missing

LLM行为测试

# Ollama model
pytest tests/test_llm_tool_calls.py -m integration -v --model qwen2.5:latest

# mlx-lm model (Apple Silicon; start mlx_lm.server first)
pytest tests/test_llm_tool_calls.py -m integration -v \
  --model mlx-community/Qwen3.5-9B-MLX-4bit --backend mlx

# Specific tier
pytest tests/test_llm_tool_calls.py -m integration -k "tier4" --model qwen2.5:latest
pytest tests/test_llm_tool_calls.py -m integration -k "tier5" --model qwen2.5:latest

# Policy engine unit tests (no backend required)
pytest tests/test_policy_engine.py -v

这 --backend 选项接受 ollama 或 mlx如果省略,夹具将从模型名称(a / 意味着mlx-lm)。

看 docs/testing-strategy.md 用于完整的测试套件文档,包括所有测试ID、断言和语料库结构。


多模型研究跑步者

# Quick run (default study — smoke test)
python scripts/run_study.py

# Full study (all confirmed tool-capable models, 3 runs each)
python scripts/run_study.py --study studies/full_study.yaml

# Common overrides
python scripts/run_study.py --runs 1
python scripts/run_study.py --tiers 4 5
python scripts/run_study.py --dry-run
python scripts/run_study.py --db ~/my-study.db

策略引擎

在任何工具调用到达上游MCP服务器之前,策略引擎在中继层强制执行URL访问控制。配置已完成 relay.yaml:

policy:
  enabled: true
  dry_run: false          # WARN instead of BLOCK (observability mode)
  ssrf_protection: true   # blocks 169.254.0.0/16, RFC 1918, loopback, localhost
  url_allowlist: []       # [] = open; or list of permitted hosts
  url_blocklist: []       # substring patterns to block
  extra_blocked_hosts: [] # additional hostnames to block

SSRF保护处理十进制IP表示法(2852039166),IPv6映射的IPv4(::ffff:169.254.169.254)、IPv6 ULA/链路本地和命名元数据主机名。看 docs/testing-strategy.md 用于旁路覆盖和已知限制。


数据库

默认位置: ~/.mcp-relay/research.db

# Custom path
pytest tests/test_llm_tool_calls.py -m integration --model qwen2.5:latest --db /path/to/custom.db
python scripts/run_study.py --db /path/to/custom.db

# Direct inspection
sqlite3 ~/.mcp-relay/research.db ".tables"
sqlite3 ~/.mcp-relay/research.db "SELECT session_id, model_name FROM sessions ORDER BY started_at DESC LIMIT 10;"
表 目录
sessions 每次测试运行一行:模型、时间戳、案例元数据
events 每个工具调用一行:工具名称、参数、延迟、传输模式

会话ID是确定的: {case_id}::{model}。重新运行会覆盖之前的结果。


研究配置

研究在YAML文件中定义 studies/。复制现有文件以创建新研究:

study:
  name: "my_study"
  runs_per_model: 3

models:
  - name: qwen2.5:latest
    enabled: true
    backend: ollama                              # ollama (default) or mlx
  - name: mlx-community/Qwen3.5-9B-MLX-4bit
    enabled: true
    backend: mlx                                 # requires mlx_lm.server on :8080
  - name: gemma3:4b
    enabled: false   # no tools API
    backend: ollama

db: null             # null = ~/.mcp-relay/research.db
tiers: null          # null = all tiers; or [1, 4, 5]
文件 描述
studies/default.yaml 5个型号,每个型号运行1次——烟雾测试(~15分钟)
studies/full_study.yaml 6个模型,每个模型运行3次——发布质量数据(~90分钟)

运输方式

模式 描述
LIVE 完整传递、真实通话、完整日志记录
RECORD 实时+将响应序列化到磁盘以供回放
REPLAY 返回记录的响应,无网络呼叫
DEGRADED 根据配置文件注入延迟和故障
OFFLINE 阻止所有呼叫,拒绝返回连接

内置配置文件: clean, degraded_static, degraded_recovery, adversarial


模型兼容性

奥拉玛 (localhost:11434):

型号 系列 工具API 注释
qwen2.5:最新消息 阿里巴巴 ✓ 确认兼容
qwen3.5:最新消息 阿里巴巴 ✓ 确认兼容
gpt oss:20b OpenAI ✓ 确认兼容
glm-4.7-flash:最新消息 智浦AI ✓ 确认兼容
llama3.2:最新 元 ✓ 确认兼容
Llama3.1:8b 梅塔 ✓ 确认兼容
deepseek-r1:* deepseek ✗ 没有工具API

mlx lm (localhost:8080,仅限苹果硅):

型号 系列 工具API 注释
mlx社区/Qwen3.5-9B-mlx-4bit 阿里巴巴 ✓ ~5.5GB,1-5级已确认
mlx社区/Qwen3-30B-A3B-mlx-4bit 阿里巴巴MoE -- ~18GB,需要36GB+统一内存
llama.cpp (localhost:8080 通过 llama-serverGGUF型号):
型号 系列 工具API 注释
Manojb/Qwen3.5-27B-UD-IQ3_XXS.gguf 阿里巴巴 ✓ ~11GB IQ3_XXS定量,工具调用已确认
完整库存及兼容性说明: studies/full_study.yaml

存储库结构

mcp-relay/
├── mcp_relay/
│   ├── config.py
│   ├── relay.py
│   ├── policy/             # Policy engine
│   │   ├── engine.py
│   │   ├── rules.py
│   │   └── decision.py
│   ├── core/
│   │   ├── intercept.py
│   │   └── logging.py
│   ├── transport/
│   └── storage/
├── tests/
│   ├── fixtures/
│   │   └── test_cases.yaml
│   ├── test_llm_tool_calls.py
│   ├── test_policy_engine.py
│   └── conftest.py
├── scripts/
│   └── run_study.py
├── studies/
│   ├── default.yaml
│   └── full_study.yaml
├── demo/
│   └── research_report.py
├── docs/
│   ├── testing-strategy.md     # Test suite documentation
│   ├── academic-results.md     # Empirical findings and academic framing
│   ├── test-corpus.md          # Per-case corpus documentation
│   ├── literature.md           # Related work
│   └── docx-style-guide.md
└── relay.yaml

许可证

麻省理工学院