KellerKev/smcp

GitHub: KellerKev/smcp

SMCP 为模型上下文协议(MCP)增加身份验证、逐消息加密和多智能体协调能力,使 MCP 工具能够安全地跨网络和智能体间运行。

Stars: 0 | Forks: 0

# SMCP — 安全模型上下文协议 [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![MCP-compatible](https://img.shields.io/badge/MCP-compatible-6E56CF.svg)](https://modelcontextprotocol.io/) ## 🎬 演示:运行中的多智能体商业智能 ![CrewAI + SMCP 演示](https://static.pigsec.cn/wp-content/uploads/repos/cas/da/da594470bc6d54bdb6ebea56c1d3486a4abd4c7eb5675d6187d5f3c47c3d1cfe.gif) *CrewAI + SMCP 编排多个 AI 智能体,利用本地 Ollama 模型、DuckDB 和安全的多智能体协调,基于 电子商务、SaaS 和物联网数据生成商业智能报告。* ## 🚀 什么是 SMCP [MCP](https://modelcontextprotocol.io/) 是为 AI 模型提供工具的绝佳方式,但它是为 **本地、可信的传输**(单台机器上的 stdio)而构建的。**SMCP 完全保留 MCP 的工具模型, 并将其封装在安全 + 协调层中**,因此相同的工具可以*跨机器*和 *在智能体之间*工作: - 🔒 **身份验证** — `api_key` → JWT 会话,带有可选的非对称 (RS256) 模式,因此 服务器签发令牌,客户端可以验证但无法伪造 - 🔐 **加密** — 经过身份验证的单条消息负载加密;使用 ECDH 密钥交换实现 具有前向保密性的会话密钥 - 🛡️ **默认故障关闭** — 服务器/客户端拒绝使用空的、弱的或 公开已知的密钥启动;拒绝向非环回主机进行明文传输 - 🔁 **重放保护** — 签名的消息带有 freshness 时间窗口,并且只能被接受一次 - 🤝 **多智能体 (A2A)** — 智能体间的发现和编排,支持串行或并行 - 🔌 **连接器** — 经过强化的 DuckDB 和文件系统集成,用于构建工具 - ✅ **兼容 MCP** — 安全是可选的;标准的 MCP 工具继续工作 选择适合的姿态 — 从用于本地测试的简单 API 密钥到 带有审计追踪的单条消息加密(请参阅下方的[安全模式](#-security-modes))。 ## 📚 文档 ### 架构与设计 - [**架构概述**](docs/ARCHITECTURE_OVERVIEW.md) - 完整的系统架构、数据流和设计模式 - [**演示架构**](docs/DEMO_ARCHITECTURES.md) - 每个演示的详细步骤流程解析 - [**MCP 与 SMCP 对比**](docs/MCP_SMCP_COMPARISON.md) - 标准 MCP 与 SMCP 的全面比较 - [**用例**](docs/USE_CASES.md) - 实际应用和实施场景 ### 技术指南 - [**AI SQL 生成指南**](docs/AI_SQL_GENERATION_GUIDE.md) - 使用 LLM 生成 SQL 查询 - [**连接器开发指南**](docs/CONNECTOR_DEVELOPMENT_GUIDE.md) - 构建自定义连接器 - [**CrewAI 集成**](docs/CREWAI_SMCP_INTEGRATION.md) - 将 CrewAI 与 SMCP 集成 ## ✨ 关键特性 ### 🔐 安全模式 根据部署进行选择 — 相同的工具,根据需要提供更强的安全姿态: - **简单** — API 密钥身份验证 → JWT 会话(本地/开发) - **基础** — JWT 会话;依赖 TLS (`wss://`) 进行传输安全 - **加密** — ECDH 密钥交换 + 经过身份验证的单条消息负载加密 - **企业** — 针对外部身份提供商的 OAuth2 client-credentials(JWKS 或 固定的静态公钥),并进行完整的令牌验证 无论处于何种模式,安全层都是**故障关闭**的:`SMCPConfig.validate()` 会拒绝空的、 过短的、占位符或公开已知的密钥,并且如果验证失败,`SMCPServer` 和 `SMCPClient` 都会拒绝 启动。 ### 🔑 非对称令牌 (RS256) 默认情况下,JWT 使用共享密钥 (HS256) 签名 — 这在单一信任域内是没有问题的。对于 多方部署,请设置 `jwt_algorithm="RS256"` 并使用服务器持有的私钥和客户端 公钥:服务器生成令牌,客户端验证它们,而客户端**无法伪造自己的令牌**。 ### 🏢 外部 IdP OAuth2(企业模式) 企业模式验证来自外部身份提供商的 OAuth2 访问令牌。它**故障关闭**: 需要 `oauth2.audience`、`oauth2.issuer` 和一个密钥源(`oauth2.jwks_url` **或** `oauth2.local_public_key_path`),令牌使用固定为 RS256 的算法进行验证,并要求包含 `exp`/`iat`/`aud`/`iss`,对 IdP 的调用强制使用带有证书 验证的 HTTPS(可以通过 `oauth2.ca_cert_path` 固定 CA 证书包),并且自动处理 JWKS 密钥 轮换。由针对模拟 OIDC 提供商(令牌 endpoint + JWKS)运行的端到端测试套件覆盖,包括错误的受众、错误的签发者、过期的、 `alg=none`、HS/RS 混淆以及密钥轮换等情况。 ### 🤖 智能体到智能体 (A2A) 系统 - 多智能体任务编排 - 动态智能体发现 - 并行和串行工作流 - 每个工具的授权(令牌范围授权给特定工具,而不是所有工具) ### 🔌 原生连接器 - **DuckDB**:高性能分析查询。默认**关闭**文件系统/网络访问, 在 DuckDB 引擎级别强制执行(`enable_external_access`);过滤原始 SQL 中的 文件/网络/扩展访问,验证标识符,并将批准的文件加载限制在 已配置的目录中。使用 `allow_raw_file_sql` 显式选择启用原始文件 SQL。 - **文件系统**:安全的本地存储,具有符号链接安全的路径包含功能,在 读取/删除/列表(不仅仅是写入)上强制执行扩展名白名单,以及读取/写入大小上限。 - **可扩展**:易于添加自定义连接器。 ### 🏗️ 技术特性 - 通过 TOML/YAML/ENV 进行配置,具有严格的优先级顺序 - 日志和监控示例 - 连接上限、单客户端速率限制和由服务器强制执行的消息大小限制 ## 📦 安装 ### 前置条件 - Python 3.11+ - [Pixi](https://pixi.sh) 包管理器 - [Ollama](https://ollama.ai)(用于演示中的 AI 功能) - Docker(仅用于 MindsDB 集成示例) ### 快速开始 1. **克隆代码库**: ``` git clone https://github.com/KellerKev/smcp.git cd smcp ``` 2. **使用 pixi 安装依赖**: ``` # 如果你还没有安装 pixi,请先安装 curl -fsSL https://pixi.sh/install.sh | bash # 核心环境(快速) pixi install # 可选:重量级集成(CrewAI + MindsDB SDK) pixi install -e integrations ``` 3. **设置 Ollama 并为演示拉取一个小型模型**: ``` # 安装 Ollama,然后: ollama serve & # 示例默认使用一个轻量、快速的模型: ollama pull llama3.2:1b ``` 示例/测试模型是可配置的 — 设置 `SMCP_DEMO_MODEL` 以使用不同的模型: ``` export SMCP_DEMO_MODEL="qwen2.5-coder:7b-instruct-q4_K_M" ``` 4. **(可选)用于 MCP-bridge / ML 示例的 MindsDB**: ``` docker run -d --name smcp-mindsdb -p 47334:47334 -p 47337:47337 mindsdb/mindsdb # 等待直到健康,然后验证: curl http://localhost:47334/api/status ``` 📚 **完整安装指南**:有关详细说明,请参阅 [SETUP_GUIDE.md](SETUP_GUIDE.md)。 ## 🧪 测试 ``` # 完整的 pytest 套件(security、connectors 和端到端 server/client) pixi run test # 仅 crypto 互操作向量 pixi run test-interop ``` 该套件涵盖了配置验证、移除旧的演示后门、重放/过期 拒绝、单工具授权、JWT 签发者/受众/过期时间、RS256 仅验证客户端、TLS 强制执行、DuckDB 注入/路径限制以及文件系统遍历/大小上限。 external-IdP OAuth2 流程针对模拟 OIDC 提供商进行了端到端测试。 服务器/客户端端到端测试在环回地址上启动真实的服务器和客户端(如果 Ollama 或演示模型不可用,基于 Ollama 的 测试会自动跳过)。 ## 🎯 快速演示 示例脚本会自动生成强大的、基于机器的演示密钥(缓存在 被 git 忽略的 `examples/.demo_secrets.json` 中),因此服务器和客户端可以在强化的 验证下互操作,而代码库中没有任何密钥。 ### 1. 服务器 + 客户端端到端 ``` # 终端 1 pixi run example-server # 终端 2 pixi run example-client ``` 执行 handshake → auth → capability discovery → 工具调用,加上实时的 Ollama 调用。 ### 2. DuckDB 分析 ``` pixi run python tools/generate_sample_data.py # writes sample_data/ pixi run duckdb-example ``` 加载数万行数据,让模型从业务问题中生成 SQL,通过 SMCP DuckDB 连接器执行它,并分析结果。 ### 3. 完整系统展示 ``` pixi run python examples/showcase_complete_system.py ``` ### 4. 多智能体报告生成 (CrewAI) ``` pixi run -e integrations crewai-report-demo ``` 针对本地 Ollama 运行数据分析师 → 业务分析师 → 报告撰写者 → 质量审查员智能体 ,并将执行报告写入 `./crewai_reports/`。 ### 5. MindsDB 集成(需要上述的 MindsDB 容器) ``` pixi run python examples/basic/basic_a2a_mcp_sample.py pixi run python examples/mindsdb_integration_example.py ``` ## 🏃 运行服务器并连接客户端 ### 服务器 ``` # 生成一个带有全新强 secrets 的 config,然后启动: pixi run create-config pixi run server ``` ### 客户端(库) ``` import secrets from smcp_client import SMCPClient from smcp_config import SMCPConfig # Secrets 是必需的,并且必须与 server 的匹配(shared-secret 模式)。 # 对于弱/空值,server 拒绝启动,且 client 拒绝连接。 config = SMCPConfig( mode="basic", server_url="ws://localhost:8765", api_key=secrets.token_urlsafe(32), secret_key=secrets.token_urlsafe(32), jwt_secret=secrets.token_urlsafe(32), kdf_salt=secrets.token_urlsafe(16), ) config.security.allow_insecure_transit = True # loopback only; use wss:// in production client = SMCPClient(config) await client.connect() capabilities = client.list_capabilities() result = await client.invoke_tool("calculator", operation="add", a=15, b=27) await client.disconnect() ``` ## 📁 项目结构 ``` smcp/ ├── smcp_*.py # Core SMCP modules ├── connectors/ # Native connector implementations │ ├── smcp_duckdb_connector.py │ └── smcp_filesystem_connector.py ├── examples/ # Demo applications │ ├── _demo_support.py # Shared strong-secret helper for the demos │ ├── basic/ # Basic (JWT) mode examples │ ├── encrypted/ # Encrypted mode examples │ └── *.py # Integration examples ├── tests/ # Pytest suite (security, connectors, e2e) ├── tools/ # Utility scripts (sample data, key generation) ├── docs/ # Documentation └── pixi.toml # Environments and tasks ``` ## 🔧 配置 SMCP 按以下优先级顺序合并配置(优先级从高到低):CLI 参数 → 环境变量 → 配置文件 → 默认值。必须提供密钥;如果缺失或太弱,应用程序将故障关闭。 ### 环境变量 ``` export SCP_API_KEY="$(python -c 'import secrets;print(secrets.token_urlsafe(32))')" export SCP_SECRET_KEY="$(python -c 'import secrets;print(secrets.token_urlsafe(32))')" export SCP_JWT_SECRET="$(python -c 'import secrets;print(secrets.token_urlsafe(32))')" export SCP_KDF_SALT="$(python -c 'import secrets;print(secrets.token_urlsafe(16))')" export SCP_MODE="basic" ``` 完整列表请参见 [.env.example](.env.example)。在联邦中的各节点之间共享 `SCP_SECRET_KEY` / `SCP_JWT_SECRET` / `SCP_KDF_SALT`。 ### TOML ``` pixi run create-config # writes scp_config.toml with fresh strong secrets ``` ## 🛡️ 安全说明 1. **密钥** — 32 个字符以上的随机 `secret_key`/`jwt_secret`,16 个字符以上的 `kdf_salt`;永远不要提交它们。 `validate()` 会拒绝空/过短/占位符/已知值。 2. **传输** — 设置 `security.tls_enabled=True`(带上证书/密钥)并在 生产环境中使用 `wss://`/`https://`。明文仅允许用于环回地址,且仅在 设置了 `security.allow_insecure_transit` 时允许。 3. **令牌** — 当客户端不应该能够 生成自己的令牌时,使用 `jwt_algorithm="RS256"`(服务器私钥,客户端公钥)。 4. **连接器** — 除非你需要主机文件/网络 访问权限,否则保持 DuckDB 的 `enable_external_access=False`,并设置 `data_dir` 以限制 文件操作。 ## 🤝 MCP 兼容性 SMCP 保持了 MCP 工具模型的完整;安全层是附加的。标准的 MCP 工具继续 工作,并且 [MCP bridge](smcp_mcp_bridge.py) 将 SMCP 连接到外部 MCP 服务器(除非 目标是环回地址,否则拒绝通过明文发送凭据)。 ## 📄 许可证 该项目基于 MIT 许可证授权。 ## 🚦 状态 - ✅ **核心 SMCP**:经过安全强化并由测试覆盖(106 项测试) - ✅ **基础/加密模式**:经过安全强化,由测试覆盖 - 🚧 **A2A 系统**:带有单工具授权的工作原型(localhost 模拟) - ✅ **DuckDB / 文件系统连接器**:经过强化,默认故障关闭,由测试覆盖 - ✅ **CrewAI 集成**:可运行的演示(在 `integrations` 环境中) - ✅ **MindsDB 集成**:可运行的演示(需要 MindsDB 容器) - ✅ **企业 / OAuth2 模式**:external-IdP 令牌验证,经过强化并由测试覆盖 (JWKS + 静态密钥),已针对模拟 OIDC 提供商进行验证 - 🚧 **联合身份验证**:带有 RS256 仅验证支持和 测试套件的绑定 audience/issuer 的令牌;默认为共享的 HS256 密钥(对于多方信任,请使用 RS256) **想要探索 MCP 安全概念?** 请从上方的[快速演示](#-quick-demo)开始。
标签:AI风险缓解, Python, 人工智能, 多智能体, 无后门, 模型上下文协议, 用户模式Hook绕过, 请求拦截, 逆向工具, 通信安全