Skip to main content
Glama
mcp-server-smartsheet-rm

mcp-server-smartsheet-rm

📋 mcp-server-smartsheet-rm

CI PyPI Python License: Apache-2.0 Coverage CodeRabbit Reviews

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_* — 19 tools, incl. 1 bulk-gated)"]
    Middle --> SubProj["projects namespace (projects_* — 36 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.


Related MCP server: @lewinnovation/clockify-mcp-server

🚀 FastMCP 4 Server Composition

  • Domain mounts (root.mount(..., namespace=...)):

    • namespace="time" → time_* (19 tools, including the bulk-gated time_bulk_delete_time_entries).

    • namespace="projects" → projects_* (36 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.

Profile

Job it serves

Tools

With SMARTSHEET_RM_READONLY=1

full

Complete 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.

115

50

time

Time tracking, approvals and timesheet recipes (time domain).

19

6

projects

Projects, phases, assignments, placeholders and subtasks (projects domain).

36

19

admin

Users, org reference data, clients, expenses, fields, reports and webhooks (admin domain).

60

25

readonly

Inspect without side effects: every tool annotated readOnlyHint=True.

50

50

timesheets

Team member or manager logs, corrects, submits, locks and approves weekly time against their assignments.

26

14

staffing

Resource manager checks availability and utilization and creates or adjusts assignments, placeholders and subtasks.

33

24

org_setup

Resource-management admin onboards people and maintains org reference data, custom-field definitions, user statuses and webhooks.

35

13

portfolio

PMO sets up and maintains projects, phases, clients, expenses and project metadata, and reads budget and report totals.

36

21

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 50 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: 115 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: 50 tools (readOnlyHint=true).

  • Destructive Gates: 21 tools requiring explicit confirm=True (19 standard + 2 bulk).

  • Idempotent Operations: 54 tools with idempotentHint=true (the 50 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_*, 19 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, time_list_time_entry_categories, time_list_project_time_entry_categories. Bulk-gated: time_bulk_delete_time_entries.

  2. Projects (projects_*, 36 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, projects_list_assignables, projects_get_assignable, projects_list_project_budget_items, projects_get_budget_item, projects_get_project_budget_item, projects_list_project_members, projects_list_relationships_project_members, projects_list_relationships_project_memberships, projects_list_user_project_memberships. 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.

Tool

Undocumented route

Documented equivalent

time_create_time_entry

POST /time_entries

POST /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_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

None found.

time_lock_timesheet

POST /users/{user_id}/time_entries/lock

None found.

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

None found (called only with 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}

The reference documents only PUT and DELETE on that path; GET /projects/{project_id}/phases lists phases.

admin_list_user_bill_rates

GET /users/{user_id}/bill_rates

GET /bill_rates and GET /projects/{project_id}/bill_rates.

admin_create_user_bill_rate

POST /users/{user_id}/bill_rates

The reference documents bill rates only under /bill_rates and /projects/{project_id}/bill_rates, with no create.

admin_get_user_availability

GET /users/{user_id}/availability

GET /users/{user_id}/availabilities.

admin_get_user_utilization

GET /users/{user_id}/utilization

None found.

admin_create_role

POST /roles

The reference documents only GET for roles.

admin_update_role

PUT /roles/{id}

The reference documents only GET for roles.

admin_delete_role

DELETE /roles/{id}

The reference documents only GET for roles.

admin_create_discipline

POST /disciplines

The reference documents only GET for disciplines.

admin_update_discipline

PUT /disciplines/{id}

The reference documents only GET for disciplines.

admin_delete_discipline

DELETE /disciplines/{id}

The reference documents only GET for disciplines.

admin_list_clients

GET /clients

None found.

admin_get_client

GET /clients/{id}

None found.

admin_create_client

POST /clients

None found.

admin_update_client

PUT /clients/{id}

None found.

admin_delete_client

DELETE /clients/{id}

None found.

admin_list_client_contacts

GET /clients/{id}/contacts

None found.

admin_create_client_contact

POST /clients/{id}/contacts

None found.

admin_delete_client_contact

DELETE /clients/{id}/contacts/{contact_id}

None found.

admin_create_leave_type

POST /leave_types

The reference documents only GET for leave types.

admin_update_leave_type

PUT /leave_types/{id}

The reference documents only GET for leave types.

admin_delete_leave_type

DELETE /leave_types/{id}

The reference documents only GET for leave types.

admin_get_holiday

GET /holidays/{id}

The reference documents only GET /holidays.

admin_create_holiday

POST /holidays

The reference documents only GET /holidays.

admin_update_holiday

PUT /holidays/{id}

The reference documents only GET /holidays.

admin_delete_holiday

DELETE /holidays/{id}

The reference documents only GET /holidays.

admin_list_expenses

GET /expenses, GET /projects/{project_id}/expenses, GET /users/{user_id}/expenses

GET /users/{user_id}/expense_items and GET /projects/{project_id}/expense_items.

admin_get_expense

GET /expenses/{id}

GET /users/{user_id}/expense_items/{expense_item_id} and 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

The reference documents only GET /expense_item_categories.

admin_delete_expense_category

DELETE /expense_categories/{id}

The reference documents only GET /expense_item_categories.

admin_list_tags

GET /tags

GET /projects/{project_id}/tags and GET /users/{user_id}/tags.

admin_create_tag

POST /tags

POST /projects/{project_id}/tags and POST /users/{user_id}/tags.

admin_delete_tag

DELETE /tags/{id}

DELETE /projects/{project_id}/tags/{tag_id} and DELETE /users/{user_id}/tags/{tag_id}.

admin_list_custom_field_values

GET /custom_field_values

GET /projects/{project_id}/custom_field_values and 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} 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

Variable

Description

Default

SMARTSHEET_RM_API_TOKEN

Smartsheet RM (10,000ft) API Token (Required)

-

SMARTSHEET_RM_BASE_URL

Base API URL

https://api.rm.smartsheet.com/api/v1

SMARTSHEET_RM_PROFILE

Profile: full, time, projects, admin, readonly, timesheets, staffing, org_setup, portfolio (see Profiles)

full

SMARTSHEET_RM_READONLY

Set to 1 to list only readOnlyHint=true tools and refuse every other call

0

SMARTSHEET_RM_ALLOW_BULK_DESTRUCTIVE

Set to 1 to let the two listed bulk delete tools execute

0

SMARTSHEET_RM_ENABLE_TOOL_SEARCH

Set to 1 (or --enable-tool-search) for Tool Search on full

0

SMARTSHEET_RM_TOOL_SEARCH_BACKEND

Tool Search backend: regex or bm25 (or --tool-search-backend)

regex

SMARTSHEET_RM_ENABLE_CODE_MODE

Set to 1 (or --enable-code-mode) for experimental Code Mode on full; not with Tool Search

0

SMARTSHEET_RM_MCP_AUTH_TOKEN

Shared bearer token required on HTTP transports (stdio ignores it)

unset

SMARTSHEET_RM_MCP_ALLOW_UNAUTHENTICATED_BIND

Set to 1 to accept a tokenless HTTP bind to a non-localhost host

unset

SMARTSHEET_RM_LOG_FORMAT

Set to json for Datadog/CloudWatch structured logs

text

SMARTSHEET_RM_ALLOWED_HOSTS

Comma-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_TOKEN

Smartsheet 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

Available Tools

115 tools
admin_create_clientAdmin Create ClientA

Create a new client record.

Undocumented route: POST /clients is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. No documented equivalent was found.

Inputs: name (required), city, state, address, +2 more. Returns: result

admin_create_client_contactAdmin Create Client ContactB

Add a contact for a client.

Undocumented route: POST /clients/{id}/contacts is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. No documented equivalent was found.

Inputs: client_id (required), last_name (required), first_name (required), email, +2 more. Returns: result

admin_create_custom_fieldAdmin Create Custom FieldA

Create a custom field definition (field_type: text, number, select, date; target_type: Project, User, Phase).

Inputs: name (required), field_type (required), target_type (required), options. Returns: result

admin_create_disciplineAdmin Create DisciplineB

Create a new discipline.

Undocumented route: POST /disciplines is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. The reference documents only GET for disciplines.

Inputs: name (required). Returns: result

admin_create_expenseAdmin Create ExpenseB

Log a project expense item.

Undocumented route: POST /expenses is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. Documented route: POST /users/{user_id}/expense_items.

Inputs: date (required), amount (required), user_id (required), project_id (required), +3 more. Returns: result

admin_create_expense_categoryAdmin Create Expense CategoryB

Create an expense category.

Undocumented route: POST /expense_categories is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. The reference documents only GET /expense_item_categories.

Inputs: name (required). Returns: result

admin_create_holidayAdmin Create HolidayB

Create a new company holiday or non-working day.

Undocumented route: POST /holidays is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. The reference documents only GET /holidays.

Inputs: date (required), name (required), end_date. Returns: result

admin_create_leave_typeAdmin Create Leave TypeB

Create a new leave type.

Undocumented route: POST /leave_types is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. The reference documents only GET for leave types.

Inputs: name (required). Returns: result

admin_create_roleAdmin Create RoleB

Create a new role.

Undocumented route: POST /roles is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. The reference documents only GET for roles.

Inputs: name (required). Returns: result

admin_create_tagAdmin Create TagB

Create a tag.

Undocumented route: POST /tags is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. Documented routes: POST /projects/{project_id}/tags and POST /users/{user_id}/tags.

Inputs: name (required). Returns: result

admin_create_userAdmin Create UserC

Create a new user profile in Smartsheet RM.

Inputs: email (required), last_name (required), first_name (required), role, +6 more. Returns: result

admin_create_user_bill_rateAdmin Create User Bill RateB

Add a bill rate tier with an effective date range for a user.

Undocumented route: POST /users/{user_id}/bill_rates is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. The reference documents bill rates only under /bill_rates and /projects/{project_id}/bill_rates, with no create.

Inputs: rate (required), user_id (required), start_date (required), end_date. Returns: result

admin_create_webhookAdmin Create WebhookC

Register a webhook subscription (e.g. 'time.entry.created', 'project.updated', 'assignment.created').

Inputs: event_type (required), callback_url (required). Returns: result

admin_delete_clientAdmin Delete ClientA
Destructive

Delete a client record (Destructive: requires confirm=True).

Undocumented route: DELETE /clients/{id} is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. No documented equivalent was found.

Inputs: client_id (required), confirm. Returns: result

admin_delete_client_contactAdmin Delete Client ContactA
Destructive

Delete a client contact (Destructive: requires confirm=True).

Undocumented route: DELETE /clients/{id}/contacts/{contact_id} is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. No documented equivalent was found.

Inputs: client_id (required), contact_id (required), confirm. Returns: result

admin_delete_custom_fieldAdmin Delete Custom FieldA
Destructive

Delete a custom field definition (Destructive: requires confirm=True).

Inputs: custom_field_id (required), confirm. Returns: result

admin_delete_disciplineAdmin Delete DisciplineA
Destructive

Delete a discipline (Destructive: requires confirm=True).

Undocumented route: DELETE /disciplines/{id} is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. The reference documents only GET for disciplines.

Inputs: discipline_id (required), confirm. Returns: result

admin_delete_expenseAdmin Delete ExpenseA
Destructive

Delete an expense item (Destructive: requires confirm=True).

Undocumented route: DELETE /expenses/{id} is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. Documented route: DELETE /users/{user_id}/expense_items/{expense_item_id}.

Inputs: expense_id (required), confirm. Returns: result

admin_delete_expense_categoryAdmin Delete Expense CategoryA
Destructive

Delete an expense category (Destructive: requires confirm=True).

Undocumented route: DELETE /expense_categories/{id} is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. The reference documents only GET /expense_item_categories.

Inputs: category_id (required), confirm. Returns: result

admin_delete_holidayAdmin Delete HolidayA
Destructive

Delete a holiday (Destructive: requires confirm=True).

Undocumented route: DELETE /holidays/{id} is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. The reference documents only GET /holidays.

Inputs: holiday_id (required), confirm. Returns: result

admin_delete_leave_typeAdmin Delete Leave TypeA
Destructive

Delete a leave type (Destructive: requires confirm=True).

Undocumented route: DELETE /leave_types/{id} is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. The reference documents only GET for leave types.

Inputs: leave_type_id (required), confirm. Returns: result

admin_delete_roleAdmin Delete RoleA
Destructive

Delete a role (Destructive: requires confirm=True).

Undocumented route: DELETE /roles/{id} is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. The reference documents only GET for roles.

Inputs: role_id (required), confirm. Returns: result

admin_delete_tagAdmin Delete TagA
Destructive

Delete a tag (Destructive: requires confirm=True).

Undocumented route: DELETE /tags/{id} is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. Documented routes: DELETE /projects/{project_id}/tags/{tag_id} and DELETE /users/{user_id}/tags/{tag_id}.

Inputs: tag_id (required), confirm. Returns: result

admin_delete_userAdmin Delete UserB
Destructive

Delete or archive a user (Destructive: requires confirm=True).

Inputs: user_id (required), confirm. Returns: result

admin_delete_webhookAdmin Delete WebhookA
Destructive

Delete a webhook subscription (Destructive: requires confirm=True).

Inputs: webhook_id (required), confirm. Returns: result

admin_get_clientAdmin Get ClientA
Read-onlyIdempotent

Get details for a specific client.

Undocumented route: GET /clients/{id} is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. No documented equivalent was found.

Inputs: client_id (required). Returns: result

admin_get_custom_fieldAdmin Get Custom FieldC
Read-onlyIdempotent

Get details of a custom field definition.

Inputs: custom_field_id (required). Returns: result

admin_get_expenseAdmin Get ExpenseB
Read-onlyIdempotent

Get details for a specific logged expense.

Undocumented route: GET /expenses/{id} is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. Documented routes: GET /users/{user_id}/expense_items/{expense_item_id} and GET /projects/{project_id}/expense_items/{expense_item_id}.

Inputs: expense_id (required). Returns: result

admin_get_holidayAdmin Get HolidayB
Read-onlyIdempotent

Get details for a specific holiday.

Undocumented route: GET /holidays/{id} is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. The reference documents only GET /holidays.

Inputs: holiday_id (required). Returns: result

admin_get_leave_typeAdmin Get Leave TypeC
Read-onlyIdempotent

Get details for a specific leave type.

Inputs: leave_type_id (required). Returns: result

admin_get_report_rowsAdmin Get Report RowsC
Read-onlyIdempotent

Generate detailed custom report rows.

Inputs: report_parameters (required). Returns: result

admin_get_report_totalsAdmin Get Report TotalsC
Read-onlyIdempotent

Generate aggregated custom report totals.

Inputs: report_parameters (required). Returns: result

admin_get_userAdmin Get UserC
Read-onlyIdempotent

Get details for a specific user.

Inputs: user_id (required). Returns: result

admin_get_user_availabilityAdmin Get User AvailabilityB
Read-onlyIdempotent

Query scheduled hours vs available capacity for a user.

Undocumented route: GET /users/{user_id}/availability is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. Documented route: GET /users/{user_id}/availabilities.

Inputs: user_id (required), to_date, from_date. Returns: result

admin_get_user_statusesAdmin Get User StatusesB
Read-onlyIdempotent

Retrieve work status history for a specific user (ITO, WFH, SIC, OOO, VAC, OOF).

Inputs: user_id (required). Returns: result

admin_get_user_utilizationAdmin Get User UtilizationB
Read-onlyIdempotent

Get billable utilization metrics for a user.

Undocumented route: GET /users/{user_id}/utilization is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. No documented equivalent was found.

Inputs: user_id (required), to_date, from_date. Returns: result

admin_list_client_contactsAdmin List Client ContactsA
Read-onlyIdempotent

List contacts associated with a client.

Undocumented route: GET /clients/{id}/contacts is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. No documented equivalent was found.

Inputs: client_id (required). Returns: result

admin_list_clientsAdmin List ClientsB
Read-onlyIdempotent

List clients.

Undocumented route: GET /clients is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. No documented equivalent was found.

Inputs: page, archived, per_page. Returns: result

admin_list_custom_fieldsAdmin List Custom FieldsB
Read-onlyIdempotent

List custom field definitions.

Inputs: no named parameters. Returns: result

admin_list_custom_field_valuesAdmin List Custom Field ValuesA
Read-onlyIdempotent

List custom field values, optionally filtered to one entity by target_id and target_type.

Undocumented route: GET /custom_field_values is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. Documented routes: GET /projects/{project_id}/custom_field_values and GET /users/{user_id}/custom_field_values.

Inputs: target_id, target_type. Returns: result

admin_list_disciplinesAdmin List DisciplinesA
Read-onlyIdempotent

List all configured disciplines.

Inputs: no named parameters. Returns: result

admin_list_expense_categoriesAdmin List Expense CategoriesA
Read-onlyIdempotent

List configured expense categories.

Undocumented route: GET /expense_categories is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. Documented route: GET /expense_item_categories.

Inputs: no named parameters. Returns: result

admin_list_expensesAdmin List ExpensesB
Read-onlyIdempotent

List logged expenses across projects or filtered by project/user.

Undocumented route: GET /expenses, GET /projects/{project_id}/expenses, GET /users/{user_id}/expenses are not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove them without notice. Documented routes: GET /users/{user_id}/expense_items and GET /projects/{project_id}/expense_items.

Inputs: page, to_date, user_id, per_page, +2 more. Returns: result

admin_list_holidaysAdmin List HolidaysB
Read-onlyIdempotent

List company and regional holidays.

Inputs: to_date, from_date. Returns: result

admin_list_leave_typesAdmin List Leave TypesA
Read-onlyIdempotent

List leave types (e.g. Vacation, Sick, Parental, PTO).

Inputs: no named parameters. Returns: result

admin_list_rolesAdmin List RolesB
Read-onlyIdempotent

List all configured user roles.

Inputs: no named parameters. Returns: result

admin_list_tagsAdmin List TagsC
Read-onlyIdempotent

List tags.

Undocumented route: GET /tags is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. Documented routes: GET /projects/{project_id}/tags and GET /users/{user_id}/tags.

Inputs: page, per_page. Returns: result

admin_list_user_bill_ratesAdmin List User Bill RatesA
Read-onlyIdempotent

List bill rate tiers for a user.

Undocumented route: GET /users/{user_id}/bill_rates is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. Documented routes: GET /bill_rates and GET /projects/{project_id}/bill_rates.

Inputs: user_id (required). Returns: result

admin_list_usersAdmin List UsersB
Read-onlyIdempotent

List users in the organization with role/discipline filtering.

Inputs: page, role, archived, per_page, +2 more. Returns: result

admin_list_webhooksAdmin List WebhooksB
Read-onlyIdempotent

List configured organization webhooks.

Inputs: no named parameters. Returns: result

admin_set_custom_field_valuesAdmin Set Custom Field ValuesB
Idempotent

Set custom field values for an entity.

Undocumented route: PUT /custom_field_values is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. Documented routes: PUT /projects/{project_id}/custom_field_values/{custom_field_value_id} and PUT /users/{user_id}/custom_field_values/{custom_field_value_id}.

Inputs: values (required), target_id (required), target_type (required). Returns: result

admin_set_user_statusAdmin Set User StatusB
Idempotent

Set current working status for a user (status: 'ITO', 'WFH', 'SIC', 'OOO', 'VAC', 'OOF').

Inputs: status (required), user_id (required), notes. Returns: result

admin_update_clientAdmin Update ClientB

Update a client record.

Undocumented route: PUT /clients/{id} is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. No documented equivalent was found.

Inputs: client_id (required), city, name, state, +4 more. Returns: result

admin_update_custom_fieldAdmin Update Custom FieldC

Update a custom field definition.

Inputs: custom_field_id (required), name, options. Returns: result

admin_update_disciplineAdmin Update DisciplineB

Update an existing discipline.

Undocumented route: PUT /disciplines/{id} is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. The reference documents only GET for disciplines.

Inputs: name (required), discipline_id (required). Returns: result

admin_update_expenseAdmin Update ExpenseC

Update a logged expense item.

Undocumented route: PUT /expenses/{id} is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. Documented route: PUT /users/{user_id}/expense_items/{expense_item_id}.

Inputs: expense_id (required), date, notes, amount, +1 more. Returns: result

admin_update_holidayAdmin Update HolidayB

Update a holiday.

Undocumented route: PUT /holidays/{id} is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. The reference documents only GET /holidays.

Inputs: holiday_id (required), date, name, end_date. Returns: result

admin_update_leave_typeAdmin Update Leave TypeA

Update a leave type name.

Undocumented route: PUT /leave_types/{id} is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. The reference documents only GET for leave types.

Inputs: name (required), leave_type_id (required). Returns: result

admin_update_roleAdmin Update RoleB

Update an existing role.

Undocumented route: PUT /roles/{id} is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. The reference documents only GET for roles.

Inputs: name (required), role_id (required). Returns: result

admin_update_userAdmin Update UserC

Update a user's profile, role, discipline, bill rate, or archive state.

Inputs: user_id (required), role, email, archived, +6 more. Returns: result

projects_bulk_delete_assignmentsProjects Bulk Delete AssignmentsA
Destructive

Bulk delete multiple resource assignments (Destructive: gated by SMARTSHEET_RM_ALLOW_BULK_DESTRUCTIVE=1 and confirm=True).

Inputs: assignment_ids (required), confirm. Returns: result

projects_clone_project_scheduleProjects Clone Project ScheduleB

Duplicate project budget settings, timeline, and phase milestone structure to a new project.

Inputs: source_project_id (required), target_project_name (required), client_id, new_start_date. Returns: result

projects_create_assignmentProjects Create AssignmentC

Create a resource assignment on a project or phase (dates: YYYY-MM-DD).

Inputs: user_id (required), end_date (required), project_id (required), start_date (required), +6 more. Returns: result

projects_create_assignment_subtaskProjects Create Assignment SubtaskC

Create a subtask under a project assignment.

Inputs: project_id (required), description (required), assignment_id (required), completed. Returns: result

projects_create_placeholder_resourceProjects Create Placeholder ResourceD

Create a placeholder resource.

Inputs: title (required), role, location, discipline. Returns: result

projects_create_projectProjects Create ProjectC

Create a new project in Smartsheet RM.

Inputs: name (required), budget, secure, end_date, +6 more. Returns: result

projects_create_project_assignmentProjects Create Project AssignmentB

Assign a user to a project on the documented route POST /projects/{project_id}/assignments (dates: YYYY-MM-DD).

Set allocation_mode and the matching value: percent (the reference documents it as a fraction from 0 to 1), hours_per_day, or fixed_hours for the fixed mode. allocation_mode is sent as given, because the reference names the fixed mode fixed in its description and fixed_hours in its schema. Percent mode is the default and requires percent; hours_per_day and the fixed mode require hours_per_day and fixed_hours. Without the matching value the call is refused before any request.

Inputs: user_id (required), end_date (required), project_id (required), start_date (required), +7 more. Returns: result

projects_create_project_phaseProjects Create Project PhaseC

Create a new phase under a project.

Inputs: name (required), end_date (required), project_id (required), start_date (required), +2 more. Returns: result

projects_create_user_assignmentProjects Create User AssignmentA

Assign a user to a project, phase or leave type on the documented route POST /users/{user_id}/assignments (dates: YYYY-MM-DD).

assignable_id is the project, phase or leave type ID. Set allocation_mode and the matching value: percent (the reference documents it as a fraction from 0 to 1), hours_per_day, or fixed_hours for the fixed mode. allocation_mode is sent as given, because the reference names the fixed mode fixed in its description and fixed_hours in its schema. Percent mode is the default and requires percent; hours_per_day and the fixed mode require hours_per_day and fixed_hours. Without the matching value the call is refused before any request.

Inputs: user_id (required), end_date (required), start_date (required), assignable_id (required), +7 more. Returns: result

projects_delete_assignmentProjects Delete AssignmentA
Destructive

Delete a resource assignment (Destructive: requires confirm=True).

Inputs: assignment_id (required), confirm. Returns: result

projects_delete_assignment_subtaskProjects Delete Assignment SubtaskB
Destructive

Delete an assignment subtask (Destructive: requires confirm=True).

Inputs: project_id (required), subtask_id (required), assignment_id (required), confirm. Returns: result

projects_delete_placeholder_resourceProjects Delete Placeholder ResourceB
Destructive

Delete a placeholder resource (Destructive: requires confirm=True).

Inputs: placeholder_id (required), confirm. Returns: result

projects_delete_projectProjects Delete ProjectA
Destructive

Delete a project (Destructive: requires confirm=True).

Inputs: project_id (required), confirm. Returns: result

projects_delete_project_phaseProjects Delete Project PhaseA
Destructive

Delete a project phase (Destructive: requires confirm=True).

Inputs: phase_id (required), project_id (required), confirm. Returns: result

projects_get_assignableProjects Get AssignableA
Read-onlyIdempotent

Fetch one assignable by ID (project or leave type).

OpenAPI: GET /assignables/{assignable_id} (getAssignablesId).

Inputs: assignable_id (required). Returns: result

projects_get_assignmentProjects Get AssignmentC
Read-onlyIdempotent

Get details for a specific assignment.

Inputs: assignment_id (required). Returns: result

projects_get_budget_itemProjects Get Budget ItemC
Read-onlyIdempotent

Fetch a budget item by ID.

OpenAPI: GET /budget_items/{budget_item_id} (getBudgetItem).

Inputs: budget_item_id (required). Returns: result

projects_get_projectProjects Get ProjectB
Read-onlyIdempotent

Get project details including budget, phases, client, and dates.

Inputs: project_id (required), with_phases. Returns: result

projects_get_project_budget_itemProjects Get Project Budget ItemC
Read-onlyIdempotent

Fetch a budget item under a project.

OpenAPI: GET /projects/{project_id}/budget_items/{budget_item_id} (getProjectBudgetItem).

Inputs: project_id (required), budget_item_id (required). Returns: result

projects_get_project_phaseProjects Get Project PhaseA
Read-onlyIdempotent

Get details for a specific project phase.

Undocumented route: GET /projects/{project_id}/phases/{phase_id} is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. The reference documents only PUT and DELETE on that path; GET /projects/{project_id}/phases lists phases.

Inputs: phase_id (required), project_id (required). Returns: result

projects_list_assignablesProjects List AssignablesA
Read-onlyIdempotent

List accessible assignables (projects and leave types).

OpenAPI: GET /assignables (getAssignables). Docs: https://developers.smartsheet.com/api/resource_management/openapi https://developers.smartsheet.com/_spec/api/resource_management/openapi.json

Inputs: page, per_page. Returns: result

projects_list_assignmentsProjects List AssignmentsC
Read-onlyIdempotent

List resource scheduling assignments across projects or filtered by user/project.

Inputs: page, to_date, user_id, per_page, +2 more. Returns: result

projects_list_assignment_subtasksProjects List Assignment SubtasksB
Read-onlyIdempotent

List subtasks (checklist tasks) for a project assignment.

Inputs: project_id (required), assignment_id (required). Returns: result

projects_list_placeholder_resourcesProjects List Placeholder ResourcesC
Read-onlyIdempotent

List placeholder resources used for forecasting and capacity modeling.

Inputs: page, per_page. Returns: result

projects_list_project_budget_itemsProjects List Project Budget ItemsA
Read-onlyIdempotent

List project/phase budget items of the given type.

OpenAPI: GET /projects/{project_id}/budget_items (getProjectBudgetItems). item_type is required (BudgetItemType: TimeFees, TimeFeesDays, or Expenses).

Inputs: item_type (required), project_id (required). Returns: result

projects_list_project_membersProjects List Project MembersA
Read-onlyIdempotent

List members of a project.

OpenAPI: GET /projects/{project_id}/project_members (getProjectsProjectIdProjectMembers). Optional membership filter: member, viewer, reporter, scheduler, or editor. When omitted, membership defaults to member; pass another level to list those.

Inputs: project_id (required), page, per_page, membership. Returns: result

projects_list_project_phasesProjects List Project PhasesC
Read-onlyIdempotent

List phases belonging to a project.

Inputs: project_id (required). Returns: result

projects_list_projectsProjects List ProjectsC
Read-onlyIdempotent

List projects in Smartsheet RM with filtering, phase inclusion, and pagination.

Inputs: page, archived, per_page, sort_field, +4 more. Returns: result

projects_list_project_usersProjects List Project UsersB
Read-onlyIdempotent

List users associated with or assigned to a specific project.

Inputs: project_id (required), page, per_page. Returns: result

projects_list_relationships_project_membersProjects List Relationships Project MembersA
Read-onlyIdempotent

List members for one or more projects (relationships endpoint).

OpenAPI: GET /relationships/project_members (getRelationshipsProjectMembers). Documented query params: membership, page, per_page. When omitted, membership defaults to member; pass another level to list those.

Inputs: page, per_page, membership. Returns: result

projects_list_relationships_project_membershipsProjects List Relationships Project MembershipsB
Read-onlyIdempotent

List project memberships for one or more users.

OpenAPI: GET /relationships/project_memberships (getRelationshipsProjectMemberships). user_ids is a comma-separated list of user IDs when provided. When omitted, membership defaults to member; pass another level to list those.

Inputs: page, per_page, user_ids, membership. Returns: result

projects_list_status_optionsProjects List Status OptionsA
Read-onlyIdempotent

List account-level assignment work status options.

Inputs: no named parameters. Returns: result

projects_list_user_project_membershipsProjects List User Project MembershipsA
Read-onlyIdempotent

List project memberships for a user.

OpenAPI: GET /users/{user_id}/project_memberships (getUsersUserIdProjectMemberships). Optional from / to are YYYY-MM-DD date filters (tool args from_date / to_date). When omitted, membership defaults to member; pass another level to list those.

Inputs: user_id (required), page, to_date, per_page, +2 more. Returns: result

projects_update_assignmentProjects Update AssignmentC

Update dates, allocation percentage, or hours on an existing assignment.

Inputs: assignment_id (required), note, percent, end_date, +3 more. Returns: result

projects_update_projectProjects Update ProjectC

Update project metadata, state, dates, budget or archive status.

Inputs: project_id (required), name, budget, archived, +5 more. Returns: result

projects_update_project_phaseProjects Update Project PhaseC

Update an existing project phase.

Inputs: phase_id (required), project_id (required), name, budget, +3 more. Returns: result

time_bulk_delete_time_entriesTime Bulk Delete Time EntriesA
Destructive

Bulk delete multiple time entries (Destructive: gated by SMARTSHEET_RM_ALLOW_BULK_DESTRUCTIVE=1 and confirm=True).

Undocumented route: DELETE /time_entries/{id} is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. Documented route: DELETE /users/{user_id}/time_entries/{id}.

Inputs: entry_ids (required), confirm. Returns: result

time_confirm_suggested_hoursTime Confirm Suggested HoursB

Auto-confirm all unconfirmed scheduled suggestions for a user within a date range.

Undocumented route: PUT /time_entries/{id} is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. Each suggestion is confirmed there. Documented route: PUT /users/{user_id}/time_entries/{id}.

Inputs: to_date (required), user_id (required), from_date (required). Returns: result

time_create_approvalTime Create ApprovalC

Submit or approve approvable records (approvable_type: 'time_entries' or 'expense_items').

Inputs: approvable_ids (required), approvable_type (required), notes, status. Returns: result

time_create_project_time_entryTime Create Project Time EntryA

Create a time entry on a project on the documented route POST /projects/{project_id}/time_entries.

date is YYYY-MM-DD. The body's assignable_id is project_id, which the reference says must match the URL; to log time to a phase or leave type, use time_create_user_time_entry. task, notes and bill_rate_id are optional; the reference limits task and notes to 256 characters.

Inputs: date (required), hours (required), user_id (required), project_id (required), +3 more. Returns: result

time_create_time_entryTime Create Time EntryA

Create a new time entry for a user on a project (date format: YYYY-MM-DD).

Undocumented route: POST /time_entries is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. Documented routes: POST /users/{user_id}/time_entries (time_create_user_time_entry) and POST /projects/{project_id}/time_entries (time_create_project_time_entry).

Inputs: date (required), hours (required), user_id (required), project_id (required), +4 more. Returns: result

time_create_user_time_entryTime Create User Time EntryA

Create a time entry for a user on the documented route POST /users/{user_id}/time_entries.

assignable_id is the project, phase or leave type ID; date is YYYY-MM-DD. task, notes and bill_rate_id are optional; the reference limits task and notes to 256 characters. The body repeats user_id, which the reference says must match the URL.

Inputs: date (required), hours (required), user_id (required), assignable_id (required), +3 more. Returns: result

time_delete_approvalTime Delete ApprovalA
Destructive

Delete a pending approval record (Destructive: requires confirm=True).

Inputs: approval_id (required), confirm. Returns: result

time_delete_time_entryTime Delete Time EntryA
Destructive

Delete a time entry (Destructive: requires confirm=True).

Undocumented route: DELETE /time_entries/{id} is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. Documented route: DELETE /users/{user_id}/time_entries/{id}.

Inputs: entry_id (required), confirm. Returns: result

time_fill_weekly_timesheetTime Fill Weekly TimesheetA

Batch-fill weekly timesheet entries (Mon-Fri 8h default, or 7-day with include_weekends=True) for a user.

start_date: Monday date of the week in YYYY-MM-DD. include_weekends: When True, logs Saturday and Sunday entries as well. weekend_hours: Specific hours for Saturday/Sunday (defaults to daily_hours if omitted).

Undocumented route: POST /time_entries is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. Each entry is created there. Documented route: POST /users/{user_id}/time_entries.

Inputs: user_id (required), start_date (required), notes, project_id, +3 more. Returns: result

time_get_time_entryTime Get Time EntryB
Read-onlyIdempotent

Get details for a specific time entry by its ID.

Inputs: entry_id (required). Returns: result

time_list_approvalsTime List ApprovalsB
Read-onlyIdempotent

List submitted time entry and expense approvals across the organization.

Inputs: page, per_page. Returns: result

time_list_project_time_entry_categoriesTime List Project Time Entry CategoriesB
Read-onlyIdempotent

List project/phase-specific time entry budget item categories.

OpenAPI: GET /projects/{project_id}/time_entry_categories (getProjectTimeEntryCategories). item_type is required by the published OpenAPI (query name item_type).

Inputs: item_type (required), project_id (required). Returns: result

time_list_time_entriesTime List Time EntriesB
Read-onlyIdempotent

List time entries across organization or filtered by project, user, or date range (YYYY-MM-DD).

Inputs: page, to_date, user_id, per_page, +3 more. Returns: result

time_list_time_entry_categoriesTime List Time Entry CategoriesA
Read-onlyIdempotent

List account-level time entry budget item categories (project-specific excluded).

OpenAPI: GET /time_entry_categories (getTimeBudgetItemCategories). Docs: https://developers.smartsheet.com/api/resource_management/openapi https://developers.smartsheet.com/_spec/api/resource_management/openapi.json

Inputs: page, per_page. Returns: result

time_list_user_suggestionsTime List User SuggestionsB
Read-onlyIdempotent

Read unconfirmed scheduled time suggestions for a user.

Inputs: user_id (required), to_date, from_date. Returns: result

time_lock_timesheetTime Lock TimesheetA
Idempotent

Lock or unlock timesheet records for a user up to a specified lock date (YYYY-MM-DD).

Undocumented route: POST /users/{user_id}/time_entries/lock is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. No documented equivalent was found.

Inputs: user_id (required), lock_date (required), unlock. Returns: result

time_reconcile_and_submit_weekTime Reconcile And Submit WeekA

Audit weekly logged hours against a target (40h) and optionally submit/approve timesheet.

Undocumented route: PUT /users/{user_id}/time_entries/approval_status is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. Only auto_submit=True calls it. No documented equivalent was found.

Inputs: user_id (required), start_date (required), auto_submit, target_hours. Returns: result

time_update_time_approval_statusTime Update Time Approval StatusB
Idempotent

Approve or reject time entries for a user (status: 'approved', 'rejected', 'pending').

Undocumented route: PUT /users/{user_id}/time_entries/approval_status is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. No documented equivalent was found.

Inputs: status (required), user_id (required), entry_ids (required), approver_notes. Returns: result

time_update_time_entryTime Update Time EntryC

Update an existing time entry.

Undocumented route: PUT /time_entries/{id} is not in Smartsheet's Resource Management API reference or the archived 10,000ft API docs, so Smartsheet may change or remove it without notice. Documented route: PUT /users/{user_id}/time_entries/{id}.

Inputs: entry_id (required), date, hours, notes, +1 more. Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    C2.5/5.0

    Scored across 115 tools

    Disambiguation2/5

    Several tool families overlap heavily: time_create_time_entry, time_create_user_time_entry, time_create_project_time_entry, and time_fill_weekly_timesheet all cover time-entry creation; projects_create_assignment, projects_create_project_assignment, projects_create_user_assignment, and projects_update_assignment cover assignment mutation. Approval-related tools also blur together, with time_create_approval, time_delete_approval, time_update_time_approval_status, and time_reconcile_and_submit_week addressing adjacent workflows.

    Naming Consistency4/5

    Names are overwhelmingly consistent snake_case with category prefixes (admin_, projects_, time_) and verb_noun structure. A few compound names are awkward or semantically ordered inconsistently, such as projects_list_relationships_project_members and projects_get_project_budget_item, but the pattern remains predictable.

    Tool Count1/5

    The server exposes 115 tools, far beyond any reasonable agent-facing tool set and well past the 50+ threshold for extreme count mismatch. Even though resource management is broad, the surface is too large to navigate without significant selection overhead.

    Completeness3/5

    Coverage is broad across projects, users, time entries, expenses, clients, roles, holidays, and custom fields, but important lifecycle gaps remain. Budget items are list/get only with no create/update/delete, and several admin resources such as client contacts and user bill rates lack full mutation coverage.

    Maintenance

    ActivityActive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers