Pre-alpha 文档
安全调用一个 Stateless MCP Tool。
连接有界 StateKnot MCP 2026-07-28 Tool Client,理解 Trust Boundary,处理 MRTR,并复现固定官方证据。
选择正确的 MCP 边界
McpClient- 动态互操作:发现有界 Tool Catalog、保留不可信 Wire Schema、调用 Tool、 接收 Request-scoped SSE,并由 Host 介入 Multi-round Input。
McpRemoteTool- 需要恢复与结果核对的外部副作用:固定已审核 Server/Input/Output Identity,先提交 Dispatch Evidence,保留不确定 Write,并在不 Redispatch 的前提下 Reconcile。
发现并调用一个 Tool
生产 Endpoint 强制 HTTPS。每个 Stateless POST 都独立解析 Authorization, 因此生产 Provider 可以轮换 Credential。不要把 Secret 放入 Endpoint URL、 Request Metadata 或 Log。
use std::sync::Arc;
use serde_json::json;
use stateknot_integrations::{
ApiKey, McpClient, McpClientIdentity, McpClientOptions,
McpToolCall, ProviderEndpoint, StaticMcpBearerAuthorization,
};
let client = McpClient::connect(
ProviderEndpoint::https("https://mcp.example.com/mcp/")?,
McpClientIdentity::new("inventory-agent", "1.0.0")?,
Arc::new(StaticMcpBearerAuthorization::new(
ApiKey::new(std::env::var("MCP_TOKEN")?)?,
)),
McpClientOptions::default(),
)
.await?;
let catalog = client.list_tools().await?;
let tool = catalog.find("inventory_lookup").ok_or("Tool unavailable")?;
let response = client.call_tool(tool, json!({ "sku": "STK-001" })).await?;
match response.into_outcome() {
McpToolCall::Complete(result) => println!("{}", result.content().len()),
McpToolCall::InputRequired(pending) => {
// 把每个请求路由到可信 Host 子系统,绝不自动批准。
println!("{} inputs required", pending.input_requests().len());
}
_ => return Err("unsupported future outcome".into()),
}
依赖 Catalog 形态前先检查 rejected_tools()。无效
x-mcp-header Descriptor 会被单独排除,永远不可调用,也不会隐藏
有效 Sibling。
始终把 Discovery 与 Output 视为不可信
- Tool Description、Annotation、Schema、Content、Structured Content、 Notification 与 Server Instruction 都不会自动授予权限。
-
Network
$ref会被保留但绝不 Dereference;执行本地 Validation 前必须应用 Offline Allowlist Schema Policy。 -
String、Integer、Boolean
x-mcp-header只从静态可达 Property 派生。不安全 Byte 使用 MCP Base64 Sentinel,Null 与缺失值被省略。 -
Tool-level
isError仍是可供 Agent 恢复的 Result;Transport 与 Protocol Failure 是类型化 Client Error。
每一轮 MRTR 都必须由 Host 介入
input_required Result 拥有原始 Tool、Arguments、Client 与 Opaque
requestState。Host 必须把每个声明 Request
路由到可信子系统,并 精确返回所需 Key。resume 会消费 Pending Value、使用全新
JSON-RPC ID、在 State 存在时精确回传,而且绝不跨调用泄漏。StateKnot 不会自动批准
Elicitation 或虚构 Roots/Sampling 数据。
给每次 Exchange 设置边界
| 资源 | 默认值 |
|---|---|
| Logical Request / 并发请求 | 30 s / 16 |
| Catalog Page / Entry | 16 / 1,024 |
| Request / JSON Response | 16 MiB / 2 MiB |
| SSE Line / Event / Total | 512 KiB / 2 MiB / 64 MiB |
| 每个 Response 的 Notification | 1,024 |
Logical Request Deadline 的硬上限为 24 小时。Redirect 与 Generic Retry 被禁用;Timeout 或 Tool Response 丢失后绝不自动 Replay。Protocol Version Negotiation 在 Server 明确声明该版本后获得一次有界 Retry。Bearer Challenge 只有 Authorization Provider 显式批准后才默认获得一次 Replay,并使用新 JSON-RPC ID。详见MCP OAuth Client 合约。
复现证据
cargo test -p stateknot-integrations --test mcp_client_contract --locked
bash conformance/mcp-client/run-2026-07-28.sh 固定官方 Runner 通过全部 32 个计分 Client 场景,包括全部 25 个 OAuth 场景: 371 项计分 Assertion Success、0 Failure,11 项 Surface 外检查明确 Skip。 提出兼容性声明前请阅读精确 Conformance 边界。