Keon MCP网关
受监管的MCP网关,用于在AI工具执行中添加策略执行、租户绑定、收据和持久内存挂钩,具有较低的客户端采用摩擦。
以两种方式之一使用它:
- 官方MCP通过流式HTTP
POST /mcp - 官方MCP通过stdio
--stdio
这是什么
此服务位于Keon Runtime Gateway的前面,并公开了一个受管的工具界面,该界面:
- 验证JWT或网关API密钥
- 绑定
tenant_id和actor_id故障关闭 - 按工具范围强制执行
- 需要
Decide之前任何Execute - 验证遗留请求和响应信封
contracts/mcp_gateway.v1.schema.json - 发出耐用的入口脊收据
directive,intent,和终端outcome - 在MCP中保留规范管理的信封
structuredContent
这不再只是一个自定义HTTP适配器。它现在公开了标准的MCP方法,因此现有的支持MCP的客户端可以直接连接。
运输支持
| 用例 | 传输 | 路径/模式 | 状态 |
|---|---|---|---|
| 远程MCP客户端 | 可流式HTTP | POST /mcp | 支持 |
| 本地MCP客户端 | stdio | --stdio | 支持 |
SSE流来自 GET /mcp | 流式HTTP可选功能 | GET /mcp | 尚未发射 |
实施MCP方法
initializenotifications/initializedpingtools/listtools/call
支持的MCP协议版本
2025-11-252025-06-182025-03-26
对于基于浏览器的HTTP客户端,默认情况下会阻止非环回源。向添加明确的来源 McpServer:AllowedOrigins 当您希望在本地主机之外访问浏览器时。
刀具表面
keon.governed.execute.v1keon.launch.hardening.v1
通过MCP:
tools/list返回标准MCP工具描述符tools/call返回中的摘要文本content- 完整的受控Keon信封保存在
structuredContent - 故障返回
isError=true
在传统的HTTP界面上:
- 请求和响应体使用规范的Keon模式信封
快速入门
先决条件
- .NET 10 SDK
- 如果你想使用附带的JWT演示助手,请使用Python
构建和测试
dotnet restore tests\Keon.McpGateway.Tests\Keon.McpGateway.Tests.csproj
dotnet test tests\Keon.McpGateway.Tests\Keon.McpGateway.Tests.csproj
dotnet build src\Keon.McpGateway\Keon.McpGateway.csproj默认本地URL
http://localhost:50002分钟内首次成功呼叫MCP
此路径使用承载令牌。对于JWT模式, tenant_id 和 actor_id 可以从声明中导出,因此您不需要额外的MCP标头。
1.创建本地开发令牌和密钥对
安装Python依赖项一次:
pip install pyjwt cryptography铸造代币和密钥对:
$auth = python .\examples\demo_jwt.py `
--tenant-id tnt_123 `
--actor-id usr_456 `
--scopes keon:mcp:list keon:mcp:invoke keon:execute `
--private-key "$env:TEMP\keon-mcp-private.pem" `
--public-key "$env:TEMP\keon-mcp-public.pem" | ConvertFrom-Json
$env:Auth__JwtPublicKeyPem = Get-Content -Raw $auth.public_key
$env:KEON_MCP_BEARER_TOKEN = $auth.token2.运行网关
dotnet run --project src\Keon.McpGateway\Keon.McpGateway.csproj3.初始化MCP会话
$headers = @{
Authorization = "Bearer $env:KEON_MCP_BEARER_TOKEN"
}
Invoke-RestMethod `
-Uri "http://localhost:5000/mcp" `
-Method Post `
-Headers $headers `
-ContentType "application/json" `
-Body '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","clientInfo":{"name":"manual-smoke","version":"1.0.0"},"capabilities":{}}}'4.列出工具
$headers["MCP-Protocol-Version"] = "2025-06-18"
Invoke-RestMethod `
-Uri "http://localhost:5000/mcp" `
-Method Post `
-Headers $headers `
-ContentType "application/json" `
-Body '{"jsonrpc":"2.0","id":"tools-list","method":"tools/list","params":{}}'5.调用受管工具
Invoke-RestMethod `
-Uri "http://localhost:5000/mcp" `
-Method Post `
-Headers $headers `
-ContentType "application/json" `
-Body '{
"jsonrpc":"2.0",
"id":"call-1",
"method":"tools/call",
"params":{
"name":"keon.governed.execute.v1",
"arguments":{
"purpose":"Summarize recent sent emails for weekly status update",
"action":"summarize",
"resource":{"type":"email","scope":"mailbox:sent"},
"params":{"window_days":7,"max_items":25},
"mode":"decide_then_execute"
}
}
}'MCP结果将包含:
- 人类可读的摘要文本
result.content - 规范统治的信封
result.structuredContent decision,receipts,以及result适用于内存和审计处理的有效载荷
与现有MCP客户端一起使用
流式HTTP客户端配置
当您的客户端通过HTTP支持远程MCP服务器时,请使用此选项。
{
"type": "streamable-http",
"url": "http://localhost:5000/mcp",
"headers": {
"Authorization": "Bearer ",
"MCP-Protocol-Version": "2025-06-18"
}
}笔记:
- 对于JWT模式,
tenant_id和actor_id可以从象征性的声明中得出。 - 对于API密钥模式,包括
X-Api-Key,X-Keon-Tenant-Id,以及X-Keon-Actor-Id. - 对于浏览器客户端,配置
McpServer:AllowedOrigins.
stdio客户端配置
当您的客户端希望启动本地MCP服务器进程时,请使用此选项。
先构建:
dotnet build src\Keon.McpGateway\Keon.McpGateway.csproj然后将客户端指向构建的DLL:
{
"type": "stdio",
"command": "dotnet",
"args": [
"D:\\Repos\\keon-omega\\keon-mcp-gateway\\src\\Keon.McpGateway\\bin\\Debug\\net10.0\\Keon.McpGateway.dll",
"--stdio"
],
"env": {
"KEON_MCP_BEARER_TOKEN": ""
}
}可选的stdio环境变量:
KEON_MCP_BEARER_TOKENKEON_MCP_API_KEYKEON_MCP_TENANT_IDKEON_MCP_ACTOR_ID
笔记:
- 在承载令牌模式中,
tenant_id和actor_id可以从象征性的声明中得出。 - 在API-key模式下,设置
KEON_MCP_TENANT_ID和KEON_MCP_ACTOR_ID. - 更喜欢内置的DLL或
dotnet run --no-build ... -- --stdio因此,对于MCP流,stdout保持干净。
身份验证模式
JWT
当您希望租户和参与者身份绑定到已签名的声明时,请使用承载身份验证。
网关强制执行:
- 发行人和受众验证
- 通过以下方式进行签名验证
Auth:JwtPublicKeyPem或Auth:JwksUrl - 所需网关范围加上每个工具范围
- 关闭租户和参与者绑定失败
典型范围:
keon:mcp:listkeon:mcp:invokekeon:executekeon:attest
API密钥
当您希望通过网关侧授权检查采用低摩擦的服务到服务时,请使用API密钥验证。
网关强制执行:
- 密钥格式和秘密验证
- 活动API密钥和环境状态
- 租户权利状态
- 受控执行的配额检查
- 成功调用时持久使用事件发件箱写入
对于HTTP MCP客户端,发送:
X-Api-KeyX-Keon-Tenant-IdX-Keon-Actor-Id
对于stdio MCP客户端,设置:
KEON_MCP_API_KEYKEON_MCP_TENANT_IDKEON_MCP_ACTOR_ID
治理和内存生命周期
每个受管调用都遵循相同的核心路径:
- 接受请求并绑定租户和参与者
- 发射
directive - 发射
intent - 请求运行时
Decide - 如果批准并提出要求,请致电
Execute - 发射终端
outcome
收据密钥在规范信封中是稳定的。当生命周期阶段未发生或引用不可用时,值可以为空:
directiveintentrequest当尝试执行并发出请求时decisionexecution执行成功时outcome一旦终端结果发射成功evidence_pack可用时
这是治理和记忆的基础:
- 代理获得标准MCP结果
- 应用程序获取结构化收据和终端状态
- 该平台具有耐用的内存挂钩和审计材料
MCP工具结果示例
tools/call 返回标准MCP结果。受控的Keon信封保存在里面 structuredContent.
{
"jsonrpc": "2.0",
"id": "call-1",
"result": {
"content": [
{
"type": "text",
"text": "keon.governed.execute.v1 completed with decision approved. Receipts are available in structuredContent."
}
],
"structuredContent": {
"correlation_id": "c01J9Z8Q6X4J5Y2P9H3K8M7N6",
"tool": "keon.governed.execute.v1",
"ok": true,
"decision": {
"status": "approved",
"policy_hash": "sha256:9c1af02e"
},
"result": {
"summary": "done"
},
"receipts": {
"directive": "rcpt_dir_01J9Z9",
"intent": "rcpt_int_01J9Z9",
"request": "rcpt_req_01J9Z9",
"decision": "rcpt_dec_01J9Z9",
"execution": "rcpt_exe_01J9Z9",
"outcome": "rcpt_out_01J9Z9",
"evidence_pack": null
}
},
"isError": false
}
}传统兼容性界面
原始HTTP端点仍然可用于已经直接集成规范Keon信封的系统。
POST /mcp/tools/list
请求架构: ToolsListRequest
响应架构: ToolsListResponse
POST /mcp/tools/invoke
请求架构: ToolsInvokeRequest
响应架构: ToolsInvokeResponse
看 contracts/README.md 和 contracts/mcp_gateway.v1.schema.json.
配置
src/Keon.McpGateway/appsettings.json
{
"Runtime": {
"BaseUrl": "http://localhost:8080",
"TimeoutSeconds": 5,
"MaxRetries": 2
},
"ControlPlane": {
"BaseUrl": "http://localhost:5000",
"TimeoutSeconds": 3
},
"IngressSpine": {
"Mode": "Off",
"ConnectionString": "Data Source=ingress-spine.db"
},
"RateLimiting": {
"Enabled": false,
"PermitLimit": 20,
"WindowSeconds": 60
},
"McpServer": {
"ServerName": "Keon MCP Gateway",
"SupportedProtocolVersions": [ "2025-11-25", "2025-06-18", "2025-03-26" ],
"AllowedOrigins": [],
"DefaultTenantId": "",
"DefaultActorId": "",
"DefaultBearerToken": "",
"DefaultApiKey": ""
},
"Auth": {
"Issuer": "keon-auth",
"Audience": "keon-mcp-gateway",
"JwksUrl": "",
"JwtPublicKeyPem": "",
"RequiredScopes": []
}
}重要设置
IngressSpine:Mode
Off:无入口持久性BestEffort:追加失败会被记录下来,并且永远不会阻止请求完成Required:附加故障被故障关闭;如果directiveappend失败,运行时从未被调用
McpServer:AllowedOrigins
- 空表示只接受非浏览器和环回浏览器来源
- 为基于浏览器的远程客户端添加显式源
McpServer:DefaultTenantId 和 McpServer:DefaultActorId
- 当调用客户端无法注入自定义MCP标头时,对于stdio模式非常有用
- 已携带的不记名代币不需要
tenant_id和actor_id
McpServer:DefaultBearerToken 和 McpServer:DefaultApiKey
- 用于本地开发或严格控制的发射器环境
- 更喜欢环境变量而不是在配置中检查机密
Keon SaaS运行时
$env:Runtime__BaseUrl = "https://api.keon.systems"
dotnet run --project src\Keon.McpGateway\Keon.McpGateway.csproj指向企业运行时
$env:Runtime__BaseUrl = "https://keon-runtime.internal"
dotnet run --project src\Keon.McpGateway\Keon.McpGateway.csproj码头工人
构建:
docker build -t keon-mcp-gateway .运行:
docker run --rm -p 8080:8080 `
-e Runtime__BaseUrl=http://host.docker.internal:8080 `
-e Auth__JwtPublicKeyPem="
" `
keon-mcp-gateway集装箱港口:
http://localhost:8080健康、限速和操作说明
GET /health验证下游运行时状态,并返回网关和运行时状态- 在以下情况下,速率限制适用于公共MCP路由
RateLimiting:Enabled=true /mcp目前支持请求/响应流式HTTP;SSE流媒体GET /mcp尚未发射- stdio模式用于本地MCP客户端启动,应在没有额外stdout噪声的情况下运行
示例和演示
包括示例:
examples/invoke_client.py:传统HTTP调用客户端examples/langchain_keon_tool.py:LangChain包装机examples/demo_jwt.py:薄荷本地开发JWT和键盘examples/mint_token.ps1:从现有私钥中提取JWTexamples/mock_runtime_server.py:演示运行时
信任失败演示:
.\examples\demo_trust_failure_runtime_down.ps1.\examples\demo_policy_deny_blocks_summarize.ps1
预期成果:
- 运行时关闭路径失败
- 拒绝路径不执行
- 脊椎入口仍有记录
directive -> intent -> outcome
工具架构
最小的工具元数据和遗留模式存在于:
contracts/mcp_gateway.v1.schema.jsonvendor/keon-contracts/Hardening/schema/hardening_attestation.v1.schema.json
测试覆盖率
自动化套件包括:
- 6个黄金有效载荷的模式夹具验证
- 批准并执行
- 拒绝而不执行
- 缺失范围
- 租户不匹配
- 运行时不可用
- 通过决策和执行来保持相关性
- 所需脊柱行为
- 尽力脊椎行为
- 速率限制
- 主控程序
initialize - 主控程序
tools/list - 主控程序
tools/call - MCP原产地执行
延迟
- SSE响应流
GET /mcp - MCP资源、提示和其他非工具功能
- 在当前SQLite支持的接收器之外,指令、意图、请求和结果收据的实时脊椎持久性
- 真实的
keon.launch.hardening.v1当前受控决策存根之外的执行接线 - 远程git托管和PR发布
CI/CD
工作流
- PR验证:
.github/workflows/pr-validation.yml - 临时部署:
.github/workflows/deploy-staging.yml
必需的GitHub机密
AZURE_CLIENT_ID:GitHub OIDC登录的Azure联合身份应用客户端IDAZURE_TENANT_ID:用于OIDC登录的Azure租户IDAZURE_SUBSCRIPTION_ID:用于ACR和容器应用程序操作的Azure订阅ID
必需的GitHub存储库变量
ACR_NAME:不带FQDN的Azure容器注册表名称ACR_LOGIN_SERVER:ACR登录服务器,例如myregistry.azurecr.ioACR_IMAGE_REPOSITORY:ACR中的图像仓库路径,例如keon-mcp-gatewayACA_RESOURCE_GROUP:包含容器应用程序的资源组ACA_APP_NAME:用于暂存的Azure容器应用程序名称STAGING_HEALTHCHECK_URL:健康URL的可选覆盖
分支保护和所需检查
保护 main 并要求:
Restore, Build, Test, Python Smoke
推荐:
- 合并前需要拉取请求
- 需要线性历史记录或挤压合并
- 限制直接推送
main - 合并前需要进行状态检查
叉PR安全
- 临时部署不在拉取请求上运行
- 部署仅在受保护的设备上运行
main或手动workflow_dispatch免受保护main - 临时环境审批可以阻止部署
打破玻璃回滚运行手册
- 识别最后一个已知的良好图像标签。
- 使用最低权限操作员凭据向Azure进行身份验证。
- 回滚容器应用程序映像。
- 对烟雾进行检查
/health. - 在事件记录中捕获回滚详细信息。
