StackJack 是一个远程 MCP 代理:AI 客户端连接到单个 MCP 端点,代理使用调用用户的凭据和策略将每个工具调用代理到正确的下游连接器。本文解释了该架构背后的思维模型,每用户 OAuth 和凭据保管如何改变安全边界,以及为什么一旦技术栈跨越 PSA、RMM 和 Microsoft 365,工具目录大小就成为运维约束。然后提供了可运行的诊断程序,用于验证端点可达性、身份验证、工具枚举和审计日志行为。测量值留给读者使用提供的程序收集,而非在此断言。
范围与直接答案
StackJack 最好被理解为一个远程 MCP 代理,而不是捆绑在一个 AI 客户端中的一组集成。您的 AI 客户端——Claude、ChatGPT、Copilot、Cursor 或任何支持远程 MCP 的代理——配置了一个 MCP 端点。StackJack 接收每个请求,解析应由哪个连接器处理,附加已认证用户存储的凭据,应用该用户的策略,并将调用转发到下游平台,如 PSA、RMM 或 Microsoft 365 租户。
本文涵盖架构和验证工作流。它不推荐特定计划、连接器数量或提供商。如果您需要具体的端点或网络建议,请使用 RPC Assistant,而不是将本页视为提供商列表。
代理模型的实际后果是身份转移到代理层。每个团队成员以自己的身份登录,代理决定该身份可以调用哪些工具。这与嵌入客户端配置中的共享服务账户是不同的安全边界。
- 一个客户端端点,多个下游连接器。
- 每用户身份验证,而非客户端中的共享 API 密钥。
- 策略和目录过滤在代理处应用,而非客户端。
- 在代理处捕获审计元数据,理想情况下不保留业务负载。
先决条件与假设
以下程序假设您有一个支持 MCP 的客户端、代理服务上的一个账户,以及至少一个配置了有效凭据的连接器。它们还假设您可以阅读服务的文档以获取确切的 MCP URL 和 OAuth 发现元数据;示例故意使用 MCP_URL 和 CONNECTOR_ID 等占位符,因为将供应商 URL 硬编码到运行手册中是一个维护陷阱。
您应该拥有 curl 以及 Node.js 或 Python 用于诊断脚本。对于审计检查,您需要查看工作区审计日志的权限。对于任何写入路径测试,请使用非生产租户或沙盒连接器,因为打开工单或修改设备的工具调用是真实的副作用。
思维模型:远程 MCP 代理如何代理调用
远程 MCP 代理位于 AI 客户端和 N 个下游系统之间。客户端对代理执行 MCP 初始化并接收工具目录。当模型选择工具时,客户端向代理发送 tools/call 请求。代理将工具名称映射到连接器,从其保管库检索调用者的凭据材料,构造下游 API 请求,并返回规范化结果。
两个设计选择在运维上很重要。第一,无状态性:在内存中保持会话状态的代理会在部署期间丢失会话;每个请求重新认证的无状态端点可以在滚动重启中存活。第二,目录塑造:每个主要 AI 客户端对上下文可容纳的工具数量有上限,一些客户端按字母顺序截断或超过上限后停止加载。暴露数千个工具的代理必须提供紧凑或按需搜索的目录模式,以免客户端在不知不觉中缺少所需的工具。
将代理视为一个 API 网关,在路由之上叠加三项职责:身份联合、凭据保管和目录治理。每一层都可以独立测试,这正是下面诊断部分所利用的。
身份验证边界:OAuth、PKCE 和凭据保管
在每用户模型中,人类使用 OAuth 向代理进行身份验证,对于公共客户端最好使用 PKCE。然后代理持有与该用户关联的下游凭据——要么是粘贴到保管库中的 API 密钥,要么是对下游平台的 OAuth 授权。当用户的 AI 客户端调用工具时,代理使用该用户的凭据,而不是工作区范围的服务账户。
这改变了事件响应。撤销离职员工的代理身份应立即移除其调用下游工具的能力,即使下游 API 密钥本身未变。明确验证这一假设,而不是信任架构图:禁用一个测试用户,然后确认以该身份进行的工具调用在到达连接器之前在代理处失败。
凭据保管还决定了您的爆炸半径。如果代理存储下游密钥,代理被攻破就是下游被攻破。询问凭据是否静态加密、是否曾返回给客户端,以及审计日志仅记录元数据还是负载。最强的姿态是仅记录元数据且零保留业务数据,但您应从供应商文档和自己的日志检查中确认,而不是从营销文案中。
诊断程序:可达性和 OAuth 发现
首先确认端点可达并公布其授权元数据。将 MCP_URL 替换为工作区设置中的 MCP 端点。健康的远程 MCP 端点通常对未认证请求响应 401 或 403,并在支持时暴露指向授权服务器的受保护资源元数据。
记录状态码、WWW-Authenticate 标头以及任何发现文档 URL。这三个值告诉您失败是网络问题、客户端配置错误还是授权服务器问题。
curl -sS -D - -o /dev/null "$MCP_URL" \
-H 'Accept: application/json, text/event-stream'
# If the response advertises protected-resource metadata, fetch it:
curl -sS "$MCP_URL/.well-known/oauth-protected-resource" | jq .诊断程序:枚举工具目录
认证后,列出代理向您的身份暴露的工具。数量和名称是您的基线。保存输出,以便在目录模式更改或连接器更新后进行比较。
下面的脚本通过可流式 HTTP 执行 MCP initialize 然后 tools/list。它使用 MCP_TOKEN 作为通过客户端 OAuth 流获得的 bearer 令牌的占位符;许多客户端内部处理此过程,在这种情况下,使用客户端自己的工具检查视图并与该基线比较。
import json, os, urllib.request
MCP_URL = os.environ["MCP_URL"]
TOKEN = os.environ["MCP_TOKEN"]
def rpc(method, params=None, session=None):
body = json.dumps({"jsonrpc": "2.0", "id": 1, "method": method, "params": params or {}}).encode()
headers = {
"Authorization": f"Bearer {TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json, text/event-stream",
}
if session:
headers["Mcp-Session-Id"] = session
req = urllib.request.Request(MCP_URL, data=body, headers=headers, method="POST")
with urllib.request.urlopen(req) as resp:
return resp.headers.get("Mcp-Session-Id"), resp.read().decode()
session, _ = rpc("initialize", {
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": {"name": "catalog-baseline", "version": "0.1.0"},
})
_, listing = rpc("tools/list", {}, session)
print(listing[:2000])预期验证结果和结果表
成功运行会在未认证探测中产生 401 或 403,一个命名授权服务器的发现文档,以及一个 tools/list 响应,其工具名称清晰地映射到您配置的连接器。如果目录相对于连接器文档记录的工具数量被截断,请切换到紧凑或按需搜索的目录模式并重新运行枚举。
记录您自己的测量值,而不是依赖供应商材料中引用的任何数字。使用如下表格,从您的运行中填写每个单元格:
- | 检查 | 命令或视图 | 观察值 | 通过标准 |
- | 未认证探测状态 | 对
MCP_URL执行curl -D -| 记录 | 401 或 403 | - | 发现文档 |
/.well-known/oauth-protected-resource| 记录 | 命名授权服务器 | - | 工具数量,默认目录 |
tools/list| 记录 | 匹配配置的连接器 | - | 工具数量,紧凑目录 | 模式切换后的
tools/list| 记录 | 符合客户端上限 | - | 测试调用的审计条目 | 工作区审计日志 | 记录 | 带时间戳,仅元数据 |
审计验证:元数据与负载保留
审计日志是代理的问责层。要验证的声明很窄:每个工具调用都记录时间戳、用户、连接器和工具名称,并且记录不包含 AI 看到的业务负载。使用针对沙盒连接器的只读工具调用进行测试,然后检查相应的审计条目。
如果条目包含工单正文、设备清单或消息内容,则保留姿态与仅元数据设计所承诺的不同,您应将审计存储视为敏感业务数据,并具有自己的访问控制。如果条目完全缺失,则代理没有提供您需要的面向客户问责的跟踪记录。
curl -sS "$PROXY_API_URL/audit/events?limit=5" \
-H "Authorization: Bearer $PROXY_API_TOKEN" \
| jq '.events[] | {ts, user, connector, tool, payload_retained}'常见故障模式排查
大多数故障分为四类:客户端无法到达端点,OAuth 流完成但工具缺失,工具调用返回下游授权错误,或会话在部署期间丢失。
对于可达性,检查出口规则以及客户端是否支持带服务器发送事件的可流式 HTTP。对于缺失工具,将目录基线与连接器文档记录的工具列表比较,并检查客户端是否截断了目录。对于下游授权错误,确认用户自己的凭据有效——静默回退到工作区凭据的代理会掩盖每用户故障。对于丢失的会话,优先使用无状态端点并在重新连接时重新初始化。
- 每次调用都 401:令牌过期或受众不匹配;重新运行 OAuth 流。
- 工具存在但调用失败:该用户的下游凭据无效。
- 目录比预期小:达到客户端上限;启用紧凑模式。
- 间歇性断开:部署时会话状态丢失;使用无状态端点。
- 审计缺口:该连接器或用户范围的日志记录被禁用。
代理模型的局限性和权衡
代理集中风险。它是每个 AI 发起的操作流经的单一节点,因此其可用性、授权逻辑和审计完整性成为您运维表面的一部分。每用户凭据改善了归因,但增加了需要轮换的机密数量。目录塑造解决了客户端上限,但增加了搜索步骤,可能隐藏模型原本会直接选择的工具。
广度和控制之间也存在治理权衡。暴露数百个连接器加速跨系统工作流,但每个连接器都是独立的下游 API,具有自己的速率限制、错误语义和权限模型。代理规范化接口,而非底层行为。为每个连接器的测试做预算,而不是假设统一的可靠性。
后续步骤:从验证到生产使用
一旦四项检查通过,分阶段推广配置:首先是只读连接器,然后是沙盒租户中支持写入的连接器,最后是计划自动化。将目录基线和审计查询保留在运行手册中,以便快速检测回归。
如果您的 AI 工作流也涉及区块链数据,同样的纪律适用于 RPC 端点:在信任提供商之前验证可达性、身份验证和响应一致性。RPC Assistant 可以帮助您选择具体端点,Learn 库在指南中涵盖了相关方法论,例如选择可靠的 RPC 端点、多链端点规划和专用节点托管。对于支持这些工作流的基础设施成本建模,请参阅 RPC 定价,并在确定拓扑之前浏览支持的网络。