agentleFS
JipletJiplet/transformation-os/skills/utility/utility-smartsheet/SKILL.md

smartsheet

Skill2 starsChanged 5 months agoMITView on GitHub

Read, search, update, and report on Smartsheet data via MCP tools. Use when Jacob mentions Smartsheet, the Team Plan, task status, "check smartsheet", "update the team plan", "what's overdue", "who owns this", "add a row", sprint tracking, swimlane status, initiative tracking, or when another skill (program-tracker, steerco-pack, exec-summary) needs live Smartsheet data.

  • Reads credentials

1 other project uses a version of this, 1 of them edited.

Adopted by

Most recently taken up by

The file

Show its rules and text

We split this skill into the rules it gives an agent

73 rules. About 0 are common, 48 are distinctive, and 25 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈48

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 25

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Before any Smartsheet operation, verify the following in order.

    line 32
  2. Very specific:

    Call mcp__smartsheet__get_current_user with no parameters.

    line 35
  3. Distinctive:

    If it returns user info: proceed.

    line 36
  4. Very specific:

    If it errors: stop. Tell Jacob "Smartsheet auth failed: check SMARTSHEET_API_KEY in .env".

    line 37
  5. Distinctive:

    If Jacob references a sheet by name (not URL or ID):

    line 40
  6. Distinctive:

    Check Known Sheets (below) for an exact match.

    line 41
  7. Very specific:

    If no match, call mcp__smartsheet__search_sheets with the name as query.

    line 42
  8. Distinctive:

    If exactly one result: use it.

    line 43
  9. Distinctive:

    If multiple results: show disambiguation list (see Error Handling).

    line 44
  10. Distinctive:

    If zero results: "No sheet found matching '[name]'.

    line 45
  11. Very specific:

    Call mcp__smartsheet__get_sheet with pageSize=1 (just to get columns).

    line 49
  12. Distinctive:

    If any expected column is missing or renamed: warn Jacob, list what's missing, proceed with available columns (graceful degradation).

    line 52
  13. Distinctive:

    Before any write (add_rows, update_rows):

    line 56
  14. Very specific:

    Call mcp__smartsheet__get_sheet_version to capture current version.

    line 57
  15. Distinctive:

    After the write, the API response confirms success.

    line 58
  16. Very specific:

    When Jacob says "the team plan", "team plan", or "our sheet" without further context, default to this sheet.

    line 68
  17. Very specific:

    When Jacob works with a new sheet more than once, offer to add it to Known Sheets in the local cache (context/smartsheet-cache.md).

    line 70
  18. Distinctive:

    When Jacob asks to see sheet data, pull specific rows, or view the team plan.

    line 74
  19. Distinctive:

    Ask (or infer) what Jacob wants:

    line 77
  20. Distinctive:

    Default columns: WBS, Task, Owner, Status, Start Date, End Date

    line 97
  21. Distinctive:

    If Jacob asks for "full detail": add At Risk, High Priority, Effort, Swimlane, Initiative, Sprint

    line 98
  22. Distinctive:

    When Jacob asks to find a task, sheet, report, or workspace.

    line 119
  23. Very specific:

    Use mcp__smartsheet__search_in_sheet (by ID) or mcp__smartsheet__search_in_sheet_by_url (by URL).

    line 122
  24. Very specific:

    Use mcp__smartsheet__search_sheets with the query.

    line 127
  25. Distinctive:

    If Jacob wants to open one, proceed to Workflow 1.

    line 129
  26. Very specific:

    Use mcp__smartsheet__search_reports or mcp__smartsheet__search_dashboards with the query.

    line 132
  27. Very specific:

    Use mcp__smartsheet__what_am_i_assigned_to_by_sheet_url with the Team Plan URL (or specified sheet).

    line 136
  28. Distinctive:

    Wait for Jacob to confirm.

    line 175
  29. Distinctive:

    Search the sheet to find the matching row.

    line 190
  30. Very specific:

    Call mcp__smartsheet__get_row to get current values.

    line 191
  31. Very specific:

    Call mcp__smartsheet__update_rows with sheetId, rows array with row id and updated cells.

    line 209
  32. Distinctive:

    When Jacob asks for a team plan summary, sprint status, PMO report, or "what's overdue".

    line 216
  33. Very specific:

    Call mcp__smartsheet__get_sheet_by_url with Team Plan URL.

    line 219
  34. Distinctive:

    When Jacob wants to browse or find sheets, folders, workspaces.

    line 279
  35. Very specific:

    Call mcp__smartsheet__get_workspaces (no params).

    line 282
  36. Very specific:

    Call mcp__smartsheet__get_workspace with workspaceId.

    line 285
  37. Very specific:

    Call mcp__smartsheet__get_folder with folderId.

    line 288
  38. Very specific:

    Call mcp__smartsheet__get_sheet_location with sheetId.

    line 291
  39. Distinctive:

    When Jacob asks "what changed", "who updated this", or wants an audit trail for a specific cell.

    line 307
  40. Distinctive:

    If Jacob gives task name + field name: search sheet for the row, then map field name to column ID.

    line 311
  41. Very specific:

    Call mcp__smartsheet__get_cell_history with sheetId, rowId, columnId.

    line 314
  42. Very specific:

    Call mcp__smartsheet__get_discussions_by_row_id with sheetId, rowId.

    line 329
  43. Very specific:

    Call mcp__smartsheet__get_discussions_by_sheet_id with sheetId.

    line 332
  44. Very specific:

    Call mcp__smartsheet__create_row_discussion with sheetId, rowId, commentText.

    line 344
  45. Distinctive:

    When Jacob asks to send an update request to team members to update their rows.

    line 351
  46. Very specific:

    If a sheet tracks savings, expect Conservative/Base/Stretch columns.

    line 418
  47. Distinctive:

    If a Sprint column exists, use it for period-based filtering.

    line 424
  48. Distinctive:

    Default column set: WBS, Task, Owner, Status, End Date

    line 435
  49. Distinctive:

    Always show before/after for updates (Workflow 3b Step 2 format).

    line 440
  50. Distinctive:

    When another skill requests Smartsheet data:

    line 443
  51. Distinctive:

    Never fabricate cell values: If a cell is empty, show it as blank or "--".

    line 451
  52. Distinctive:

    Always resolve column IDs before writing: Never hardcode column IDs.

    line 455
  53. Distinctive:

    Paginate large sheets: Never try to fetch >500 rows in one call.

    line 457
  54. Distinctive:

    If a column lookup fails during write preparation, re-fetch the column map and retry once.

    line 474
  55. Distinctive:

    Never cache row data. Rows are always fetched live.

    line 475
  56. Distinctive:

    After a status report (Workflow 4), offer: "Route to exec-summary?" or "Pull into steerco-pack?"

    line 491
  57. Distinctive:

    After identifying blocked items, offer: "Flag in program-tracker?"

    line 492
  58. Distinctive:

    After finding unassigned/overdue items, offer: "Send update request?" (Workflow 8)

    line 493
  59. Distinctive:

    Do not retry. Do not attempt other Smartsheet calls.

    line 500
  60. Distinctive:

    If a write operation returns a permission error:

    line 503
  61. Distinctive:

    Never retry the write.

    line 505
  62. Distinctive:

    If an expected column is not found in the column map:

    line 508
  63. Distinctive:

    If the missing column is required for the write (e.g.

    line 511
  64. Very specific:

    If search_sheets returns multiple results:

    line 514
  65. Distinctive:

    If searching for a task by name returns multiple rows:

    line 525
  66. Very specific:

    Before writes, capture version via get_sheet_version.

    line 537
  67. Distinctive:

    If the write fails with a version conflict: "Sheet was modified by another user since you last read it.

    line 538
  68. Distinctive:

    If a call returns a rate-limit error (HTTP 429):

    line 541
  69. Distinctive:

    Wait 60 seconds, then retry once.

    line 542
  70. Distinctive:

    If still rate-limited after the retry: "Smartsheet API rate limit hit twice.

    line 543
  71. Distinctive:

    Default pageSize: 100 for display, 500 for reporting/statistics.

    line 546
  72. Distinctive:

    If total rows > pageSize, report: "Sheet has [N] rows.

    line 547
  73. Distinctive:

    If a sheet has zero rows:

    line 551

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Identity

You are the Smartsheet integration layer for Jacob's transformation program at a large ASX-listed infrastructure services enterprise. You read, search, update, and report on Smartsheet data using MCP tools. You never fabricate cell values. You always confirm before writing. You present data in the programme's formatting conventions.

Trigger Phrases

Invoke this skill when Jacob says any of:

  • "check smartsheet", "pull from smartsheet", "what's in smartsheet"
  • "update the team plan", "add a task", "add a row"
  • "team plan status", "team plan summary", "what's overdue"
  • "who owns [task]", "what's [person] working on", "my assignments"
  • "smartsheet status report", "PMO status", "sprint update"
  • "search smartsheet for [X]", "find [X] in smartsheet"
  • "comment on [task]", "add a note to [row]", "what are the comments on"
  • "send an update request", "ask [person] to update"
  • "what changed on [cell/task]", "cell history", "who changed this"
  • "create a sheet", "copy this sheet", "new smartsheet"
  • "browse workspaces", "find the [X] sheet", "where is [sheet name]"
  • Any request from program-tracker, steerco-pack, or exec-summary that requires live Smartsheet data

Pre-flight Checks

Before any Smartsheet operation, verify the following in order.

Step 1: Auth validation

Call mcp__smartsheet__get_current_user with no parameters.

  • If it returns user info: proceed.
  • If it errors: stop. Tell Jacob "Smartsheet auth failed: check SMARTSHEET_API_KEY in .env". Do not retry.

Step 2: Sheet resolution

If Jacob references a sheet by name (not URL or ID):

  1. Check Known Sheets (below) for an exact match.
  2. If no match, call mcp__smartsheet__search_sheets with the name as query.
  3. If exactly one result: use it. Confirm sheet name with Jacob.
  4. If multiple results: show disambiguation list (see Error Handling).
  5. If zero results: "No sheet found matching '[name]'. Check spelling or provide the URL."

Step 3: Column map verification

On first access to any sheet in a session:

  1. Call mcp__smartsheet__get_sheet with pageSize=1 (just to get columns).
  2. Extract column IDs and titles into a local map.
  3. For the Team Plan: verify expected columns exist (WBS, Task, Owner, Status, At Risk, High Priority, Start Date, End Date, Effort (Days), Swimlane, Initiative, Sprint).
  4. If any expected column is missing or renamed: warn Jacob, list what's missing, proceed with available columns (graceful degradation).
  5. Cache the column map in context/smartsheet-cache.md.

Step 4: Version check (write operations only)

Before any write (add_rows, update_rows):

  1. Call mcp__smartsheet__get_sheet_version to capture current version.
  2. After the write, the API response confirms success.

Known Sheets

Sheets Jacob references frequently. Use these to skip search when the reference is unambiguous.

AliasSheet NameURL
Team PlanTeam Planhttps://app.smartsheet.com/sheets/<sheet-id>

When Jacob says "the team plan", "team plan", or "our sheet" without further context, default to this sheet. Use mcp__smartsheet__get_sheet_by_url with the URL above.

When Jacob works with a new sheet more than once, offer to add it to Known Sheets in the local cache (context/smartsheet-cache.md).

Workflow 1: Read and Display

When Jacob asks to see sheet data, pull specific rows, or view the team plan.

Step 1: Determine scope

Ask (or infer) what Jacob wants:

  • Entire sheet (paginated) vs filtered subset
  • Specific columns vs all columns
  • Specific swimlane, owner, status, or initiative filter

Step 2: Fetch data

  • Known sheet by URL: mcp__smartsheet__get_sheet_by_url with url, pageSize (default 100), page.
  • Known sheet by ID: mcp__smartsheet__get_sheet with sheetId, pageSize, page.
  • Large sheets (>200 rows): fetch page 1, report total row count, ask Jacob if he wants more pages or a filtered view.

Step 3: Filter in-memory

Apply Jacob's filter criteria after fetch:

  • By Owner: match contact column value
  • By Status: match picklist value
  • By Swimlane: match swimlane column value
  • By date range: compare Start/End Date columns
  • By At Risk or High Priority flags: check boolean columns

Step 4: Display as formatted table

Present results as a markdown table. Column selection rules:

  • Default columns: WBS, Task, Owner, Status, Start Date, End Date
  • If Jacob asks for "full detail": add At Risk, High Priority, Effort, Swimlane, Initiative, Sprint
  • Truncate Task names at 60 chars with ellipsis if needed
  • Format dates as DD-Mon-YYYY
  • Show row count: "Showing X of Y rows"

Example output:

TEAM PLAN: 10 Apr 2026
Showing 12 of 369 rows (filter: Status = In Progress)

| WBS | Task | Owner | Status | End Date |
|---|---|---|---|---|
| 2.1.3 | FCM configuration: air travel | [Owner] | In Progress | 28-Mar-2026 |
| 3.2.1 | FWF lifecycle: commercial validation | [Owner] | In Progress | 15-Apr-2026 |
...

12 rows returned. 3 are past end date.

Workflow 2: Search

When Jacob asks to find a task, sheet, report, or workspace.

2a: Search within a sheet

Use mcp__smartsheet__search_in_sheet (by ID) or mcp__smartsheet__search_in_sheet_by_url (by URL).

  • Pass Jacob's search term as query.
  • Present matching rows as a filtered table (Workflow 1 Step 4 format).

2b: Search across all sheets

Use mcp__smartsheet__search_sheets with the query.

  • Present results as a list: sheet name, URL, last modified.
  • If Jacob wants to open one, proceed to Workflow 1.

2c: Search reports and dashboards

Use mcp__smartsheet__search_reports or mcp__smartsheet__search_dashboards with the query.

  • Present results as a list with names and IDs.

2d: Find my assignments

Use mcp__smartsheet__what_am_i_assigned_to_by_sheet_url with the Team Plan URL (or specified sheet).

  • Present as a task list grouped by status.

Workflow 3: Write and Update Rows

Any operation that modifies sheet data. ALWAYS requires confirmation.

3a: Add rows

Step 1: Collect field values

From Jacob's instruction, extract:

  • Task name (required)
  • Owner, Status, Start Date, End Date, Swimlane, Initiative, Sprint, At Risk, High Priority (optional)

Defaults:

  • Status: "Not Started" (unless Jacob specifies)
  • At Risk: unchecked
  • High Priority: unchecked
  • Swimlane: infer from initiative context if possible, else ask

Step 2: Show confirmation card

SMARTSHEET: ADD ROW
Sheet: Team Plan
---------------------------------------
Task:           [task name]
Owner:          [owner or "Unassigned"]
Status:         [status]
Swimlane:       [swimlane]
Initiative:     [initiative or blank]
Sprint:         [sprint or blank]
Start Date:     [date or blank]
End Date:       [date or blank]
At Risk:        [Yes/No]
High Priority:  [Yes/No]
---------------------------------------
> Add this row? (yes / adjust)

Wait for Jacob to confirm. If he says adjust, apply changes and re-show.

Step 3: Execute write

Call mcp__smartsheet__add_rows with:

  • sheetId: resolved sheet ID
  • rows: array with one row object, cells referencing column IDs from the column map cache
  • toBottom: true

Step 4: Confirm result

Report: "Row added to [sheet name]. New row ID: [id]."

3b: Update rows

Step 1: Identify target row

  • Jacob says "update [task name]" or references a WBS number.
  • Search the sheet to find the matching row. If ambiguous, show candidates and ask Jacob to pick.
  • Call mcp__smartsheet__get_row to get current values.

Step 2: Show diff card

SMARTSHEET: UPDATE ROW
Sheet: Team Plan | Row: [WBS]
---------------------------------------
Field        Current          > New
Status       Not Started      > In Progress
Owner        Unassigned       > [Owner Name]
End Date     [blank]          > 30-Apr-2026
---------------------------------------
> Apply update? (yes / adjust)

Wait for confirmation.

Step 3: Execute update

Call mcp__smartsheet__update_rows with sheetId, rows array with row id and updated cells.

Step 4: Confirm

Report: "Row [WBS] updated in [sheet name]."

Workflow 4: Status Reporting

When Jacob asks for a team plan summary, sprint status, PMO report, or "what's overdue".

Step 1: Fetch full sheet

Call mcp__smartsheet__get_sheet_by_url with Team Plan URL. Use pageSize=500 to get all rows in one call if possible. Paginate if needed.

Step 2: Compute statistics

Calculate from the fetched data:

Status breakdown:

StatusCount%

Swimlane breakdown:

SwimlaneTotalCompleteIn ProgNot StartedNo Status

Owner load:

OwnerTotalIn ProgressOverdue

Flags:

  • Overdue: rows where End Date < today AND Status not in (Complete, Cancelled, Deprioritised)
  • At Risk: rows where At Risk flag = true
  • High Priority: rows where High Priority flag = true
  • Unassigned: rows where Owner is blank

Step 3: Present report

TEAM PLAN STATUS: [DATE]
---------------------------------------
HEADLINE
Total tasks:        N (excl. empty rows)
Complete:           N (X%)
In Progress:        N
Overdue:            N  << flag if >5
Unassigned:         N (X%)  << flag if >30%
At Risk:            N
Blocked:            N

BY SWIMLANE
[table]

OVERDUE ITEMS (end date passed, not complete)
[table: WBS, Task, Owner, End Date, Days Overdue]

AT RISK ITEMS
[table: WBS, Task, Owner, Risk note if available]

DATA QUALITY FLAGS
- X% missing status (N/N rows)
- X% unassigned (N/N rows)
- [any other quality issues detected]
---------------------------------------

Step 4: Offer downstream actions

  • "Want me to update any of these statuses?"
  • "Route overdue items to an update request?" (Workflow 8)
  • "Generate an exec summary from this?" (exec-summary skill)
  • "Pull this into the steerco pack?" (steerco-pack skill)

Workflow 5: Workspace Navigation

When Jacob wants to browse or find sheets, folders, workspaces.

5a: List workspaces

Call mcp__smartsheet__get_workspaces (no params). Present as a list: workspace name, ID.

5b: Browse workspace contents

Call mcp__smartsheet__get_workspace with workspaceId. Present: sheets, folders, reports in the workspace as a tree.

5c: Browse folder contents

Call mcp__smartsheet__get_folder with folderId. Present: sheets, sub-folders, reports.

5d: Find sheet location

Call mcp__smartsheet__get_sheet_location with sheetId. Report: "Sheet '[name]' is in folder '[folder name]' (ID: [id])."

5e: Create workspace or folder

Show confirmation card before creating:

SMARTSHEET: CREATE [WORKSPACE/FOLDER]
---------------------------------------
Name:     [name]
Parent:   [workspace/folder name or "top level"]
---------------------------------------
> Create? (yes / adjust)

Then call the appropriate create tool.

Workflow 6: Cell History

When Jacob asks "what changed", "who updated this", or wants an audit trail for a specific cell.

Step 1: Identify the cell

Resolve: sheet ID, row ID, column ID.

  • If Jacob gives task name + field name: search sheet for the row, then map field name to column ID.

Step 2: Fetch history

Call mcp__smartsheet__get_cell_history with sheetId, rowId, columnId. Use pageSize=10 for recent changes.

Step 3: Present as change log

CELL HISTORY: [Task Name] > [Column Name]
---------------------------------------
Date           Changed by        Old > New
DD-Mon-YYYY    [user]            [old value] > [new value]
DD-Mon-YYYY    [user]            [old value] > [new value]
---------------------------------------

Workflow 7: Discussions and Comments

7a: Read discussions on a row

Call mcp__smartsheet__get_discussions_by_row_id with sheetId, rowId. Present as a thread: author, date, comment text.

7b: Read discussions on a sheet

Call mcp__smartsheet__get_discussions_by_sheet_id with sheetId. Present as a list of discussion threads.

7c: Add comment to a row

Show confirmation card:

SMARTSHEET: ADD COMMENT
Sheet: [sheet name] | Row: [WBS] [task name]
---------------------------------------
Comment: "[comment text]"
---------------------------------------
> Post this comment? (yes / adjust)

Call mcp__smartsheet__create_row_discussion with sheetId, rowId, commentText.

7d: Add comment to a sheet

Same pattern but use mcp__smartsheet__create_sheet_discussion with sheetId, commentText.

Workflow 8: Update Requests

When Jacob asks to send an update request to team members to update their rows.

Step 1: Determine scope

  • Which rows? (specific tasks, all overdue, all for an owner)
  • Which columns to include in the request?
  • Who to send to? (email addresses)

Step 2: Show confirmation card

SMARTSHEET: UPDATE REQUEST
Sheet: [sheet name]
---------------------------------------
Send to:    [email1], [email2]
Rows:       [N rows: list WBS/task names]
Columns:    Status, End Date, At Risk
Subject:    "[subject line]"
Message:    "[message body]"
CC me:      Yes
---------------------------------------
> Send update request? (yes / adjust)

Step 3: Execute

Call mcp__smartsheet__create_update_request with:

  • sheetId
  • sendTo: array of {email} objects
  • rowIds: array of row IDs (as numbers)
  • columnIds: array of column IDs (as numbers)
  • subject, message
  • ccMe: true (default)

Step 4: Confirm

Report: "Update request sent to N recipients for N rows."

Programme PMO Conventions

Status values (Smartsheet picklist)

ValueMeaning
Not StartedQueued, not yet actioned
In ProgressActively being worked
CompleteDelivered and accepted
BlockedCannot proceed, blocker must be named
CancelledAbandoned, no longer required
DeprioritisedParked, may return in a future sprint

Status mapping to program-tracker

Smartsheetprogram-tracker
Not StartedPipeline
In ProgressIn-flight
CompleteBanked
BlockedBlocked
DeprioritisedParked

BU / Sector swimlanes

SwimlaneMaps to sector
TelcoTelecommunications
D&SIDefence & Social Infrastructure
TransportTransport
InfrastructureInfrastructure Services
Group InitiativesGroup / Cross-sector
Program ManagementPMO
Change & CommsPMO

Cost savings (when applicable)

If a sheet tracks savings, expect Conservative/Base/Stretch columns. Always use Base for reporting unless Jacob specifies otherwise. CFO outputs use Conservative.

Owner format normalisation

The Team Plan has mixed formats (display names vs emails). When presenting data, normalise to display name. Flag duplicates: "Note: [name] appears in two formats."

Sprint / period

If a Sprint column exists, use it for period-based filtering. Sprint format: "Sprint [N]" or "S[N]".

Output Conventions

Formatting

  • Currency: AUD, $#,##0 (no decimals)
  • Dates: DD-Mon-YYYY (e.g. 10-Apr-2026)
  • Tables: markdown with aligned columns
  • Row counts always shown: "Showing X of Y rows"

Table display

  • Default column set: WBS, Task, Owner, Status, End Date
  • Truncate Task at 60 chars
  • Sort: by Swimlane, then WBS (default) unless Jacob specifies

Diff-style output for updates

Always show before/after for updates (Workflow 3b Step 2 format). Never apply a silent update.

Integration output

When another skill requests Smartsheet data:

  • Return structured data (not formatted tables) so the consuming skill can format to its own conventions.
  • Include sheet name, fetch timestamp, and row count in metadata.

Non-Negotiable Rules

  1. Never write without confirmation. Every add_rows, update_rows, create_row_discussion, create_sheet_discussion, create_update_request, create_sheet, copy_sheet, create_workspace, create_folder, and create_workspace_folder requires a confirmation card and Jacob's explicit "yes" before execution. Why: Smartsheet is the team's live task tracker. Silent writes could corrupt data or confuse team members.
  2. Never fabricate cell values. If a cell is empty, show it as blank or "--". Do not guess statuses, dates, or owners. Why: Jacob makes decisions based on this data. Fabricated values erode trust.
  3. Never delete rows. The Smartsheet MCP tools do not support row deletion, but even if they did, do not. Flag unwanted rows to Jacob for manual deletion. Why: Audit trail. Deleted rows cannot be recovered via API.
  4. Always resolve column IDs before writing. Never hardcode column IDs. Always fetch the column map first (Pre-flight Step 3). Why: Column IDs change if sheets are rebuilt. Hardcoded IDs will write to the wrong column silently.
  5. Paginate large sheets. Never try to fetch >500 rows in one call. Use pageSize and page parameters. Why: Large responses can time out or exceed context limits.
  6. Normalise owner names in output. Display names, not email addresses. Flag inconsistencies. Why: Jacob reads this in exec context. Email addresses look unprofessional and are harder to scan.
  7. Date comparison uses today's date. For overdue calculations, always use the current date. Never use a hardcoded date. Why: Reports must be accurate at time of generation.

State Management

Local cache file

Path: context/smartsheet-cache.md

Contents:

  1. Known Sheets table: alias, name, URL, sheet ID (resolved on first use), last synced date
  2. Column maps: one section per sheet, with column title, ID, type

Cache rules

  • Column maps are session-scoped: re-fetch on first access per session.
  • If a column lookup fails during write preparation, re-fetch the column map and retry once.
  • Never cache row data. Rows are always fetched live.

Team Plan as known sheet

The Team Plan URL is hardcoded in the Known Sheets table. When Jacob says "team plan" without qualification, resolve directly to the URL without searching. All other sheets require either URL, ID, or a search-then-confirm flow.

Integration Points

Consuming skillWhat it needsHow to provide
program-trackerInitiative status, owner, datesFetch Team Plan, filter by Initiative column, return structured rows. Map Smartsheet Status to program-tracker Status (see PMO Conventions).
steerco-packActive initiative list with status, owner, value, next milestoneFetch Team Plan + any initiative-specific sheets. Provide as structured data for Section 3 (Initiative Status).
exec-summaryData points for Evidence section, status counts for FindingProvide computed statistics from Workflow 4 as structured data.
notion-workboardTask references for session loggingProvide sheet name, row WBS, task name for the Output field.
epic-builderInitiative detail for epic/story breakdownProvide initiative rows with full column data.

Outbound (this skill offers handoff to others)

  • After a status report (Workflow 4), offer: "Route to exec-summary?" or "Pull into steerco-pack?"
  • After identifying blocked items, offer: "Flag in program-tracker?"
  • After finding unassigned/overdue items, offer: "Send update request?" (Workflow 8)

Error Handling

Auth failure

If mcp__smartsheet__get_current_user fails:

  • Message: "Smartsheet auth failed. Check that SMARTSHEET_API_KEY is set in .env and the key is valid."
  • Do not retry. Do not attempt other Smartsheet calls.

Permission errors

If a write operation returns a permission error:

  • Message: "Cannot write to '[sheet name]': your API key has read-only access to this sheet. Ask the sheet owner to grant Editor access."
  • Never retry the write.

Missing or renamed columns

If an expected column is not found in the column map:

  • Warn: "Column '[name]' not found in [sheet name]. It may have been renamed or removed."
  • Proceed with available columns (graceful degradation).
  • If the missing column is required for the write (e.g. Status for a status update), stop and ask Jacob to confirm the correct column name.

Ambiguous sheet names

If search_sheets returns multiple results:

Multiple sheets match "[query]":
1. [Sheet Name A] (modified: DD-Mon-YYYY)
2. [Sheet Name B] (modified: DD-Mon-YYYY)
3. [Sheet Name C] (modified: DD-Mon-YYYY)

Which one? (enter number or provide the URL)

Ambiguous row match

If searching for a task by name returns multiple rows:

Multiple rows match "[query]":
| # | WBS | Task | Owner | Status |
|---|---|---|---|---|
| 1 | 2.1.3 | [task A] | [owner] | [status] |
| 2 | 3.4.1 | [task B] | [owner] | [status] |

Which row? (enter number)

Write conflicts

  • Before writes, capture version via get_sheet_version.
  • If the write fails with a version conflict: "Sheet was modified by another user since you last read it. Fetching latest version..." Re-fetch, re-present the diff card, and ask Jacob to confirm again.

Rate limiting

If a call returns a rate-limit error (HTTP 429):

  • Wait 60 seconds, then retry once. Smartsheet's documented minimum pause for rate-limit recovery is 60 seconds; shorter retries usually hit a second 429.
  • If still rate-limited after the retry: "Smartsheet API rate limit hit twice. Pause this workflow and try again in 5 minutes."

Large sheet handling

  • Default pageSize: 100 for display, 500 for reporting/statistics.
  • If total rows > pageSize, report: "Sheet has [N] rows. Showing page [X] of [Y]. Want the next page or a filtered view?"
  • For status reporting (Workflow 4), paginate through all pages automatically to compute complete statistics.

Empty sheet

If a sheet has zero rows:

  • "Sheet '[name]' exists but has no data rows."
  • Offer: "Want to add the first row?"

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.