mcp-server-smartsheet-rm

Registre officiel Autres

MCP server for Smartsheet Resource Management (10,000ft API) time tracking and scheduling.

Que pouvez-vous faire avec mcp-server-smartsheet-rm ?

  • --enable-tool-search / SMARTSHEET_RM_ENABLE_TOOL_SEARCH=1 replaces tools/list with search_tools and call_tool. The backend is regex (default) or bm25 (--tool-search-backend / SMARTSHEET_RM_TOOL_SEARCH_BACKEND).
  • --enable-code-mode / SMARTSHEET_RM_ENABLE_CODE_MODE=1 attaches FastMCP's experimental Code Mode (search, get_schema, execute). Code Mode needs the sandbox from the package's code-mode extra (fastmcp[code-mode], which ships pydantic-monty): `...
  • Turning on both raises ValueError. Asking for either on another profile logs a warning and keeps the flat list.
  • search_tools, search and get_schema only read the catalog and are annotated readOnlyHint=True. Under read-only, Code Mode execute is refused.

Installation

Ajoutez ceci à la configuration MCP de votre client (Claude Desktop : claude_desktop_config.json ; Cursor : .cursor/mcp.json ; VS Code et les autres utilisent la même forme « mcpServers »).

PYPI package mcp-server-smartsheet-rm
Claude Code
claude mcp add mcp-server-smartsheet-rm -e 'SMARTSHEET_RM_API_TOKEN=<your smartsheet_rm_api_token>' -e 'SMARTSHEET_RM_BASE_URL=<SMARTSHEET_RM_BASE_URL>' -e 'SMARTSHEET_RM_GOV_SMARTSHEET_API_TOKEN=<your smartsheet_rm_gov_smartsheet_api_token>' -e 'SMARTSHEET_RM_ALLOWED_HOSTS=<SMARTSHEET_RM_ALLOWED_HOSTS>' -- uvx mcp-server-smartsheet-rm==2.1.1
Configuration JSON (Claude Desktop, Cursor, VS Code)
{
    "mcpServers": {
        "mcp-server-smartsheet-rm": {
            "command": "uvx",
            "args": [
                "mcp-server-smartsheet-rm==2.1.1"
            ],
            "env": {
                "SMARTSHEET_RM_API_TOKEN": "<your smartsheet_rm_api_token>",
                "SMARTSHEET_RM_BASE_URL": "<SMARTSHEET_RM_BASE_URL>",
                "SMARTSHEET_RM_GOV_SMARTSHEET_API_TOKEN": "<your smartsheet_rm_gov_smartsheet_api_token>",
                "SMARTSHEET_RM_ALLOWED_HOSTS": "<SMARTSHEET_RM_ALLOWED_HOSTS>"
            }
        }
    }
}

Variables d'environnement

  • SMARTSHEET_RM_API_TOKEN obligatoire secret Your Smartsheet Resource Management (10,000ft) API token
  • SMARTSHEET_RM_BASE_URL API base URL. Host must be in SMARTSHEET_RM_ALLOWED_HOSTS (default api.rm.smartsheet.com).
  • SMARTSHEET_RM_GOV_SMARTSHEET_API_TOKEN secret Smartsheet Gov only: Smartsheet API token sent as Authorization: Bearer to app.smartsheetgov.com.
  • SMARTSHEET_RM_ALLOWED_HOSTS Comma-separated hostnames allowed for base URL overrides. A non-blank value replaces the default (api.rm.smartsheet.com).

Documentation

Tirée du README du projet sur GitHub, actualisée chaque semaine. Les liens ouvrent GitHub.

Sommaire
  1. 📋 mcp-server-smartsheet-rm
  2. 🏗️ System Architecture
  3. 🚀 FastMCP 4 Server Composition
  4. ⚡ Tool Surface Overview
  5. 🚀 Quickstart & Installation
  6. 💻 Client Configurations
  7. 🛡️ Safety & Reliability
  8. 🧪 Testing & Validation

📋 mcp-server-smartsheet-rm

Enterprise Model Context Protocol (MCP) server for Resource Management by Smartsheet (10,000ft API).

Enables AI coding agents, planners, and assistants (Claude, Cortex, Antigravity, VS Code) to work with the Smartsheet RM public REST API: time tracking & timesheet reconciliation, resource scheduling & allocations, capacity planning, project & phase management, leaves/holidays, expense tracking, and custom fields.


🏗️ System Architecture

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 mounts the time, projects, and admin sub-servers with FastMCP 4 namespace=, so tools/list names are time_*, projects_*, and admin_*. Legacy rm_* names are not registered on the gateway.


🚀 FastMCP 4 Server Composition

  • Domain mounts (root.mount(..., namespace=...)):
    • namespace="time" → time_* (17 tools, including the bulk-gated time_bulk_delete_time_entries).
    • namespace="projects" → projects_* (27 tools, including the bulk-gated projects_bulk_delete_assignments).
    • namespace="admin" → admin_* (60 tools).
  • Hierarchical middleware:
    • Parent: ParentAuditMiddleware (timing, lifecycle logs, secret redaction) and ReadOnlyGateMiddleware (annotation-driven read-only gate, see below).
    • Child: TimeDomainGuardMiddleware (logged hours must be 0–24; bulk gate), ProjectsDomainGuardMiddleware (project names must be non-empty; bulk gate), AdminDomainGuardMiddleware (per_page must be ≤ 1000).
Profiles

Pick a profile with --profile or SMARTSHEET_RM_PROFILE (default full). An unknown profile name fails at startup with ValueError. There are two kinds:

  • Domain-mount profiles mount whole domains: full, time, projects, admin, and readonly.
  • Job profiles mount every domain, then expose only an explicit list of tool names for one job. Prompts and resources stay available on every job profile and on readonly; the domain-mount profiles time, projects and admin carry only their own domain's prompts and resources. Each listed name is checked against the full catalog when the server builds, so a typo fails at startup.
ProfileJob it servesToolsWith SMARTSHEET_RM_READONLY=1
fullComplete catalog, nothing omitted. Bulk tools are listed and refused at call time unless SMARTSHEET_RM_ALLOW_BULK_DESTRUCTIVE=1. Tool Search and Code Mode attach only here.10439
timeTime tracking, approvals and timesheet recipes (time domain).174
projectsProjects, phases, assignments, placeholders and subtasks (projects domain).2710
adminUsers, org reference data, clients, expenses, fields, reports and webhooks (admin domain).6025
readonlyInspect without side effects: every tool annotated readOnlyHint=True.3939
timesheetsTeam member or manager logs, corrects, submits, locks and approves weekly time against their assignments.2412
staffingResource manager checks availability and utilization and creates or adjusts assignments, placeholders and subtasks.2718
org_setupResource-management admin onboards people and maintains org reference data, custom-field definitions, user statuses and webhooks.3513
portfolioPMO sets up and maintains projects, phases, clients, expenses and project metadata, and reads budget and report totals.3318

Seven tools are in no job profile and are reachable only in full (or their domain-mount profile): time_bulk_delete_time_entries, projects_bulk_delete_assignments, admin_delete_client, admin_delete_client_contact, admin_create_expense_category, admin_delete_expense_category, and admin_delete_tag.

Read-only behavior
  • The MCP readOnlyHint annotation is the only thing that decides whether a tool is read-only. Every tool declares it explicitly: true on the 39 reads and false on the 65 writes. A tool with no annotation or no readOnlyHint counts as a write.
  • --profile readonly or SMARTSHEET_RM_READONLY=1 (on any profile) lists only the read-only tools, and ReadOnlyGateMiddleware refuses any call to a real tool that is not read-only, including a write the filter hid. A refusal comes back as a tool result with isError: true.
  • A name that is not a tool on the server gets FastMCP's normal Unknown tool error, directly or through call_tool, so a typo is never reported as a blocked tool.
  • With Tool Search on, the gate checks the tool that call_tool wraps. Reads through call_tool work and writes are refused. Without Tool Search, call_tool is not a tool on the server, so a call to it gets Unknown tool: 'call_tool'.
  • If the gate cannot see the serving server, it refuses the call.
Bulk gate

time_bulk_delete_time_entries and projects_bulk_delete_assignments are listed in full, time and projects. The domain guards refuse them at call time (isError: true) unless SMARTSHEET_RM_ALLOW_BULK_DESTRUCTIVE=1, and the handlers still require confirm=True. Read-only mode hides and refuses them.

Tool Search and Code Mode

tools/list is flat by default. Discovery is opt-in and attaches only on full:

  • --enable-tool-search / SMARTSHEET_RM_ENABLE_TOOL_SEARCH=1 replaces tools/list with search_tools and call_tool. The backend is regex (default) or bm25 (--tool-search-backend / SMARTSHEET_RM_TOOL_SEARCH_BACKEND).
  • --enable-code-mode / SMARTSHEET_RM_ENABLE_CODE_MODE=1 attaches FastMCP's experimental Code Mode (search, get_schema, execute). Code Mode needs the sandbox from the package's code-mode extra (fastmcp[code-mode], which ships pydantic-monty): pip install "mcp-server-smartsheet-rm[code-mode]" or uvx --from "mcp-server-smartsheet-rm[code-mode]" smartsheet-rm-mcp --enable-code-mode. Without it, Code Mode is skipped with a warning and the flat catalog is served.
  • Turning on both raises ValueError. Asking for either on another profile logs a warning and keeps the flat list.
  • search_tools, search and get_schema only read the catalog and are annotated readOnlyHint=True. Under read-only, Code Mode execute is refused.

⚡ Tool Surface Overview

The server exposes tools covering projects, resources, timesheets, and capacity. Call the namespaced names below:

  • Default Registration: 104 tools on full (the 2 bulk-destructive tools are listed and refused at call time unless SMARTSHEET_RM_ALLOW_BULK_DESTRUCTIVE=1).
  • Read-Only Mode: 39 tools (readOnlyHint=true).
  • Destructive Gates: 21 tools requiring explicit confirm=True (19 standard + 2 bulk).
  • Idempotent Operations: 43 tools with idempotentHint=true (the 39 read-only tools, plus time_update_time_approval_status, time_lock_timesheet, admin_set_custom_field_values, and admin_set_user_status).
Domain Overview

Agents call these tools/list names. Counts for time and projects include the bulk-gated tool.

  1. Time (time_*, 17 tools): 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. Bulk-gated: time_bulk_delete_time_entries.
  2. Projects (projects_*, 27 tools): 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. Bulk-gated: projects_bulk_delete_assignments.
  3. Admin (admin_*, 60 tools):
    • Users, roles, disciplines, and capacity: 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.
    • Clients and contacts: 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.
    • Leaves and holidays: 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.
    • Expenses: 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.
    • Tags and custom fields: 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.
    • Status, reports, and webhooks: 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.
Undocumented routes

The tools below call routes that are in neither Smartsheet's Resource Management API reference (OpenAPI JSON) nor the archived 10,000ft API docs. There are 46 such method and path pairs. They are kept, and not re-pointed, because some documented equivalents take different request shapes, so moving a tool would change what it sends. Smartsheet may change or remove an undocumented route without notice, and each of these tools says so in its description. Prefer a tool on a documented route when one fits: for example, time_create_user_time_entry or time_create_project_time_entry instead of time_create_time_entry. Each of these client calls carries # drift-ignore: undocumented route, and scripts/check_openapi_drift.py fails on any other call that is not in the published spec.

ToolUndocumented routeDocumented equivalent
time_create_time_entryPOST /time_entriesPOST /users/{user_id}/time_entries (time_create_user_time_entry) and POST /projects/{project_id}/time_entries (time_create_project_time_entry).
time_update_time_entryPUT /time_entries/{id}PUT /users/{user_id}/time_entries/{id}.
time_delete_time_entryDELETE /time_entries/{id}DELETE /users/{user_id}/time_entries/{id}.
time_update_time_approval_statusPUT /users/{user_id}/time_entries/approval_statusNone found.
time_lock_timesheetPOST /users/{user_id}/time_entries/lockNone found.
time_fill_weekly_timesheetPOST /time_entriesPOST /users/{user_id}/time_entries.
time_confirm_suggested_hoursPUT /time_entries/{id}PUT /users/{user_id}/time_entries/{id}.
time_reconcile_and_submit_weekPUT /users/{user_id}/time_entries/approval_statusNone found (called only with auto_submit=True).
time_bulk_delete_time_entriesDELETE /time_entries/{id}DELETE /users/{user_id}/time_entries/{id}.
projects_get_project_phaseGET /projects/{project_id}/phases/{phase_id}The reference documents only PUT and DELETE on that path; GET /projects/{project_id}/phases lists phases.
admin_list_user_bill_ratesGET /users/{user_id}/bill_ratesGET /bill_rates and GET /projects/{project_id}/bill_rates.
admin_create_user_bill_ratePOST /users/{user_id}/bill_ratesThe reference documents bill rates only under /bill_rates and /projects/{project_id}/bill_rates, with no create.
admin_get_user_availabilityGET /users/{user_id}/availabilityGET /users/{user_id}/availabilities.
admin_get_user_utilizationGET /users/{user_id}/utilizationNone found.
admin_create_rolePOST /rolesThe reference documents only GET for roles.
admin_update_rolePUT /roles/{id}The reference documents only GET for roles.
admin_delete_roleDELETE /roles/{id}The reference documents only GET for roles.
admin_create_disciplinePOST /disciplinesThe reference documents only GET for disciplines.
admin_update_disciplinePUT /disciplines/{id}The reference documents only GET for disciplines.
admin_delete_disciplineDELETE /disciplines/{id}The reference documents only GET for disciplines.
admin_list_clientsGET /clientsNone found.
admin_get_clientGET /clients/{id}None found.
admin_create_clientPOST /clientsNone found.
admin_update_clientPUT /clients/{id}None found.
admin_delete_clientDELETE /clients/{id}None found.
admin_list_client_contactsGET /clients/{id}/contactsNone found.
admin_create_client_contactPOST /clients/{id}/contactsNone found.
admin_delete_client_contactDELETE /clients/{id}/contacts/{contact_id}None found.
admin_create_leave_typePOST /leave_typesThe reference documents only GET for leave types.
admin_update_leave_typePUT /leave_types/{id}The reference documents only GET for leave types.
admin_delete_leave_typeDELETE /leave_types/{id}The reference documents only GET for leave types.
admin_get_holidayGET /holidays/{id}The reference documents only GET /holidays.
admin_create_holidayPOST /holidaysThe reference documents only GET /holidays.
admin_update_holidayPUT /holidays/{id}The reference documents only GET /holidays.
admin_delete_holidayDELETE /holidays/{id}The reference documents only GET /holidays.
admin_list_expensesGET /expenses, GET /projects/{project_id}/expenses, GET /users/{user_id}/expensesGET /users/{user_id}/expense_items and GET /projects/{project_id}/expense_items.
admin_get_expenseGET /expenses/{id}GET /users/{user_id}/expense_items/{expense_item_id} and GET /projects/{project_id}/expense_items/{expense_item_id}.
admin_create_expensePOST /expensesPOST /users/{user_id}/expense_items.
admin_update_expensePUT /expenses/{id}PUT /users/{user_id}/expense_items/{expense_item_id}.
admin_delete_expenseDELETE /expenses/{id}DELETE /users/{user_id}/expense_items/{expense_item_id}.
admin_list_expense_categoriesGET /expense_categoriesGET /expense_item_categories.
admin_create_expense_categoryPOST /expense_categoriesThe reference documents only GET /expense_item_categories.
admin_delete_expense_categoryDELETE /expense_categories/{id}The reference documents only GET /expense_item_categories.
admin_list_tagsGET /tagsGET /projects/{project_id}/tags and GET /users/{user_id}/tags.
admin_create_tagPOST /tagsPOST /projects/{project_id}/tags and POST /users/{user_id}/tags.
admin_delete_tagDELETE /tags/{id}DELETE /projects/{project_id}/tags/{tag_id} and DELETE /users/{user_id}/tags/{tag_id}.
admin_list_custom_field_valuesGET /custom_field_valuesGET /projects/{project_id}/custom_field_values and GET /users/{user_id}/custom_field_values.
admin_set_custom_field_valuesPUT /custom_field_valuesPUT /projects/{project_id}/custom_field_values/{custom_field_value_id} and PUT /users/{user_id}/custom_field_values/{custom_field_value_id}.

🚀 Quickstart & Installation

1. Run via uvx

Console scripts in [project.scripts] both call smartsheet_rm_mcp.server:main: smartsheet-rm-mcp (used below) and mcp-server-smartsheet-rm. Install examples stay unpinned. To freeze a release, pin the version from Releases.

uvx --from mcp-server-smartsheet-rm smartsheet-rm-mcp

After an upgrade, reload the MCP host so the live process start time is after the new binary mtime (stale process ≠ new package).

2. Installation
# Using uv (recommended)
uv pip install mcp-server-smartsheet-rm

# Or standard pip
pip install mcp-server-smartsheet-rm
3. Environment Variables
VariableDescriptionDefault
SMARTSHEET_RM_API_TOKENSmartsheet RM (10,000ft) API Token (Required)-
SMARTSHEET_RM_BASE_URLBase API URLhttps://api.rm.smartsheet.com/api/v1
SMARTSHEET_RM_PROFILEProfile: full, time, projects, admin, readonly, timesheets, staffing, org_setup, portfolio (see Profiles)full
SMARTSHEET_RM_READONLYSet to 1 to list only readOnlyHint=true tools and refuse every other call0
SMARTSHEET_RM_ALLOW_BULK_DESTRUCTIVESet to 1 to let the two listed bulk delete tools execute0
SMARTSHEET_RM_ENABLE_TOOL_SEARCHSet to 1 (or --enable-tool-search) for Tool Search on full0
SMARTSHEET_RM_TOOL_SEARCH_BACKENDTool Search backend: regex or bm25 (or --tool-search-backend)regex
SMARTSHEET_RM_ENABLE_CODE_MODESet to 1 (or --enable-code-mode) for experimental Code Mode on full; not with Tool Search0
SMARTSHEET_RM_MCP_AUTH_TOKENShared bearer token required on HTTP transports (stdio ignores it)unset
SMARTSHEET_RM_MCP_ALLOW_UNAUTHENTICATED_BINDSet to 1 to accept a tokenless HTTP bind to a non-localhost hostunset
SMARTSHEET_RM_LOG_FORMATSet to json for Datadog/CloudWatch structured logstext
SMARTSHEET_RM_ALLOWED_HOSTSComma-separated hostnames allowed for base URL overrides. A non-blank value replaces the default. Loopback and private targets stay blocked.api.rm.smartsheet.com
SMARTSHEET_RM_GOV_SMARTSHEET_API_TOKENSmartsheet API token for Smartsheet Gov only; sent as Authorization: Bearer and only to app.smartsheetgov.com (see Smartsheet Gov)unset
Smartsheet Gov

Smartsheet Gov is opt-in; the default base URL and allowlist do not change. Per Smartsheet's RM API Introduction and Authentication pages, the Gov base URL is https://app.smartsheetgov.com/2.0/rm/api/v1 and every request needs both the RM token in auth and a Smartsheet API token as Authorization: Bearer. To use it:

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'

The Gov host goes through the same HTTPS, SSRF, allowlist and DNS-pinning checks as any other base URL. The client refuses to start against the Gov host without the Smartsheet token, and sends that token to no other host. On HTTP transports, a caller that sends its own auth or x-smartsheet-rm-token header must also send its own x-smartsheet-gov-api-token header; the environment Gov token is never paired with a caller's RM token.


💻 Client Configurations

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

Prefer Streamable HTTP. --transport sse is deprecated (MCP spec SEP-2577); main() logs a migration warning and does not advertise /sse as the client path.

uvx --from mcp-server-smartsheet-rm smartsheet-rm-mcp --transport streamable-http --host 127.0.0.1 --port 8000

Connect clients to http://127.0.0.1:8000/mcp (FastMCP's default Streamable HTTP path). run(transport="streamable-http") does not set a custom path. Binding to 0.0.0.0 or :: requires an explicit --allowed-host (a wildcard * is rejected).

In the default (stateful) HTTP mode, a session idle for 30 minutes expires: its next request gets HTTP 404 and the client must start a new session. Change this with FastMCP's session_idle_timeout (on http_app()) or FASTMCP_HTTP_SESSION_IDLE_TIMEOUT (seconds, or none to never expire); see the FastMCP 4.1.0 release and #5229.

HTTP authentication. Set SMARTSHEET_RM_MCP_AUTH_TOKEN to require Authorization: Bearer <token> on every HTTP request; a missing or wrong token gets 401. The token is stripped, and a blank value counts as unset. It is attached when the server is built, so smartsheet-rm-mcp, fastmcp run and an ASGI host mounting mcp.http_app() all enforce it. stdio never uses it.

With no token, an HTTP bind to 127.0.0.1, ::1 or localhost still starts, unauthenticated, and logs a warning. A tokenless bind to any other host exits with code 2. Set the token, bind to localhost, or set SMARTSHEET_RM_MCP_ALLOW_UNAUTHENTICATED_BIND to 1, true, yes or on to accept an unauthenticated public bind (any other value refuses). To serve the image over HTTP, pass the tokens from your environment or an env file, not on the command line:

# 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

🛡️ Safety & Reliability

  • Secret Redaction: API tokens, bearer headers, and sensitive keys are automatically scrubbed from errors and logs.
  • Destructive Gates: Every deletion tool declares confirm: bool = False and makes no change unless the caller explicitly passes confirm=True. Without it the tool returns a normal result (isError: false) with "status": "confirmation_required" and a message to re-call with confirm=true; that is the designed two-step, not an error.
  • Input Validation: Missing or invalid arguments (for example an update with no fields, or a malformed date) return a tool error (isError: true, "type": "invalid_request") the model can correct, as the MCP spec describes for input validation errors.
  • Batch Results: time_fill_weekly_timesheet, time_confirm_suggested_hours, time_bulk_delete_time_entries and projects_bulk_delete_assignments share one shape: "status": "success" or "partial_success", a success count (filled_count / confirmed_count / deleted_count), failed_count, results and errors. Each success is {id|date, status, result}; each failure is {id|date, status: "failed", error} where error always has a message (API errors via to_dict(); other exceptions as "type": "internal" with a redacted message). The field names from earlier releases stay alongside: time_fill_weekly_timesheet also returns days_filled, created_count and entries (the created entries), and time_confirm_suggested_hours returns confirmed_entries. When every item fails, the call is a tool error (isError: true, "type": "batch_failed").
  • Profiles: Minimize token footprint by loading only the tools one job needs (timesheets, staffing, org_setup, portfolio) or one domain (time, projects, admin).
  • Read-Only Gate: readOnlyHint decides; anything else is refused with isError: true.
  • Resilience: Exponential backoff with randomized jitter on HTTP 429 rate limits.

🧪 Testing & Validation

# 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

Questions fréquentes

Qu'est-ce que mcp-server-smartsheet-rm ?

MCP server for Smartsheet Resource Management (10,000ft API) time tracking and scheduling.

Comment installer mcp-server-smartsheet-rm ?

Il s'exécute sur votre machine. Dans Claude Code : claude mcp add mcp-server-smartsheet-rm -e 'SMARTSHEET_RM_API_TOKEN=<your smartsheet_rm_api_token>' -e 'SMARTSHEET_RM_BASE_URL=<SMARTSHEET_RM_BASE_URL>' -e 'SMARTSHEET_RM_GOV_SMARTSHEET_API_TOKEN=<your smartsheet_rm_gov_smartsheet_api_token>' -e 'SMARTSHEET_RM_ALLOWED_HOSTS=<SMARTSHEET_RM_ALLOWED_HOSTS>' -- uvx mcp-server-smartsheet-rm==2.1.1. Pour les autres clients, collez la configuration JSON de cette page dans leurs réglages MCP.

Faut-il une clé API pour mcp-server-smartsheet-rm ?

Oui. Il attend SMARTSHEET_RM_API_TOKEN, SMARTSHEET_RM_GOV_SMARTSHEET_API_TOKEN, à renseigner dans sa configuration.

mcp-server-smartsheet-rm est-il open source ?

Oui. Son code est sur GitHub sous licence Apache-2.0.

Qui maintient mcp-server-smartsheet-rm ?

Il est publié par christianclaudio. AI.tn le référence sans le maintenir ni le recommander.

Issu du registre MCP officiel. Être listé n'est pas une recommandation : vérifiez le code et les permissions d'un serveur avant de lui donner accès à vos données.