CTDS Spreadsheet Apps
The arithmetic behind Sheets templates for small trades, offered to AI assistants as 8 tools over the Model Context Protocol.
The vertical spreadsheet apps (Job-Cost Tracker, Equipment Hours & Service Log, Bid Tracker, Turnover & Revenue Board): their specs and SKUs, a validator for specs, a Sheets formula evaluator, and the reference models that compute what each workbook's dashboard shows from rows you pass in. The server reads no Google Sheet and holds no data: give it the rows. Amounts are plain dollars (not cents) and rates are fractions (0.2 = 20 %), as the workbooks hold them; dates are YYYY-MM-DD and dashboards take an optional today. Results are bookkeeping arithmetic on the caller's numbers, not tax or accounting advice.
Connect
The server is at https://chimneytopdigital.com/api/mcp/sheets. It is free, asks for no sign-in and keeps nothing between calls. Rate limits apply per address.
| Client | How |
|---|---|
| Claude Code | One command in a terminal: |
| Claude (web and desktop apps) | Settings → Connectors → Add custom connector, with the URL https://chimneytopdigital.com/api/mcp/sheets. No sign-in is asked for. |
| Codex CLI | One command in a terminal: |
| Any other MCP client | Use the Streamable HTTP transport with the URL https://chimneytopdigital.com/api/mcp/sheets: one JSON-RPC message per POST, JSON answers, no session and no authentication. |
To see the raw protocol, list the tools and call one from a terminal:
curl -s https://chimneytopdigital.com/api/mcp/sheets -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
curl -s https://chimneytopdigital.com/api/mcp/sheets -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"list_workbooks","arguments":{}}}'Tools
Every tool is read-only and idempotent, so a client may run it without asking you first. Arguments are checked before a tool runs; a wrong one comes back as a message naming the field.
list_workbooksList workbooks and SKUsThe spreadsheet products: every SKU in the catalog (name, vertical, core job, Pro automation, prices, status, version) and the compiled workbook specs behind them (id, name, version, vertical, summary, Pro features, sheet names). Gated workbooks, not for sale yet, are listed only when asked.
include_gated(boolean, default false): Also list workbooks kept out of the store until the owner approves them
describe_workbookDescribe a workbookThe compiled spec of one workbook: each sheet with its role and purpose, a table sheet's columns (key, header, type, input or formula, validation, help) and a grid sheet's cell count, plus the named ranges. Use it to tell a user what to enter where, or what a column computes.
id(job-cost-tracker | equipment-hours-log | turnover-revenue-board | bid-tracker | virtual-golf-league, required): The workbook id
validate_workbook_specValidate a workbook specChecks a compiled workbook spec (JSON) the way the build does: the schema first, then the semantic rules (standard tabs in order, a Help tab, formulas that parse and use only verified built-in functions, known named ranges and sheets, validations on inputs, brand-only URLs, phone usability). Returns every issue found; an empty list means it passes.
spec(object, required): The spec object, as describe_workbook shows one or as templates compile it
evaluate_formulaEvaluate a Sheets formulaEvaluates a Google Sheets formula with the repository's evaluator (the subset of functions the templates use: SUM, SUMIFS, IF, INDEX/MATCH, TODAY, date arithmetic and so on) against cell values you give, so a formula can be checked without a spreadsheet. Cell values that start with "=" are formulas themselves; dates are returned as serial numbers, with the ISO date alongside when the result looks like one. One call may read at most 100,000 cells across its ranges.
formula(string, required): The formula, with or without the leading =cells(object, default {}): Cell contents by A1 reference on the sheet (for example {"A1": 10, "B1": "=A1*2"})sheet(string, default "Sheet1"): The sheet the formula and cells live ontoday(string): What TODAY() returns; defaults to today (YYYY-MM-DD)
job_cost_resultJob-Cost Tracker: estimate vs actualThe Job-Cost Tracker's numbers for a set of jobs and cost-log entries: per job the estimate and actual by category (labor, fuel, materials with tax, equipment), hours, variance and flag (Not started, On track, Over budget), and the dashboard totals. Rates come from the settings unless a line gives its own.
settings(object, required): The Settings tabjobs(array, required): The Inputs tabentries(array, required): The Cost Log tab
equipment_dashboardEquipment Hours & Service Log: service due and cost per hourThe Equipment Hours & Service Log's numbers for a fleet: per machine the current hours, last and next service (by hours or by date, whichever comes first), hours and days remaining, status (OK, Due soon, Overdue), fuel and service cost, hours used and cost per hour including ownership; and the fleet dashboard.
settings(object, required): The Settings tabmachines(array, required): The Machines tabhours(array, required): The Hours Log tabservices(array, required): The Service Log tabtoday(string): The date the dashboard is for; defaults to today (YYYY-MM-DD)
bid_dashboardBid Tracker: prices, margins, win rateThe Bid Tracker's numbers for a list of bids: per bid the price from cost and markup, the margin and margin percent, days open for a sent bid and whether a follow-up is due; and the dashboard (open, won, lost, win rate, pipeline value, won value and margin, follow-ups).
settings(object, required): The Settings tabbids(array, required): The Bids tabtoday(string): The date the dashboard is for; defaults to today (YYYY-MM-DD)
turnover_dashboardTurnover & Revenue Board: cleaning schedule, occupancy, netThe Turnover & Revenue Board's numbers for up to ten rental units: the cleaning schedule from the bookings (check-out day, next arrival, same-day or next-day priority), per unit the year's nights, occupancy, revenue net of fees and tax, expenses including cleaning, and net by month; and the board totals with the turnovers due in the next seven days.
settings(object, required): The Settings tabunits(array, required): The Units tab (the board shows the first ten)bookings(array, required): The Bookings tabexpenses(array, required): The Expenses tabtoday(string): The date the dashboard is for; defaults to today (YYYY-MM-DD)
Limits
- The tools compute from the values the assistant passes in. They cannot read or change anything in your Sheets templates for small trades account; for that, use the app.
- Results carry the same notices the app shows. They are estimates and working aids, not professional advice; ask your assistant to show the notice with the figure.
- Rate limits apply per address. A request over the limit gets a plain error the assistant can read.
- The tool list may grow. This page is generated from the running server, so it shows the tools as they are today.
If something fails
- "Couldn't reach the MCP server", or a 404
- Check the address character by character: the server answers only at
https://chimneytopdigital.com/api/mcp/sheets, over HTTPS. Nothing else on this host speaks MCP. - 405 Method Not Allowed
- The client sent a GET. The server speaks the Streamable HTTP transport without an event stream: one JSON-RPC message per POST, a JSON answer, no session. A notification gets an empty 202.
- 429 Too Many Requests
- Your address passed the fair-use limit. The
Retry-Afterheader says how many seconds to wait; the limit resets on its own. - 413 Payload Too Large
- One request may carry 256 KiB. Send fewer rows per call, or summarize before you send.
- A tool answers with an error naming a field
- The argument did not match the tool's schema above: money is integer cents (or plain dollars where the tool says so), dates are
YYYY-MM-DD, and lists are JSON arrays. Fix the named field and call again; nothing was stored. - Still stuck
- Write to support@chimneytopdigital.com with the tool name, the arguments you sent (with nothing personal in them), the time in UTC and the exact message. We keep no record of calls, so what you send us is all we can look at.
How we built the servers, and the rules every one follows: our guide. Questions: hello@chimneytopdigital.com.