关于 mcp-server-smartsheet-rm
面向使用 Smartsheet Resource Management 的团队,通过其公共 REST API 管理工时、人员安排、项目和管理数据。领域与任务配置可限定 Agent 可用的工具,并提供只读及破坏性操作控制。
主要功能
- 01管理工时记录和审批
- 02创建项目、阶段和分配
- 03查看资源可用性与利用率
- 04维护用户、费用和自定义字段
- 05选择领域或任务专用配置
- 06限制只读和批量破坏性操作
适用场景
- 01核对并提交每周工时表
- 02检查资源容量并调整分配
- 03设置项目、阶段和客户记录
- 04将 Agent 限定为只读操作
MCP 相关
将 Smartsheet Resource Management 操作作为带命名空间的 MCP 工具、提示词和资源提供。支持 stdio 与 Streamable HTTP,并可配置只读访问和破坏性操作限制。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx mcp-server-smartsheet-rmSMARTSHEET_RM_API_TOKEN密钥Your Smartsheet Resource Management (10,000ft) API tokenSMARTSHEET_RM_BASE_URLAPI base URL. Host must be in SMARTSHEET_RM_ALLOWED_HOSTS (default api.rm.smartsheet.com).SMARTSHEET_RM_GOV_SMARTSHEET_API_TOKEN密钥Smartsheet Gov only: Smartsheet API token sent as Authorization: Bearer to app.smartsheetgov.com.SMARTSHEET_RM_ALLOWED_HOSTSComma-separated hostnames allowed for base URL overrides. A non-blank value replaces the default (api.rm.smartsheet.com).本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
📋 mcp-server-smartsheet-rm
面向企业的 Model Context Protocol(MCP)服务,用于 Resource Management by Smartsheet(10,000ft API)。
让 AI 编码 Agent、规划人员和助手(Claude、Cortex、Antigravity、VS Code)能够使用 Smartsheet RM 公共 REST API:时间跟踪与工时表核对、资源排期与分配、产能规划、项目与阶段管理、休假/节假日、费用跟踪以及自定义字段。
🏗️ 系统架构
graph TD
Client["AI Agent (Claude / Cortex / Antigravity / Cursor)"] -->|"MCP Stdio / Streamable HTTP /mcp"| Server["Root Gateway create_server()"]
Server --> Middle["Parent Middleware (ParentAudit / ReadOnly Gate)"]
Middle --> SubTime["time namespace (time_* — 17 tools, incl. 1 bulk-gated)"]
Middle --> SubProj["projects namespace (projects_* — 27 tools, incl. 1 bulk-gated)"]
Middle --> SubAdmin["admin namespace (admin_* — 60 tools)"]
SubTime --> Guards["Domain Guards"]
SubProj --> Guards
SubAdmin --> Guards
Guards --> ClientPool["SmartsheetRMClient (httpx.AsyncClient Pool)"]
ClientPool -->|"auth header + 429 Jitter Retry"| API["Smartsheet RM (10,000ft API)"]
create_server 使用 FastMCP 4 的 namespace= 挂载时间、项目和管理子服务,因此 tools/list 中的名称为 time_*、projects_* 和 admin_*。网关未注册旧版 rm_* 名称。
🚀 FastMCP 4 服务组合
- 领域挂载(
root.mount(..., namespace=...)):namespace="time"→time_*(17 个工具,包括受批量操作门控的time_bulk_delete_time_entries)。namespace="projects"→projects_*(27 个工具,包括受批量操作门控的projects_bulk_delete_assignments)。namespace="admin"→admin_*(60 个工具)。
- 分层中间件:
- 父级:
ParentAuditMiddleware(计时、生命周期日志、机密信息脱敏)和ReadOnlyGateMiddleware(基于注解的只读门控,见下文)。 - 子级:
TimeDomainGuardMiddleware(记录的工时必须为 0–24;批量操作门控)、ProjectsDomainGuardMiddleware(项目名称不能为空;批量操作门控)、AdminDomainGuardMiddleware(per_page必须 ≤ 1000)。
- 父级:
配置文件
使用 --profile 或 SMARTSHEET_RM_PROFILE 选择配置文件(默认为 full)。未知的配置文件名称会在启动时触发 ValueError。配置文件分为两类:
- 领域挂载配置文件会挂载整个领域:
full、time、projects、admin和readonly。 - 工作配置文件会挂载所有领域,然后仅开放某项工作明确列出的工具名称。所有工作配置文件和
readonly都提供提示词和资源;领域挂载配置文件time、projects和admin则仅提供各自领域的提示词和资源。服务器构建时会根据完整目录检查每个列出的名称,因此拼写错误会导致启动失败。
| 配置文件 | 服务的工作 | 工具数 | 使用 SMARTSHEET_RM_READONLY=1 时 |
|---|---|---|---|
full | 完整目录,不省略任何内容。批量工具也会列出,但除非设置 SMARTSHEET_RM_ALLOW_BULK_DESTRUCTIVE=1,否则调用时会拒绝。工具搜索和代码模式仅在此配置文件中启用。 | 104 | 39 |
time | 时间跟踪、审批和工时表配方(时间领域)。 | 17 | 4 |
projects | 项目、阶段、分配、占位项和子任务(项目领域)。 | 27 | 10 |
admin | 用户、组织参考数据、客户、费用、字段、报告和 Webhook(管理领域)。 | 60 | 25 |
readonly | 仅供查看,无副作用:所有标注了 readOnlyHint=True 的工具。 | 39 | 39 |
timesheets | 团队成员或经理根据其分配记录、更正、提交、锁定和审批每周工时。 | 24 | 12 |
staffing | 资源经理检查可用性和利用率,并创建或调整分配、占位项和子任务。 | 27 | 18 |
org_setup | 资源管理管理员负责人员入职,并维护组织参考数据、自定义字段定义、用户状态和 Webhook。 | 35 | 13 |
portfolio | PMO 设置和维护项目、阶段、客户、费用及项目元数据,并读取预算和报告总计。 | 33 | 18 |
有 7 个工具不属于任何工作配置文件,只能通过 full(或对应的领域挂载配置文件)访问:time_bulk_delete_time_entries、projects_bulk_delete_assignments、admin_delete_client、admin_delete_client_contact、admin_create_expense_category、admin_delete_expense_category 和 admin_delete_tag。
只读行为
- MCP 的
readOnlyHint注解是判断工具是否为只读工具的唯一依据。每个工具都会显式声明该注解:39 个读取工具为true,65 个写入工具为false。没有注解或没有readOnlyHint的工具均视为写入工具。 - 使用
--profile readonly或设置SMARTSHEET_RM_READONLY=1(适用于任何配置文件)时,列表中仅包含只读工具;ReadOnlyGateMiddleware会拒绝对任何非只读的实际工具的调用,包括被筛选器隐藏的写入工具。拒绝调用会以工具结果的形式返回,并带有isError: true。 - 如果某个名称不是服务器上的工具,FastMCP 会按常规返回
Unknown tool错误,无论是直接调用还是通过call_tool调用。因此,拼写错误不会被报告为已拦截的工具。 - 启用工具搜索后,门控会检查
call_tool包装的工具。通过call_tool读取可以正常执行,写入则会被拒绝。未启用工具搜索时,call_tool不是服务器上的工具,因此调用它会得到Unknown tool: 'call_tool'。 - 如果门控无法看到提供服务的服务器,就会拒绝调用。
批量操作门控
time_bulk_delete_time_entries 和 projects_bulk_delete_assignments 会列在 full、time 和 projects 中。除非设置 SMARTSHEET_RM_ALLOW_BULK_DESTRUCTIVE=1,否则领域保护措施会在调用时拒绝这些工具(isError: true),且处理程序仍要求设置 confirm=True。只读模式会隐藏并拒绝这些工具。
工具搜索与代码模式
默认情况下,tools/list 是扁平列表。发现功能默认关闭,只有在 full 配置下才会启用:
--enable-tool-search/SMARTSHEET_RM_ENABLE_TOOL_SEARCH=1会将tools/list替换为search_tools和call_tool。后端为regex(默认)或bm25(--tool-search-backend/SMARTSHEET_RM_TOOL_SEARCH_BACKEND)。--enable-code-mode/SMARTSHEET_RM_ENABLE_CODE_MODE=1会启用 FastMCP 的实验性代码模式(search、get_schema、execute)。代码模式需要使用软件包的code-mode扩展提供沙箱(fastmcp[code-mode],其中包含pydantic-monty):pip install "mcp-server-smartsheet-rm[code-mode]"或uvx --from "mcp-server-smartsheet-rm[code-mode]" smartsheet-rm-mcp --enable-code-mode。如果未安装,代码模式将跳过并发出警告,同时提供扁平目录。- 同时启用两者会引发
ValueError。在其他配置下启用任一功能会记录警告,并保留扁平列表。 search_tools、search和get_schema仅读取目录,并标注为readOnlyHint=True。在只读模式下,代码模式的execute会被拒绝。
⚡ 工具概览
该服务提供涵盖项目、资源、工时表和容量的工具。请调用以下命名空间名称:
- 默认注册:
full配置下有 104 个工具(2 个批量破坏性工具会列出,但调用时会被拒绝,除非设置SMARTSHEET_RM_ALLOW_BULK_DESTRUCTIVE=1)。 - 只读模式:39 个工具(
readOnlyHint=true)。 - 破坏性操作门控:21 个工具需要显式设置
confirm=True(19 个标准工具 + 2 个批量工具)。 - 幂等操作:43 个工具带有
idempotentHint=true(39 个只读工具,以及time_update_time_approval_status、time_lock_timesheet、admin_set_custom_field_values和admin_set_user_status)。
领域概览
Agent 会调用这些 tools/list 名称。时间和项目的数量包含受批量操作门控的工具。
- 时间(
time_*,17 个工具):time_list_time_entries、time_get_time_entry、time_create_time_entry、time_create_user_time_entry、time_create_project_time_entry、time_update_time_entry、time_delete_time_entry、time_list_user_suggestions、time_update_time_approval_status、time_lock_timesheet、time_fill_weekly_timesheet、time_confirm_suggested_hours、time_reconcile_and_submit_week、time_list_approvals、time_create_approval、time_delete_approval。受批量操作门控:time_bulk_delete_time_entries。 - 项目(
projects_*,27 个工具):projects_list_projects、projects_get_project、projects_create_project、projects_update_project、projects_delete_project、projects_list_project_users、projects_list_project_phases、projects_get_project_phase、projects_create_project_phase、projects_update_project_phase、projects_delete_project_phase、projects_list_assignments、projects_get_assignment、projects_create_assignment、projects_create_project_assignment、projects_create_user_assignment、projects_update_assignment、projects_delete_assignment、projects_clone_project_schedule、projects_list_status_options、projects_list_placeholder_resources、projects_create_placeholder_resource、projects_delete_placeholder_resource、projects_list_assignment_subtasks、projects_create_assignment_subtask、projects_delete_assignment_subtask。受批量操作门控:projects_bulk_delete_assignments。 - 管理(
admin_*,60 个工具):- 用户、角色、专业领域和容量:
admin_list_users、admin_get_user、admin_create_user、admin_update_user、admin_delete_user、admin_list_user_bill_rates、admin_create_user_bill_rate、admin_get_user_availability、admin_get_user_utilization、admin_list_roles、admin_create_role、admin_update_role、admin_delete_role、admin_list_disciplines、admin_create_discipline、admin_update_discipline、admin_delete_discipline。 - 客户和联系人:
admin_list_clients、admin_get_client、admin_create_client、admin_update_client、admin_delete_client、admin_list_client_contacts、admin_create_client_contact、admin_delete_client_contact。 - 休假和节假日:
admin_list_leave_types、admin_get_leave_type、admin_create_leave_type、admin_update_leave_type、admin_delete_leave_type、admin_list_holidays、admin_get_holiday、admin_create_holiday、admin_update_holiday、admin_delete_holiday。 - 费用:
admin_list_expenses、admin_get_expense、admin_create_expense、admin_update_expense、admin_delete_expense、admin_list_expense_categories、admin_create_expense_category、admin_delete_expense_category。 - 标签和自定义字段:
admin_list_tags、admin_create_tag、admin_delete_tag、admin_list_custom_fields、admin_get_custom_field、admin_create_custom_field、admin_update_custom_field、admin_delete_custom_field、admin_list_custom_field_values、admin_set_custom_field_values。 - 状态、报告和 Webhook:
admin_get_user_statuses、admin_set_user_status、admin_get_report_rows、admin_get_report_totals、admin_list_webhooks、admin_create_webhook、admin_delete_webhook。
- 用户、角色、专业领域和容量:
未记录的路由
以下工具调用的路由既不在 Smartsheet 的 资源管理 API 参考(OpenAPI JSON)中,也不在已归档的 10,000ft API 文档中。这类方法与路径组合共有 46 个。保留这些组合且不更改其指向,是因为部分有文档记录的等效路由采用不同的请求格式,因此迁移工具会改变它发送的内容。Smartsheet 可能会在不另行通知的情况下更改或移除未公开文档的路由,每个此类工具的描述中都说明了这一点。如果有合适的工具,请优先使用有文档记录的路由:例如,使用 time_create_user_time_entry 或 time_create_project_time_entry,而不是 time_create_time_entry。这些客户端调用均带有 # drift-ignore: undocumented route,而 scripts/check_openapi_drift.py 会在发现任何其他不属于已发布规范的调用时失败。
| 工具 | 未记录的路由 | 有文档的对应项 |
|---|---|---|
time_create_time_entry | POST /time_entries | POST /users/{user_id}/time_entries(time_create_user_time_entry)和 POST /projects/{project_id}/time_entries(time_create_project_time_entry)。 |
time_update_time_entry | PUT /time_entries/{id} | PUT /users/{user_id}/time_entries/{id}。 |
time_delete_time_entry | DELETE /time_entries/{id} | DELETE /users/{user_id}/time_entries/{id}。 |
time_update_time_approval_status | PUT /users/{user_id}/time_entries/approval_status | 未找到。 |
time_lock_timesheet | POST /users/{user_id}/time_entries/lock | 未找到。 |
time_fill_weekly_timesheet | POST /time_entries | POST /users/{user_id}/time_entries。 |
time_confirm_suggested_hours | PUT /time_entries/{id} | PUT /users/{user_id}/time_entries/{id}。 |
time_reconcile_and_submit_week | PUT /users/{user_id}/time_entries/approval_status | 未找到(仅在 auto_submit=True 时调用)。 |
time_bulk_delete_time_entries | DELETE /time_entries/{id} | DELETE /users/{user_id}/time_entries/{id}。 |
projects_get_project_phase | GET /projects/{project_id}/phases/{phase_id} | 参考文档仅记录了该路径上的 PUT 和 DELETE;GET /projects/{project_id}/phases 用于列出阶段。 |
admin_list_user_bill_rates | GET /users/{user_id}/bill_rates | GET /bill_rates 和 GET /projects/{project_id}/bill_rates。 |
admin_create_user_bill_rate | POST /users/{user_id}/bill_rates | 参考文档仅在 /bill_rates 和 /projects/{project_id}/bill_rates 下记录了账单费率,且不包含创建操作。 |
admin_get_user_availability | GET /users/{user_id}/availability | GET /users/{user_id}/availabilities。 |
admin_get_user_utilization | GET /users/{user_id}/utilization | 未找到。 |
admin_create_role | POST /roles | 参考文档仅记录了角色的 GET 操作。 |
admin_update_role | PUT /roles/{id} | 参考文档仅记录了角色的 GET 操作。 |
admin_delete_role | DELETE /roles/{id} | 参考文档仅记录了角色的 GET 操作。 |
admin_create_discipline | POST /disciplines | 参考文档仅记录了专业领域的 GET 操作。 |
admin_update_discipline | PUT /disciplines/{id} | 参考文档仅记录了专业领域的 GET 操作。 |
admin_delete_discipline | DELETE /disciplines/{id} | 参考文档仅记录了专业领域的 GET 操作。 |
admin_list_clients | GET /clients | 未找到。 |
admin_get_client | GET /clients/{id} | 未找到。 |
admin_create_client | POST /clients | 未找到。 |
admin_update_client | PUT /clients/{id} | 未找到。 |
admin_delete_client | DELETE /clients/{id} | 未找到。 |
admin_list_client_contacts | GET /clients/{id}/contacts | 未找到。 |
admin_create_client_contact | POST /clients/{id}/contacts | 未找到。 |
admin_delete_client_contact | DELETE /clients/{id}/contacts/{contact_id} | 未找到。 |
admin_create_leave_type | POST /leave_types | 参考文档仅记录了休假类型的 GET 操作。 |
admin_update_leave_type | PUT /leave_types/{id} | 参考文档仅记录了休假类型的 GET 操作。 |
admin_delete_leave_type | DELETE /leave_types/{id} | 参考文档仅记录了休假类型的 GET 操作。 |
admin_get_holiday | GET /holidays/{id} | 参考文档仅记录了 GET /holidays。 |
admin_create_holiday | POST /holidays | 参考文档仅记录了 GET /holidays。 |
admin_update_holiday | PUT /holidays/{id} | 参考文档仅记录了 GET /holidays。 |
admin_delete_holiday | DELETE /holidays/{id} | 参考文档仅记录了 GET /holidays。 |
admin_list_expenses | GET /expenses、GET /projects/{project_id}/expenses、GET /users/{user_id}/expenses | GET /users/{user_id}/expense_items 和 GET /projects/{project_id}/expense_items。 |
admin_get_expense | GET /expenses/{id} | GET /users/{user_id}/expense_items/{expense_item_id} 和 GET /projects/{project_id}/expense_items/{expense_item_id}。 |
admin_create_expense | POST /expenses | POST /users/{user_id}/expense_items。 |
admin_update_expense | PUT /expenses/{id} | PUT /users/{user_id}/expense_items/{expense_item_id}。 |
admin_delete_expense | DELETE /expenses/{id} | DELETE /users/{user_id}/expense_items/{expense_item_id}。 |
admin_list_expense_categories | GET /expense_categories | GET /expense_item_categories。 |
admin_create_expense_category | POST /expense_categories | 参考文档仅记录了 GET /expense_item_categories。 |
admin_delete_expense_category | DELETE /expense_categories/{id} | 参考文档仅记录了 GET /expense_item_categories。 |
admin_list_tags | GET /tags | GET /projects/{project_id}/tags 和 GET /users/{user_id}/tags。 |
admin_create_tag | POST /tags | POST /projects/{project_id}/tags 和 POST /users/{user_id}/tags。 |
admin_delete_tag | DELETE /tags/{id} | DELETE /projects/{project_id}/tags/{tag_id} 和 DELETE /users/{user_id}/tags/{tag_id}。 |
admin_list_custom_field_values | GET /custom_field_values | GET /projects/{project_id}/custom_field_values 和 GET /users/{user_id}/custom_field_values。 |
admin_set_custom_field_values | PUT /custom_field_values | PUT /projects/{project_id}/custom_field_values/{custom_field_value_id} 和 PUT /users/{user_id}/custom_field_values/{custom_field_value_id}。 |
🚀 快速入门与安装
1. 通过 uvx 运行
[project.scripts] 中的两个控制台脚本都会调用 smartsheet_rm_mcp.server:main:smartsheet-rm-mcp(下文使用)和 mcp-server-smartsheet-rm。安装示例不固定版本。如需固定版本,请从 Releases 中选择版本。
uvx --from mcp-server-smartsheet-rm smartsheet-rm-mcp
升级后,请重新加载 MCP 主机,以确保运行中进程的启动时间晚于新二进制文件的修改时间(旧进程 ≠ 新软件包)。
2. 安装
# Using uv (recommended)
uv pip install mcp-server-smartsheet-rm
# Or standard pip
pip install mcp-server-smartsheet-rm
3. 环境变量
| 变量 | 描述 | 默认值 |
|---|---|---|
SMARTSHEET_RM_API_TOKEN | Smartsheet RM(10,000ft)API 令牌(必填) | - |
SMARTSHEET_RM_BASE_URL | API 基础 URL | https://api.rm.smartsheet.com/api/v1 |
SMARTSHEET_RM_PROFILE | 配置:full、time、projects、admin、readonly、timesheets、staffing、org_setup、portfolio(参见配置) | full |
SMARTSHEET_RM_READONLY | 设为 1 时,仅列出 readOnlyHint=true 的工具,并拒绝其他所有调用 | 0 |
SMARTSHEET_RM_ALLOW_BULK_DESTRUCTIVE | 设为 1 时,允许执行列出的两个批量删除工具 | 0 |
SMARTSHEET_RM_ENABLE_TOOL_SEARCH | 设为 1(或使用 --enable-tool-search)时,在 full 配置下启用工具搜索 | 0 |
SMARTSHEET_RM_TOOL_SEARCH_BACKEND | 工具搜索后端:regex 或 bm25(或使用 --tool-search-backend) | regex |
SMARTSHEET_RM_ENABLE_CODE_MODE | 设为 1(或使用 --enable-code-mode)时,在 full 配置下启用实验性代码模式;不能与工具搜索同时使用 | 0 |
SMARTSHEET_RM_MCP_AUTH_TOKEN | HTTP 传输所需的共享 bearer 令牌(stdio 会忽略此变量) | 未设置 |
SMARTSHEET_RM_MCP_ALLOW_UNAUTHENTICATED_BIND | 设为 1 时,允许在非 localhost 主机上进行无令牌 HTTP 绑定 | 未设置 |
SMARTSHEET_RM_LOG_FORMAT | 设为 json 时,输出适用于 Datadog/CloudWatch 的结构化日志 | text |
SMARTSHEET_RM_ALLOWED_HOSTS | 允许用于覆盖基础 URL 的主机名,以逗号分隔。非空值会替换默认值。仍会阻止环回和私有目标。 | api.rm.smartsheet.com |
SMARTSHEET_RM_GOV_SMARTSHEET_API_TOKEN | 仅用于 Smartsheet Gov 的 Smartsheet API 令牌;作为 Authorization: Bearer 发送,且仅发送至 app.smartsheetgov.com(参见 Smartsheet Gov) | 未设置 |
Smartsheet Gov
Smartsheet Gov 为可选项;默认基础 URL 和允许列表不会改变。根据 Smartsheet 的 RM API 简介和身份验证页面,Gov 的基础 URL 为 https://app.smartsheetgov.com/2.0/rm/api/v1,每个请求都需要在 auth 中提供 RM 令牌,并在 Authorization: Bearer 中提供 Smartsheet API 令牌。使用方法如下:
export SMARTSHEET_RM_BASE_URL='https://app.smartsheetgov.com/2.0/rm/api/v1'
export SMARTSHEET_RM_ALLOWED_HOSTS='app.smartsheetgov.com'
export SMARTSHEET_RM_API_TOKEN='your_rm_api_token'
export SMARTSHEET_RM_GOV_SMARTSHEET_API_TOKEN='your_smartsheet_api_token'
Gov 主机与其他任何基础 URL 一样,会经过 HTTPS、SSRF、允许列表和 DNS 固定检查。客户端在缺少 Smartsheet 令牌时拒绝启动并连接 Gov 主机,且不会将该令牌发送到其他主机。对于 HTTP 传输,发送自有 auth 或 x-smartsheet-rm-token 标头的调用方也必须发送自有 x-smartsheet-gov-api-token 标头;环境中的 Gov 令牌绝不会与调用方的 RM 令牌配对使用。
💻 客户端配置
Google Antigravity(~/.gemini/antigravity-cli/mcp_config.json)
{
"mcpServers": {
"smartsheet-rm": {
"command": "uvx",
"args": ["--from", "mcp-server-smartsheet-rm", "smartsheet-rm-mcp"],
"env": {
"SMARTSHEET_RM_API_TOKEN": "your-api-token"
},
"lazy": true
}
}
}
Snowflake Cortex(~/.snowflake/cortex/mcp.json)
{
"servers": {
"smartsheet-rm": {
"command": "uvx",
"args": ["--from", "mcp-server-smartsheet-rm", "smartsheet-rm-mcp"],
"env": {
"SMARTSHEET_RM_API_TOKEN": "your-api-token"
}
}
}
}
Claude Desktop(claude_desktop_config.json)
{
"mcpServers": {
"smartsheet-rm": {
"command": "uvx",
"args": ["--from", "mcp-server-smartsheet-rm", "smartsheet-rm-mcp"],
"env": {
"SMARTSHEET_RM_API_TOKEN": "your-api-token"
}
}
}
}
Streamable HTTP
优先使用 Streamable HTTP。--transport sse 已弃用(MCP 规范 SEP-2577);main() 会记录迁移警告,且不会将 /sse 声明为客户端路径。
uvx --from mcp-server-smartsheet-rm smartsheet-rm-mcp --transport streamable-http --host 127.0.0.1 --port 8000
将客户端连接到 http://127.0.0.1:8000/mcp(FastMCP 的默认 Streamable HTTP 路径)。run(transport="streamable-http") 不会设置自定义路径。绑定到 0.0.0.0 或 :: 时,必须显式指定 --allowed-host(不接受通配符 *)。
在默认的(有状态)HTTP 模式下,空闲 30 分钟的会话会过期:该会话的下一次请求会收到 HTTP 404,客户端必须启动新会话。可通过 FastMCP 的 session_idle_timeout(在 http_app() 上)或 FASTMCP_HTTP_SESSION_IDLE_TIMEOUT(秒数,或设为 none 表示永不过期)更改此设置;请参阅 FastMCP 4.1.0 发布说明和 #5229。
HTTP 身份验证。 设置 SMARTSHEET_RM_MCP_AUTH_TOKEN,即可要求每个 HTTP 请求都携带 Authorization: Bearer <token>;缺少令牌或令牌错误时会返回 401。令牌会被去除首尾空格,空白值视为未设置。服务器构建时会附加此令牌,因此 smartsheet-rm-mcp、fastmcp run 和挂载 mcp.http_app() 的 ASGI 主机都会执行此验证。stdio 不会使用此令牌。
未设置令牌时,绑定到 127.0.0.1、::1 或 localhost 的 HTTP 服务仍会启动,不进行身份验证,并记录警告。未设置令牌却绑定到其他主机时,程序会以代码 2 退出。请设置令牌、绑定到 localhost,或将 SMARTSHEET_RM_MCP_ALLOW_UNAUTHENTICATED_BIND 设为 1、true、yes 或 on,以允许公开绑定且不进行身份验证(其他任何值都会拒绝)。若要通过 HTTP 提供镜像,请从环境变量或环境文件传递令牌,不要在命令行中传递:
# export SMARTSHEET_RM_API_TOKEN and SMARTSHEET_RM_MCP_AUTH_TOKEN first, or use --env-file .env
docker run --rm -p 8000:8000 -e SMARTSHEET_RM_API_TOKEN -e SMARTSHEET_RM_MCP_AUTH_TOKEN \
ghcr.io/christianclaudio/mcp-server-smartsheet-rm:latest \
--transport streamable-http --host 0.0.0.0 --allowed-host localhost:8000
🛡️ 安全与可靠性
- 机密信息脱敏:API 令牌、Bearer 标头和敏感密钥会自动从错误和日志中清除。
- 破坏性操作防护:每个删除工具都声明
confirm: bool = False,除非调用方显式传入confirm=True,否则不会进行任何更改。未传入时,工具会返回正常结果(isError: false),其中包含"status": "confirmation_required"和要求使用confirm=true重新调用的消息;这是设计好的两步流程,并非错误。 - 输入验证:缺少或无效的参数(例如,不含任何字段的更新,或格式错误的日期)会返回工具错误(
isError: true,"type": "invalid_request"),模型可据此修正。MCP 规范对输入验证错误也有此说明。 - 批量结果:
time_fill_weekly_timesheet、time_confirm_suggested_hours、time_bulk_delete_time_entries和projects_bulk_delete_assignments使用相同的数据结构:"status": "success"或"partial_success"、成功计数(filled_count/confirmed_count/deleted_count)、failed_count、results和errors。每项成功结果的格式为{id|date, status, result};每项失败结果的格式为{id|date, status: "failed", error},其中error始终包含message(API 错误使用to_dict();其他异常使用"type": "internal"和经过脱敏的消息)。早期版本中的字段名仍会保留:time_fill_weekly_timesheet还会返回days_filled、created_count和entries(已创建的条目),time_confirm_suggested_hours还会返回confirmed_entries。当所有项目都失败时,该调用会返回工具错误(isError: true,"type": "batch_failed")。 - 配置文件:只加载某项工作所需的工具(
timesheets、staffing、org_setup、portfolio)或某个领域(time、projects、admin),以尽量减少令牌占用。 - 只读防护:以
readOnlyHint为准;其他情况一律拒绝,并返回isError: true。 - 弹性:遇到 HTTP 429 速率限制时,采用带随机抖动的指数退避策略。
🧪 测试与验证
# Run tests with 100% coverage requirement
pytest --cov=src/smartsheet_rm_mcp --cov-fail-under=100 -v
# Run Tool Contract verification
python scripts/check_tool_contract.py
# Run OpenAPI Drift check against Smartsheet's published spec (or --spec-file for a local copy)
python scripts/check_openapi_drift.py --spec-url https://developers.smartsheet.com/_spec/api/resource_management/openapi.json
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。