关于 Thalovant MCP
Thalovant MCP 将 Thalovant 控制平面与 Hub 运行时 API 接入 MCP 客户端,面向需要发现、管理 Hub 并调用运行时能力的 Agent。支持本地 stdio 与远程 Streamable HTTP,并提供身份验证和工具策略配置。
主要功能
- 01通过 stdio 和 Streamable HTTP 连接
- 02发现并管理 Hub 与运行时组
- 03访问运行时技能、记忆和分析
- 04支持设备登录及令牌认证
- 05配置主体凭据与工具策略
- 06提供限流、审计日志和会话绑定
适用场景
- 01从 MCP 客户端发现 Thalovant Hub
- 02配置 Hub 或运行时组
- 03管理运行时技能和记忆条目
- 04通过远程 HTTP 接入 Thalovant
MCP 相关
该 MCP 服务通过 stdio 或 `/mcp` 上的 Streamable HTTP 连接 MCP 客户端,并将 Thalovant 控制平面及 Hub 运行时能力作为工具提供。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
50收录的工具列表 · 更新于 3 天前
此工具无需参数。
详细介绍
最后编辑:Codex(确切的运行时模型标识符不可用)- 2026-10-25 - 原因:记录安全依赖兼容性和下一个补丁版本。
Thalovant MCP 服务
可用于生产环境的 Thalovant 控制平面和中心运行时 API MCP 服务。
此服务使用官方 Thalovant Node.js SDK 和生产级 MCP TypeScript SDK,通过 stdio 和 Streamable HTTP 运行,因此可与 Claude Desktop、Codex、Cursor 等本地 MCP 主机以及远程 MCP 客户端配合使用。
包含内容
- 为本地 Agent 提供 stdio 传输。
- 在
/mcp提供 Streamable HTTP 传输,供远程 Agent 使用。 - 在
/.well-known/oauth-protected-resource提供 OAuth 风格的受保护资源元数据。 - 支持静态 bearer token,适用于简单或私有部署。
- 支持 JWT/JWKS 和 OAuth token introspection,适用于生产环境远程部署。
- 支持按主体配置 Thalovant 凭据和工具策略。
- 提供主机/来源验证、CORS、速率限制、请求体大小限制、安全标头和会话绑定。
- 可选的可恢复性事件存储和 JSONL 审计日志。
- 提供 Docker、Compose、Kubernetes、CI、npm 包元数据和 MCP 注册表
server.json。
为什么选择 TypeScript
Thalovant 提供 Python、Node.js、Go 和 Rust SDK。此服务选择 Node.js,因为 @thalovant/sdk 可直接提供 Thalovant 控制平面、身份加载、WSS/HTTPS/MQTT 运行时客户端、记忆、分析和上下文辅助工具;而对于跨 Agent 的 stdio 和 Streamable HTTP 服务,@modelcontextprotocol/sdk 是支持最完善的方案。
安装
使用 npx -y @thalovant/mcp-server 运行已发布的包,或从代码检出版本构建:
npm install
npm run build
需要 Node.js 20 或更高版本。
控制平面身份验证
公开中心发现无需 Thalovant 凭据。私有控制平面工具和运行时中心工具只会从 MCP 服务环境或服务端主体凭据文件中读取凭据。请勿通过聊天或工具参数传递 API token 或密码。
服务按以下顺序选择控制平面身份验证方式:
THALOVANT_API_TOKEN— 范围受限的 Thalovant API token。推荐使用。THALOVANT_ACCESS_TOKEN— 预先签发的会话访问 token。THALOVANT_EMAIL+THALOVANT_PASSWORD— 交互式账户登录备用方式。
设置了 token 后,服务绝不会调用登录端点。thalovant_config_status 会通过 controlPlaneAuthMode 报告当前模式,但不会泄露 token 值。
如果以上变量均未配置,用户也可以通过浏览器登录服务:请参阅设备登录。登录时签发的 token 仅会在以上配置均不存在时使用。
设备登录
工具调用无法等待人员操作,因此设备授权流程(RFC 8628)分为两个工具:
thalovant_begin_device_login可选接受scopes(空列表与不传相同,表示请求 API 的默认范围)、clientName和clientId,并返回loginId、userCode、verificationUri、verificationUriComplete、interval和expiresIn。向用户显示 URL 和代码。clientId会以已注册应用的身份登录;Home Assistant 使用thalovant-home-assistant:审批页面会将平台名称显示为已验证,再次批准会替换该应用已有的令牌。API 不认识的 ID 会被拒绝(400unknown_client)。thalovant_poll_device_login使用该loginId查询一次。outcome可能为pending(在interval秒后再次查询;如果 API 要求减慢查询速度,则已额外增加 5 秒)、approved(附带tokenId、scopes和expiresAt)、expired或denied。
设备代码和令牌不会传给模型:服务器会在进程运行期间保存它们,并将二者绑定到发起登录的主体。批准后,该主体的所有控制平面工具在未配置凭据时都会使用此令牌。thalovant_revoke_device_login 用于退出登录:它会撤销该令牌(令牌始终可以撤销自身,已撤销的令牌也视为已撤销),并将其删除;再次退出登录时,无需发出请求便会返回 alreadyRevoked,且绝不会触及已配置的令牌。登录请求只会发送到已配置的 API 来源(THALOVANT_API_URL,或默认来源),因为返回的验证 URL 会显示给用户。Home Assistant 的连接请求 hubs:read、clients:read 和 clients:write;Free 套餐也只能批准这些范围。
API 令牌(推荐用于 AI Agent 和 CI)
范围受限的 API 令牌是用于 AI 和自动化的合适凭据:它们从 Thalovant 控制面板(或通过设备授权流程)生成,仅携带你授予的权限范围,可单独撤销,并且绝不会涉及你的账户密码或 MFA。令牌以 tvpat_ 开头。
export THALOVANT_API_TOKEN="tvpat_..."
export THALOVANT_API_URL="https://api.thalovant.com"
npm start
完整控制平面工具集所需的最低权限范围:
| 权限范围 | 用途 |
|---|---|
hubs:read | thalovant_list_hubs、thalovant_get_hub、thalovant_get_analytics_overview、thalovant_list_marketplace_skills、thalovant_list_runtime_groups、thalovant_get_runtime_group、thalovant_get_runtime_group_config、thalovant_update_runtime_group_config 中受保护的合并读取操作,以及 thalovant_create_client_identity 中的 hub 查询 |
hubs:inspect | thalovant_get_hub_runtime_capabilities、thalovant_list_runtime_group_marketplace、thalovant_list_runtime_group_inventory、thalovant_list_hub_skills、thalovant_list_hub_skill_history |
hubs:write | 所有 hub 和运行时组的配置操作:thalovant_create_hub、thalovant_update_hub、thalovant_release_hub、thalovant_create_runtime_group、thalovant_update_runtime_group、thalovant_update_runtime_group_config、thalovant_release_runtime_group、thalovant_install_runtime_group_skill、thalovant_uninstall_runtime_group_skill、针对单个 hub 的 thalovant_install_hub_skill、thalovant_update_hub_skill、thalovant_remove_hub_skill、hub 评分工具,以及选择启用的删除工具 |
clients:write | thalovant_create_client_identity(POST /v1/clients)和选择启用的 thalovant_delete_client |
memory:read | thalovant_list_memory_items、thalovant_get_memory_summary、thalovant_get_memory_item |
memory:write | thalovant_create_memory_item、thalovant_update_memory_item、thalovant_delete_memory_item |
hub 权限范围彼此包含:hubs:write 授予 hubs:read,而 hubs:read 又授予 hubs:inspect 和 hubs:preview。因此,生成具有 hubs:read 权限范围的令牌,就足以使用上表中的所有发现工具。
配置操作所需的不只是权限范围。所有 hub 和运行时组写入操作还要求付费套餐,且 API 会先检查权限范围,再检查套餐,因此两种失败情况按以下顺序出现:
- 缺少权限范围的令牌会返回
403 Insufficient scopes。免费套餐 API 令牌的权限范围上限为hubs:read、clients:read和clients:write,因此在免费套餐中,配置操作会以此 403 失败,不会到达 402 检查。 - 权限范围正确但使用免费套餐的令牌会返回
402 API access requires a paid plan. - 如果套餐为付费套餐,但不包含
access_tier: paid目录条目,thalovant_install_runtime_group_skill可能会返回另一种不同的 402:This skill requires paid marketplace access for the tenant plan.
发现操作有意不受付费限制:免费套餐令牌可以浏览市场目录并设置 hub 评分,但不能安装技能或配置 hub。 安装前请使用 thalovant_list_runtime_group_marketplace — 它会针对每项技能报告 installable、purchase_required 和 access_message,让你能够提前做出决定,而不是面对含义不明的 402。
部署范围越窄,授予的权限范围就应越少:只读助手仅需 hubs:read 和 memory:read;只浏览技能、从不进行配置的发现型 Agent 仅需 hubs:read。使用 admin: true 调用 thalovant_get_analytics_overview 还需要具备 admin:analytics 权限的管理员账户;常规使用的 API 令牌不应携带此权限。运行时 hub 工具(thalovant_ask、thalovant_send_action 等)使用 Thalovant 客户端身份,而非控制平面令牌。
Hub Etag
thalovant_update_hub 和 thalovant_delete_hub 使用乐观锁定,需要提供 Hub 当前的 etag,并通过 If-Match 发送。etag 仅在 Hub 资源的正文中提供——API 不会发送 ETag 响应头——因此 Agent 必须先调用 thalovant_get_hub,并传入该响应中的 etag 字段。缺少该值或值已过期都会导致 412 ETag mismatch,且不会更改任何内容;请重新获取并重试。创建后,name、namespace 和 domain 均不可更改,因此 thalovant_update_hub 完全不接受这些字段;只发送要更改的字段,不要往返传递整个 Hub 资源。运行时组写入不使用 etag。
Hub 技能
thalovant_list_hub_skills、thalovant_install_hub_skill、thalovant_update_hub_skill 和 thalovant_remove_hub_skill 会选择 Hub 所属的运行时组;所有共享该运行时组的 Hub 都会受到影响。Hub 可以在没有任何技能的情况下启动,之后逐个添加技能;更改会在大约 15 秒内实时应用到 Hub,无需重启。hubId 必须是 Hub UUID——经过身份验证的 Hub 路由不接受 slug。
thalovant_list_hub_skills 返回完整的 GET /v1/hubs/{hub_id}/skills 信封:hub_id、runtime_group_id、observed_at、source、运行时的阶段和消息,以及 data。data 为每个技能提供一行(也可能为空),包含 skill、title、marketplace_skill_id、package_name、source_type、install_source、version、version_pin、installed_version、observed_version、previous_version、latest_version、available_version、update_available、changelog、active、state、运行时的阶段、消息和上次错误,以及 last_transition_at。state 的值可以是 pending、installed、failed、removing、drifted、quarantined 或 unmanaged;更改进行中时显示为 pending。
每次写入都会以 202 返回 operation_id、hub_id、runtime_group_id、skill、version(移除时为 null)、previous_version 和 state(installing、updating 或 removing);传入 wait: true,即可每隔 2 s 轮询该操作,直到操作收敛(安装时为 installed,移除时为 removed;failed 或 timed_out 操作会引发包含其 error_message 的错误),默认 timeoutMs 为 120 s;或者使用 thalovant_get_operation 自行跟踪操作。若要安装的技能已以其他版本安装,则会执行更新;若版本相同,则会返回 409,错误代码为 skill_version_already_installed。没有运行时组的 Hub 会返回 404,错误代码为 hub_without_runtime_group(普通的 404 表示 Hub 不存在或技能未安装);无法解析的 latest 或无效版本会返回 422。错误采用 RFC 7807 问题正文;工具错误会保留简短的 message,并在括号中附上根错误代码,例如 Thalovant API request failed with HTTP 409: Skill version already installed. (skill_version_already_installed),随后附上错误代码和正文的其他字段(参见工具错误)。
列出技能需要 hubs:inspect(hubs:read 隐含此权限);写入需要 hubs:write 和付费套餐。由于先检查权限范围,再检查套餐,因此免费套餐令牌会收到 403,而不会收到 402。四个路由都会遵循 Hub 受限令牌(hub_ids 允许列表)的限制。服务器使用已发布的 Node SDK Hub 技能方法,并在轮询期间保留 MCP 取消检查。状态读取失败时会保留已接受操作的 ID;请使用该 ID 调用 thalovant_get_operation,不要再次提交写入请求。达到轮询截止时间时或之后,不会再开始新的轮询。该截止时间不会取消已经在执行中的 HTTP 请求。
登录回退
export THALOVANT_EMAIL="[email protected]"
export THALOVANT_PASSWORD="..."
export THALOVANT_PROFILE="prod"
export THALOVANT_API_URL="https://api.thalovant.com"
npm start
如果未配置令牌或电子邮件/密码,经过身份验证的控制平面工具会失败,并清楚说明支持的选项。
已配置的 API 令牌和登录凭据会绑定到其已配置的 apiUrl 或 THALOVANT_API_URL 的源站(默认为 https://api.thalovant.com)。
工具参数无法将这些凭据重定向到其他源站。同一源站上等效的 URL 写法和路径均可使用;自定义源站必须与凭据一同配置。匿名公共发现仍可选择自定义 API URL。
连接 Home Assistant
Home Assistant 这类家庭控制器会以自身类型的连接连接到集线器:
- 未配置令牌时,请登录:设备登录。
- 调用
thalovant_create_client_identity,并设置connectionType: "home_assistant"。API 必须返回相同类型;如果返回的是普通连接,则会再次删除该连接,并使调用失败。结果包含clientId、connectionType和operationId。 - 使用该
operationId调用thalovant_wait_for_admission。集线器会在约 90 秒内接纳新连接,在此之前会拒绝该连接。outcome的值为admitted、failed或timeout。平台上的失败会包含操作的errorCode(且status为 null);API 本身拒绝等待时则会包含其status、code和detail。timeout表示连接仍可能获准:请再次调用该工具,而不要创建另一个连接。遇到 429 时,等待 API 指定的时长(依次读取其响应正文、Retry-After或RateLimit-Reset);如果请求的等待时间超过剩余时长,则立即返回timeout。API 拒绝令牌(401、403)和 API 无法访问时,会分别返回各自带有提示的工具错误,绝不会作为接纳失败处理。该工具只读取数据、遵循取消操作,且绝不会跟随指向不同于 API 源站的links.self。
对于步骤 2 中的每次拒绝,都会在 API 自身的文本之后说明下一步该怎么做(参见工具错误):API 尚不认识的类型、不允许此类连接的套餐、已占用唯一 Home Assistant 链接的集线器(会提供占用链接的 client_id),或被 API 拒绝的令牌(请重新登录)。thalovant_delete_client 会删除连接(使用 If-Match;未提供时先读取 etag;遇到 412 时重试一次;若连接已不存在,也视为已删除);这是一个需要由操作员启用的破坏性工具。
之后响应集线器请求,是该集成在数据平面上的长期运行任务;MCP 工具调用只会在其自身运行期间维持集线器连接,因此这部分连接工作并不由工具承担。
本地 Stdio
此服务通过 stdio 使用 MCP 通信,且不会向 stdout 写入日志。
运行时集线器工具按以下顺序加载本地身份信息:
identityFile工具参数。configPath或profile工具参数。- Thalovant SDK 环境身份变量。
- 默认的 Thalovant SDK 配置配置文件。
请妥善保密 Thalovant 身份文件。SDK 要求配置文件受到保护,例如将 ~/.config/thalovant/config.yaml 的权限设为 0600。
Streamable HTTP
远程模式使用 MCP Streamable HTTP,端点为 /mcp,默认要求使用 bearer 身份验证。
export MCP_TRANSPORT="http"
export MCP_HTTP_HOST="127.0.0.1"
export MCP_HTTP_PORT="3000"
export MCP_HTTP_AUTH_TOKEN="$(openssl rand -hex 32)"
export MCP_HTTP_ALLOWED_HOSTS="127.0.0.1:3000,localhost:3000"
npm run start:http
客户端连接到:
http://127.0.0.1:3000/mcp
Authorization: Bearer <token>
/healthz 和 /readyz 提供健康检查。
对于公共部署,请设置公共 URL 以及精确的主机/源站允许列表:
export MCP_HTTP_HOST="0.0.0.0"
export MCP_HTTP_PORT="3000"
export MCP_PUBLIC_URL="https://mcp.example.com"
export MCP_HTTP_ALLOWED_HOSTS="mcp.example.com"
export MCP_HTTP_ALLOWED_ORIGINS="https://agent.example.com"
远程身份验证
仅在本地、私有或单租户部署中使用静态 bearer 令牌:
export MCP_HTTP_AUTH_TOKEN="$(openssl rand -hex 32)"
# or
export MCP_HTTP_AUTH_TOKENS="token-a,token-b"
在生产环境中使用 JWT/JWKS 进行资源服务器验证:
export MCP_HTTP_AUTH_MODE="jwt"
export MCP_OAUTH_ISSUER="https://auth.example.com/"
export MCP_OAUTH_JWKS_URL="https://auth.example.com/.well-known/jwks.json"
export MCP_OAUTH_AUDIENCE="https://mcp.example.com/mcp"
export MCP_OAUTH_AUTHORIZATION_SERVERS="https://auth.example.com/"
export MCP_OAUTH_REQUIRED_SCOPES="mcp:thalovant"
如果授权服务器颁发不透明令牌,请使用内省:
export MCP_HTTP_AUTH_MODE="introspection"
export MCP_OAUTH_INTROSPECTION_URL="https://auth.example.com/oauth2/introspect"
export MCP_OAUTH_CLIENT_ID="mcp-server-client"
export MCP_OAUTH_CLIENT_SECRET="..."
export MCP_OAUTH_AUDIENCE="https://mcp.example.com/mcp"
export MCP_OAUTH_AUTHORIZATION_SERVERS="https://auth.example.com/"
export MCP_OAUTH_REQUIRED_SCOPES="mcp:thalovant"
此服务会在以下位置发布受保护资源元数据:
https://mcp.example.com/.well-known/oauth-protected-resource
对于支持 OAuth 发现的 MCP 客户端,401 响应会包含带有 resource_metadata 指针的 WWW-Authenticate。
主体凭据
对于多用户远程部署,不要让所有 MCP 用户共用一个 Thalovant 访问令牌。应将每个经过身份验证的 MCP 主体映射到各自的 Thalovant 控制平面令牌、运行时身份和工具策略。
单文件模式:
export THALOVANT_PRINCIPAL_CREDENTIALS_FILE="/run/secrets/thalovant-principals.json"
目录模式:
export THALOVANT_PRINCIPAL_CREDENTIALS_DIR="/run/secrets/thalovant-principals"
目录中的文件名为 <sha256(principal-id)>.json。服务会检查 OAuth 主体、主体 ID 和客户端 ID。请参阅 examples/principal-credentials.sample.json。
对于多用户部署,请保持禁用此项;除非你有意让每个远程主体都使用服务环境中的 Thalovant 凭据:
export THALOVANT_ALLOW_SHARED_CREDENTIALS="false"
默认情况下,会为远程主体禁用运行时 identityFile、configPath、profile 和 fromEnv 工具参数。仅在可信的私有部署中设置 MCP_HTTP_ALLOW_CLIENT_CREDENTIAL_PATHS=true。
策略、审计与可恢复性
全局工具策略:
export MCP_TOOL_ALLOWLIST="thalovant_*"
export MCP_TOOL_DENYLIST="thalovant_delete_memory_item"
每个主体的凭据文件也可以包含 allowedTools 和 deniedTools。
这两项都是调用时过滤器,且空的允许列表表示“允许所有内容”。它们无法将工具设为默认关闭,也无法让工具从 tools/list 中隐藏,因此这两个具有破坏性的控制平面工具会通过 THALOVANT_ENABLE_DESTRUCTIVE_TOOLS 单独进行门控。请参阅破坏性工具。
审计日志:
export MCP_AUDIT_LOG="stderr" # off, stderr, file, or both
export MCP_AUDIT_LOG_FILE="/var/log/thalovant-mcp/audit.jsonl"
export MCP_AUDIT_INCLUDE_ARGS="false"
审计条目采用 JSONL 格式,类似凭据的字段会被脱敏。
Streamable HTTP 的可恢复性默认使用内存事件存储。若需支持单实例重启,请使用文件存储:
export MCP_EVENT_STORE_FILE="/var/lib/thalovant-mcp/events.jsonl"
HTTP 加固
- 除非明确设置
MCP_HTTP_ALLOW_UNAUTHENTICATED=true,否则必须进行 Bearer 身份验证。 - 对 Host 标头进行允许列表控制,以降低 DNS 重绑定风险。
- 除非浏览器的
Origin标头与MCP_HTTP_ALLOWED_ORIGINS完全匹配,否则将予以拒绝。 - CORS 仅公开 MCP 会话/协议标头。
- 会话使用加密安全的随机 ID,并绑定到经过身份验证的主体。
- 请求正文大小受
MCP_HTTP_MAX_BODY_BYTES限制,默认值为 1 MiB。 - 固定窗口速率限制默认设置为每个客户端地址每分钟 120 个 MCP 请求。
- 安全标头包括
nosniff、DENY框架限制、不发送 referrer,以及限制性 CSP。
常用 HTTP 环境变量:
MCP_HTTP_PATH=/mcp
MCP_HTTP_RATE_LIMIT_MAX=120
MCP_HTTP_RATE_LIMIT_WINDOW_MS=60000
MCP_HTTP_SESSION_TTL_MS=3600000
MCP_HTTP_MAX_BODY_BYTES=1048576
MCP_HTTP_ENABLE_JSON_RESPONSE=false
MCP_HTTP_TRUST_PROXY=false
Claude Desktop
建议:使用范围受限的 API 令牌进行身份验证,这样 MCP 配置中就不会包含你的账户密码。
{
"mcpServers": {
"thalovant": {
"command": "npx",
"args": ["-y", "@thalovant/mcp-server"],
"env": {
"THALOVANT_API_TOKEN": "tvpat_...",
"THALOVANT_PROFILE": "prod"
}
}
}
}
Codex
在 MCP 客户端配置中使用相同的 stdio 命令:
{
"mcpServers": {
"thalovant": {
"command": "npx",
"args": ["-y", "@thalovant/mcp-server"],
"env": {
"THALOVANT_API_TOKEN": "tvpat_...",
"THALOVANT_PROFILE": "prod"
}
}
}
}
工具
只读:
thalovant_config_statusthalovant_list_public_hubsthalovant_get_public_hubthalovant_list_hubsthalovant_get_hubthalovant_get_operationthalovant_wait_for_admissionthalovant_identity_statusthalovant_healthcheckthalovant_intent_inventorythalovant_wait_for_eventthalovant_get_analytics_overviewthalovant_list_memory_itemsthalovant_get_memory_summarythalovant_get_memory_item
技能和运行时组发现(只读):
thalovant_list_marketplace_skillsthalovant_list_runtime_group_marketplacethalovant_list_runtime_group_inventorythalovant_list_runtime_groupsthalovant_get_runtime_groupthalovant_get_runtime_group_configthalovant_get_hub_runtime_capabilities
登录(请参阅设备登录):
thalovant_begin_device_loginthalovant_poll_device_loginthalovant_revoke_device_login
写入或中心事件:
thalovant_create_client_identitythalovant_askthalovant_querythalovant_send_actionthalovant_send_codethalovant_emit_eventthalovant_create_memory_itemthalovant_update_memory_itemthalovant_delete_memory_item
中心和运行时组配置:
thalovant_create_hubthalovant_update_hubthalovant_release_hubthalovant_set_hub_ratingthalovant_clear_hub_ratingthalovant_create_runtime_groupthalovant_update_runtime_groupthalovant_update_runtime_group_configthalovant_release_runtime_groupthalovant_install_runtime_group_skillthalovant_uninstall_runtime_group_skill
Hub 技能,作用于 Hub 的共享运行时(参见 Hub 技能;列表工具为只读):
thalovant_list_hub_skillsthalovant_list_hub_skill_historythalovant_install_hub_skillthalovant_update_hub_skillthalovant_remove_hub_skill
破坏性操作,除非明确启用,否则不会注册(参见 破坏性工具):
thalovant_delete_hubthalovant_delete_runtime_groupthalovant_delete_client
工具输出会隐藏看起来像凭据的字段。thalovant_create_client_identity 不会返回身份密钥材料;如果你希望将完整身份写入权限模式为 0600 的本地文件,请传入 savePath。savePath 被限制在服务端的身份目录(THALOVANT_MCP_IDENTITY_DIR,默认值为 <config-dir>/thalovant/identities)中:请传入纯文件名,因为系统会拒绝该目录之外的绝对路径和 .. 路径遍历,防止模型将凭据文件放入 git 工作树或同步文件夹。thalovant_config_status 会报告当前生效的 identityDir。
thalovant_intent_inventory 使用运行时身份,并接受 languages、
describe、fallback、speakable、sentence、slots、exampleLimit 和按单次查询/批处理设置的 timeoutMs。它会按请求的语言返回已注册
的意图和示例、回退技能、fallbacks_known、listed_in 和
may_answer。listed_in 指明每种请求语言所对应的 Hub 语言。Hub 不会列出其未加载语言下的内容,因此,没有句子的语言会以其通常形式列出(在 en-US 中为 en-CA),或以 Hub 加载的最接近语言列出;examples 也会以该语言呈现。如果 listed_in 与请求的语言不同,说明句子使用的是另一种语言,且 presentation.notes 会说明这一点。回退技能来自 ovos.skills.list,按技能 ID 排序,且 priority: null:Hub 不会说明它按什么顺序尝试这些技能。若回退技能查询缺失或被拒绝,结果仍为未知,而不会报告为已知的空列表。可选探测最多增加 1500ms。静默列表可以使用引擎清单;将此功能设为禁用:fallback: false。这两个新工具均可在只读模式下使用,并遵循每个主体的策略。thalovant_get_operation 可读取配置操作返回的操作 ID,而不会重放写入操作。
新增的 presentation 对象包含共享的 SDK 清单结构:cache_version、hub_id、hub_name、source、generated_at、skills、notes 和 languages_present。技能标题由 ID 派生。运行时发现无法证实目录区域设置或 Hub 显示元数据,因此这些字段仍为未知值(空列表/字符串),并附有说明性注释。意图语言顺序明确指定,且不会因 JSON 键排序而改变。每次工具调用都会保留自己的身份租约;服务端不会持久化清单,也不会在调用方之间共享会话。
工具错误
当 Thalovant API 拒绝控制平面调用时,工具结果会返回一条错误,其文本以 SDK 的单行消息开头(其中会指出 HTTP 状态码,也可能缩短消息),然后完整说明 API 返回的内容:
Thalovant API request failed with HTTP 403: Only an administrator can run an image the platform does not release: bus may be one of ghcr.io/thalovant/ovos-messagebus:2026.09.2, ... (platform_image_required)
code: platform_image_required
detail: Only an administrator can run an image the platform does not release: bus may be one of ghcr.io/thalovant/ovos-messagebus:2026.09.2, ghcr.io/thalovant/ovos-messagebus:2026.09.3-alpha.1, ghcr.io/thalovant/ovos-messagebus:2026.08.7; core may be any tag or digest of ghcr.io/thalovant/ovos-core.
fields: {"allowed_images":{"bus":[...],"core":[...]},"allowed_repositories":{"core":"ghcr.io/thalovant/ovos-core"},"component":"runtime_group","refused_images":{...}}
code是 API 提供的机器可读代码(如果有)。detail是完整句子,仅当第一行不得不缩短时才会出现。fields是错误正文中的所有其他成员,以紧凑 JSON 格式呈现(不包括 Problem+JSON 的type、title、status和instance),并采用与其他工具输出相同的密钥脱敏规则。验证错误从请求中回显的值——即detail或errors列表中每个条目的input,无论其键或形状如何——都会被替换为"[omitted]",且绝不会出现在第一行中。计划拒绝会在此处携带resource、limit、used和plan。
对于需要提示的状态码,后面可能会附带提示。platform_image_required 或 plan_limit 403 错误会各自附带专用提示,而不是通用范围提示。
请求提示、嵌入式音频与配置合并
thalovant_ask 接受 sttLang、有序的 pipeline,以及包含必填 city 和可选 region、country、timezone、latitude、longitude 的 location。提示仅适用于当前请求。省略未使用的提示;空的 pipeline 会被忽略,空白的语言或城市字符串会被拒绝。
Ask 和 Query 会返回语言、有序事件元数据、hasAudio 和 droppedMedia。十六进制嵌入内容不会出现在文本输出中。设置 includeAudio: true 可选择接收单独的 MCP 音频块;未知格式会变成嵌入式二进制资源块。片段和回复的大小上限分别为 4 MiB 和 16 MiB,并由 SDK 在保留前进行检查。播放由客户端负责。不会获取技能提供的任何路径或 URL。清单中的 speakable: true 会生成示例,但不会更改原始模式;slots 提供示例槽位值,exampleLimit 将每种语言的示例数量限制为 1–20 个(默认为 2 个)。
配置更新默认使用 merge: true:获取修订版本,对调用方的增量进行深度合并,然后使用 expected_revision 执行 PUT。仅 HTTP 412 会重试,重试时会重新读取,最多总共尝试三次。这需要 hubs:read、hubs:write 和付费计划。不支持修订版本的旧版 API 会在写入前失败。没有无条件回退机制。提供的角色设定会被替换;省略的角色设定保持不变。如需有意进行完整替换,请传入 merge: false,这需要 hubs:write、付费计划,并与其他写入者协调。
受保护的合并会在写入前拒绝增量或已存储配置中超出 JavaScript 安全整数范围的整数。较大的标识符应存储为字符串,或使用能够保留较大 JSON 整数的 SDK。
破坏性工具
thalovant_delete_hub、thalovant_delete_runtime_group 和 thalovant_delete_client 默认处于禁用状态。调用时它们并非只是被拦截,而是根本不会注册,因此不会出现在 tools/list 中,模型也无法看到或尝试使用它们。
长期有效的控制平面令牌与始终可用的删除工具相结合,带来的风险与读取或更新工具截然不同:删除枢纽还会删除其关联的客户端和 ACL,而且这些操作都不可撤销。因此,这些工具需要主动启用:
export THALOVANT_ENABLE_DESTRUCTIVE_TOOLS="true"
接受的真值为 1、true、yes 和 on;其他任何值(包括未设置)都会让这些工具保持关闭状态。服务器实例创建时会读取此标志。更改后,请使用更新后的环境变量重启服务器进程。thalovant_config_status 会通过 destructiveToolsEnabled 报告当前状态,并列出此标志控制的工具。
这是与现有工具策略刻意分开的机制。MCP_TOOL_ALLOWLIST / MCP_TOOL_DENYLIST 和每个主体的 allowedTools / deniedTools 是调用时过滤器;空的允许列表表示“允许所有工具”。它们无法表达“某个工具在操作员启用前一直关闭”,也无法将工具从 tools/list 中隐藏。设置 THALOVANT_ENABLE_DESTRUCTIVE_TOOLS 后,删除工具就会恢复为普通工具,并继续受该策略约束,因此两层机制可以叠加使用:
# Register delete tools, then deny their use by every principal.
export THALOVANT_ENABLE_DESTRUCTIVE_TOOLS="true"
export MCP_TOOL_DENYLIST="thalovant_delete_hub,thalovant_delete_runtime_group"
全局拒绝规则适用于每个主体,且无法被主体的 allowedTools 覆盖。若只想限制选定主体,请勿将这些工具加入全局拒绝列表,而应改用这些主体的 deniedTools。
删除枢纽仍需要提供当前 etag(否则会返回 412);当运行时组是工作区默认组或仍关联有枢纽时,删除操作会失败并返回 409。删除客户端会切断正在使用它的设备或链接;如果未提供 etag,则会先读取其 etag。
非目录技能来源
thalovant_install_runtime_group_skill 默认从经过审核的市场目录安装。其他任何来源——尤其是通过 sourceType: "git" 配合任意 sourceRef 仓库 URL 指定的来源——都会将市场从未审核过的代码直接拉取到生产运行时中,而且控制平面验证器只检查格式,不设主机允许列表。由于这些工具由持有长期有效令牌的模型驱动,除非操作员主动启用,否则会拒绝非目录来源:
export THALOVANT_ENABLE_GIT_SKILL_SOURCES="true"
未设置此标志时,任何 sourceType 不是 catalog 的调用都会在发出控制平面请求前失败。接受的真值为 1、true、yes 和 on。thalovant_config_status 会通过 gitSkillSourcesEnabled 报告当前状态。此工具标注为 destructiveHint: true。
只读模式
设置 THALOVANT_MCP_READONLY=1 后,只会注册标注为 readOnlyHint: true 的工具(登录工具不在其中;thalovant_wait_for_admission 则在其中)。写入和破坏性工具将不会注册,也不会出现在 tools/list 中,因此操作员无需手动编写拒绝列表,就能运行仅用于观察的 Agent。与其他注册时门控一样,此设置会在服务器实例创建时读取;thalovant_config_status 会通过 readOnly 报告当前状态。
HiveMind Runtime 兼容性
共享同一 hub 客户端身份的 Runtime 调用会在单个 MCP 进程中依次运行。为每个独立运行的 MCP 服务使用不同的客户端身份,以便 hub 将它们的会话分开。
版本 0.6.6 要求 @thalovant/sdk ^0.9.9(0.9.9 至低于 0.10.0 的版本)。从 0.5.1 起,服务会强制使用
安全的有效 MQTT URL,并在 MQTT 设置和 HTTP 失败清理期间沿用同一个连接截止时间。
Runtime 工具支持通过 WSS 使用 HiveMind v3 Noise、HTTPS,以及通过 TLS 使用 MQTT。thalovant_healthcheck
仅在身份验证完成后报告就绪;仅能访问 hub 或 broker 并不代表已建立 Runtime 会话。
Zod 4 安全迁移保留了 50 个默认工具和以字符串为键的记录值。其 JSON Schema 输出会内联重复记录,标明字符串属性名称,并在剥离对象中省略 additionalProperties: false;在处理程序接收输入前,仍会剥离未知输入键。UUID 验证现在会强制检查标准版本和变体位(以及 nil/max UUID),内存列表偏移量必须是安全整数。有关证据和发布门槛,请参阅安全审计。
请在服务重启期间保持 SDK 配置目录持久且私密(~/.config/thalovant,或配置的 XDG/Windows 等效目录)。其中包含客户端 Noise 密钥和受信任的服务端固定值。身份验证失败时会保留这些固定值;更换服务端密钥需要明确且经过验证的信任变更。HTTPS 身份必须声明 hub 的 HTTPS 插件,MQTT 则需要该身份的 broker 凭据和主题前缀。
Runtime 工具会一直保留其身份租约,直到实际清理完成。如果调用方等待关闭操作超时,后续工具会在打开会话前最多等待六秒,以完成该清理。 如果排队的工具达到此截止时间,则会失败,不会稍后执行,也不会释放先前会话的身份。 实际清理失败时,会将该身份标记为不可供后续调用使用,而不是冒险并发运行会话。这些租约仅限进程内有效;不同的服务进程或副本需要使用不同的 Runtime 身份或进行外部协调。
MCP 请求取消功能适用于 stdio 和 Streamable HTTP 模式下排队的 Runtime 工具。已取消的排队调用不会创建 Runtime 客户端,也不会稍后执行。取消操作也会传递到 Runtime 连接设置、Ask、Query 和事件等待过程。Action/code 发送、原始事件发布和清单查询会在连接设置期间检查取消状态,然后持续持有操作权,直到已准入的 SDK 操作完成。取消 MCP 请求无法撤销已准入的操作或其影响。身份会在该操作和实际清理完成前保持预留;应用程序请求绝不会自动重放。本版本不会为控制平面工具新增 Runtime 取消语义。
例如,MCP TypeScript 客户端可以在十秒后取消 Runtime 查询,其中包括等待身份租约所花的时间:
await mcpClient.callTool({
name: "thalovant_query",
arguments: { identityFile: "/secure/identity.json", text: "What is the weather?", timeoutMs: 30000 },
}, undefined, { signal: AbortSignal.timeout(10000) });
意图清单会保留连接设置预算以及每次查询/批次预算,并提供单独的可选回退探测;它没有覆盖整个清单的统一截止时间。
开发
npm run typecheck
npm test
npm run build
npm run test:smoke
npm run test:http
npm run bench
npm run bench:http
npm pack --dry-run
许可证
MIT。这是公共集成服务的理想默认选项:它采用宽松许可,与 MIT Thalovant Node SDK 和 MCP TypeScript SDK 兼容,也不会强制下游 Agent 或企业用户采用互惠许可模式。
携带凭据的控制平面调用必须使用 HTTPS。显式的环回 HTTP(localhost、127.0.0.1、[::1])仍受支持,可用于本地开发。
API 重定向会被拒绝,以免转发密码登录请求正文。
只有在获取身份租约后,才会构建运行时客户端。
thalovant_query 会发送路由到 HiveMind 的查询;中枢可能会根据其路由策略级联处理。它接受 text、timeoutMs、lang、sessionId、requestId、queryId、context 和 replySettleMs,以及运行时身份选项,并返回与 thalovant_ask 相同的规范化回复格式。查询可能触发操作,因此只读模式会隐藏此工具。对话工作流使用 sessionId 配合 ask/query 和现有的事件等待工具;MCP 不会为每种 SDK 对话或事件监听器方法都提供一个工具。
共享运行时技能管理
目录默认包含 50 个工具,只读模式下有 24 个,启用破坏性工具后有 53 个。
面向中枢的技能方法会选择关联到中枢 UUID 的运行时组。共享该组的所有中枢都会看到相同的技能变更和历史记录。API 要求受限令牌涵盖所有已提供服务的中枢。读取需要 hubs:inspect(hubs:read 也可满足要求);写入需要 hubs:write、符合条件的付费方案和所有权。
历史记录响应包含按时间从新到旧排列的 event 和 operation 条目,其中操作者和版本字段可能为 null。条目数限制为 1–200(省略时为 50)。
变更被接受并不代表技能已就绪。可选的等待功能会轮询操作,默认超时时间为 120 秒,轮询间隔为两秒。轮询不会重复已接受的变更,也不会在截止时间后启动新的读取;已在运行的 HTTP 请求仍保留其正常请求超时时间。
使用 thalovant_list_hub_skill_history(hubId,可选的 limit)读取历史记录。此工具在只读模式下仍可用。
库存中的 sentence: true 表示采用适合语音播报的呈现方式,并依据捆绑的 thalovant-languages 0.2.1 规则为示例添加大写和标点。区域语言环境匹配遵循 OVOS 距离;显式 slots 会覆盖语言环境示例值。完整短语优先排序,exampleLimit 统计不重复的非空呈现结果。
响应中仍包含原始意图定义;未知语言环境会保留纯文本。
CLI 在 stdio 和 HTTP 模式下都会处理 SIGTERM 和 SIGINT,包括作为容器 PID 1 运行时。CLI 会在正常退出前关闭会话和 HTTP 连接;如果清理过程卡住,则会在十秒后失败退出。
版本 0.5.1 使用 Node SDK 0.7.1,提供与 Python 0.7.4 兼容的库存和疑问检测功能,包括 Unicode 问号和省略语言的模式。启用 sentence: true 时,西班牙语疑问句会添加问号,完整法语短语会保留句末句号。未描述的语言会保留纯文本。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。