Product Requirements Document
cld-ext — Claude for Sheets
PRD: cld-ext — Claude for Sheets
Version: 1.0 Date: 2026-06-25 Status: Draft Owner: Zync-code
Executive Summary
cld-ext ("Claude for Sheets") is a Google Sheets editor add-on that puts Claude directly inside the spreadsheet. Users authorize the add-on with their own Anthropic API key, open a sidebar, and chat with Claude using their spreadsheet data as context — selecting ranges to feed in as context, asking Claude to analyze, transform, or generate data, and letting Claude write the result straight back into cells, add cell comments, or create/edit whole tabs. Two operating modes are supported: Suggest mode (Claude proposes a change, user clicks Apply) and Autonomous mode (Claude writes directly, no confirmation step) — both togglable per session or per request.
The add-on ships with a public landing page at cld-ext.dibly.me, which doubles as documentation, install guide, and (eventually) the Privacy Policy / Terms of Service required for Google Workspace Marketplace listing. This PRD itself is published on that landing page.
Target users: Power users of Google Sheets who already use Claude and want it without context-switching to a separate tab/app. Business model: Free, BYOK (bring-your-own-key) — user pays Anthropic directly for their own usage. No backend billing. Distribution: Personal/private use first (test deployment), with the architecture and compliance groundwork laid so it can later go through Google Workspace Marketplace review without a rebuild.
Problem Statement
- Today, using Claude with spreadsheet data means: select cells → copy → switch to claude.ai → paste → prompt → copy the answer → switch back → paste into the sheet. Every round-trip breaks flow and risks copy/paste errors (wrong range, stale data, lost formatting).
- Existing "AI in Sheets" add-ons are either tied to a single vendor's own model (e.g. Gemini in Sheets) or are heavyweight enterprise tools with seat-based pricing — there is no lightweight, BYOK, Claude-native add-on.
- Power users want Claude to be able to act on the sheet (fill cells, leave a comment explaining a number, restructure a tab) — not just answer questions in a side chat that they then transcribe by hand.
Solution
A Sheets-native sidebar add-on, built on Google Apps Script, that:
- Lets the user paste in their own Anthropic API key once (stored only in their Google account's script storage — never leaves Google's infrastructure to any server we control).
- Lets the user select any range(s) — including across multiple tabs — and pull them into the chat as structured context with one click ("Use selection as context").
- Sends the prompt + context straight to the Anthropic API (direct call from Apps Script — no middleman backend needed for the MVP).
- Gives Claude a small set of tools (function-calling) scoped to the active spreadsheet: read a range, write a range, add a comment, create/rename a sheet, list sheets. Claude decides which tool(s) to call to satisfy the user's request.
- Applies tool calls either as a preview the user must approve (Suggest mode) or immediately (Autonomous mode), with the mode controlled by a switch in the sidebar (and overridable inline, e.g. "do this without asking me").
- Logs every applied write/comment to a hidden audit tab so changes can be reviewed and undone — since Apps Script edits do not appear in Sheets' native Ctrl+Z history.
Target Users
Primary persona: The data-driven operator
- Runs ops/finance/growth for a small business or agency, lives in spreadsheets daily.
- Already pays for Claude (Pro or API) and constantly copies sheet data into claude.ai to ask questions ("summarize this", "find anomalies", "write a formula for X", "draft a comment explaining this variance").
- Wants the answer to land back in the sheet, not in a separate window.
Secondary persona: The technical builder
- Comfortable with API keys, Apps Script, and tool-use concepts.
- Wants fine-grained control (model choice, system prompt, autonomous vs. suggest mode) rather than a black-box experience.
Core Features — MVP (Phase 1)
1. Authorization (BYOK)
- Sidebar Settings panel: paste Anthropic API key, pick default model (latest Sonnet / Opus / Haiku, fetched from a small allow-list, defaulting to the current recommended model).
- Key is stored via Apps Script
PropertiesService.getUserProperties()— scoped to the individual Google user, never written to a shared property store, never transmitted to any cld-ext-controlled server (there is no cld-ext server in the MVP). - "Test connection" button does a minimal API call to validate the key before saving.
- Clear empty/invalid-key state with a link to https://console.anthropic.com/ to obtain a key.
2. Chat sidebar
- Standard Sheets sidebar (
HtmlService, opened via add-on menu Extensions → cld-ext → Open sidebar). - Chat-style transcript (user messages, Claude responses, and a distinct visual treatment for tool calls / applied actions).
- Input box + Send button + "Use selection as context" button.
- Mode toggle: Suggest / Autonomous, plus a per-message override phrase the user can type (e.g. prefixing "auto:") — but the toggle is the primary control.
- Model picker and "new conversation" (clears transcript + conversation memory, not the underlying sheet).
3. Context injection ("copy from sheet")
- "Use selection as context" serializes the current selection (supports multiple non-contiguous ranges and multiple sheets selected via
RangeAPI) into a compact table representation (TSV-like, with sheet name + A1 range header) and inserts it into the chat input, clearly delimited, editable before sending. - A "Use whole active sheet" shortcut for smaller sheets (size-guarded — see Non-Functional Requirements).
- Existing cell comments/notes in the selected range are included as additional context when present, so Claude is aware of prior annotations.
4. Sheet-manipulation tools (Claude tool-use / function calling)
Exposed to the model as callable tools, each implemented as an Apps Script function operating on the bound spreadsheet:
| Tool | Description |
|---|---|
list_sheets() |
Returns names, dimensions, and frozen rows/cols of every tab in the workbook |
read_range(sheet, a1Range) |
Returns values (and basic number formats) for a range |
write_range(sheet, a1Range, values) |
Writes a 2D array of values into a range |
add_comment(sheet, cell, text) |
Adds a cell comment (Sheets "note"/comment) |
create_sheet(name) / rename_sheet(oldName, newName) |
Adds or renames a tab |
format_range(sheet, a1Range, format) |
Bold/italic, background color, number format — stretch goal, may ship in Phase 2 |
- Tool definitions follow the Anthropic tool-use schema; the add-on runs the standard tool-use loop (send message → model requests tool call → execute locally → send tool result back → repeat until the model returns a final text response).
- Every tool call that mutates the sheet (
write_range,add_comment,create_sheet,rename_sheet,format_range) is gated by the active mode:- Suggest mode: the call is rendered as a preview card in the chat (target range/cell + old value → new value, or comment text) with Apply / Discard buttons. Nothing touches the sheet until the user clicks Apply.
- Autonomous mode: the call executes immediately, and a compact "✓ Applied: wrote B2:D10 on 'Q2 Budget'" line appears in the chat retroactively (still visible, just not blocking).
- Read-only tool calls (
list_sheets,read_range) always execute immediately in both modes — only mutations are gated.
5. Audit log & undo
- A hidden sheet (
_cld_ext_log, created on first mutation, excluded fromlist_sheets()results shown to the model) records: timestamp, tool name, target sheet/range, previous value snapshot, new value, and the user prompt that triggered it. - Sidebar shows a compact "Recent changes" list (last N entries) with a one-click Undo that restores the previous-value snapshot for that entry.
- This compensates for the fact that Apps Script writes do not enter Sheets' native edit history / Ctrl+Z stack.
6. Usage & cost transparency
- After each response, show input/output token counts (from the Anthropic API response usage field) and a running session total.
- No cost estimation in USD in the MVP (model pricing varies and is out of scope to keep in sync) — token counts only.
Core Features — Phase 2
- Autonomous-mode safety rails: a configurable "protected ranges" list (e.g. header rows, formula columns) that even Autonomous mode will never overwrite without falling back to Suggest behavior for that specific call.
- format_range tool (styling) if not already shipped in Phase 1.
- Multi-turn tool chains across tabs: explicit test coverage for prompts like "summarize Sheet1 into a new tab called Summary" that require
list_sheets→read_range→create_sheet→write_rangein sequence. - Prompt presets: a small library of canned prompts (e.g. "Explain this formula", "Find anomalies in this range", "Draft a comment summarizing this row") accessible from the sidebar.
- Streaming-like response rendering: since Apps Script
UrlFetchAppdoes not support true HTTP streaming, simulate progressive rendering by chunking the final response client-side, or poll a short-lived cache entry if a future backend is introduced (see Open Questions).
Core Features — Phase 3 (Landing page)
- Public site at https://cld-ext.dibly.me:
- Hero section explaining the product in one screen, with a short demo GIF/video.
- Feature walkthrough (mirrors the MVP feature list above) with screenshots.
- Install instructions (see Distribution below).
- This PRD, rendered as a readable page (not just a markdown link) — reuses the same approach as the command-center PRD viewer (rendered markdown, not raw text dump).
- Privacy Policy page — states explicitly that the add-on does not transmit spreadsheet data or API keys to any cld-ext server; all calls go directly from the user's Google account to Anthropic.
- Terms of Service page.
- Support/contact section.
Core Features — Phase 4 (Marketplace readiness)
- OAuth consent screen branding (logo, app name, support email, scopes justification copy).
- Google Workspace Marketplace listing assets: icon set, screenshots, short/long descriptions, category.
- OAuth scope minimization review (only request
spreadsheets.currentonlyif feasible instead of broadspreadsheets, plusscript.external_requestfor calling the Anthropic API). - Submission for Google's OAuth verification + Marketplace review (external process, timeline outside our control — typically several weeks).
Technical Architecture
Add-on (core product)
- Platform: Google Apps Script, Sheets Editor Add-on (not a standalone web app) — installs directly into the Sheets UI via the Extensions menu.
- Tooling: developed locally with
clasp(Apps Script CLI) for version control and CI-friendly pushes; source lives inapps/addon/in the repo. - UI:
HtmlServicesidebar (HTML/CSS/vanilla JS — no heavy framework needed given Apps Script's sandboxed iframe constraints), communicating with server-side.gsfunctions viagoogle.script.run. - LLM calls: server-side Apps Script function uses
UrlFetchApp.fetch()to call the Anthropic Messages API directly (https://api.anthropic.com/v1/messages) with the user's stored key in thex-api-keyheader. No proxy server required — this also simplifies the privacy story (no third party ever sees the spreadsheet data or the key). - Storage:
PropertiesService.getUserProperties()for the API key and per-user settings (default model, default mode); the hidden_cld_ext_logsheet for audit/undo data (per-spreadsheet, travels with the file). - OAuth scopes (minimum required):
https://www.googleapis.com/auth/spreadsheets.currentonly,https://www.googleapis.com/auth/script.external_request,https://www.googleapis.com/auth/script.container.ui.
Landing page
- Standalone Next.js app (consistent with other zync-code projects), statically rendering the marketing page, PRD viewer, Privacy Policy, and Terms of Service.
- Deployed via the existing nginx + PM2 pattern used across this server (subdomain, not path-prefix), at cld-ext.dibly.me, with a Let's Encrypt certificate via certbot — same pattern as
ssl-sentinel.thinkn.cloudandcommand-center.thinkn.cloudset up earlier on this server. - Requires a DNS A record for
cld-ext.dibly.mepointed at the server's IP before deployment (thedibly.mezone does not have a wildcard record — each subdomain needs its own explicit A record, confirmed while setting up other subdomains on this server).
No backend service in the MVP
Deliberately avoided to keep the privacy story simple and remove an entire class of infra/billing concerns (BYOK means no server-side key custody, no quota system, no server-side logging of prompts). A backend may be introduced later only if true streaming or team/shared-key billing is required (see Open Questions) — out of scope for Phases 1–3.
Non-Functional Requirements
- Security: API key never leaves the user's Google account boundary; no cld-ext server exists to leak it from.
UrlFetchAppcalls happen server-side inside Apps Script's execution sandbox, not in the browser, so the key is never exposed to page JS/network tab inspection by other parties (it is visible to the user's own browser dev tools, which is expected and acceptable for a BYOK tool the user controls). - Size limits: Apps Script has a 6-minute execution limit per call and
UrlFetchApppayload/response size limits (~50MB) — large selections must be chunked or rejected with a clear "selection too large, narrow your range" error before hitting the API. - Error handling: Distinct, human-readable error states for: invalid/revoked API key, Anthropic rate limit (429) with retry guidance, malformed tool-call arguments from the model (caught and surfaced, not silently applied), and Apps Script quota errors (daily
UrlFetchAppquota). - Idempotency / safety: mutating tool calls always operate on an explicit sheet + A1 range — never on "the active sheet" implicitly — to avoid Claude accidentally targeting the wrong tab after the user has switched tabs mid-conversation.
- Reversibility: every mutation is undoable via the audit log (see Feature 5) for at least the current session; older entries may be pruned to keep
_cld_ext_logfrom growing unbounded (cap configurable, default last 200 actions).
Distribution
- Phase 1–3: private use. Installed as a personal/unpublished Apps Script project ("Test deployment" / bound or standalone script the owner installs into their own account). No Google review needed at this stage.
- Phase 4 (future): Google Workspace Marketplace public listing — requires OAuth app verification (scopes review, possibly a demo video for sensitive/restricted scopes), a published Privacy Policy and Terms of Service (hosted on the landing page, see Phase 3), and Marketplace listing assets. This is an external, multi-week Google-side review process and is tracked as a separate milestone, not blocking Phases 1–3.
Roadmap / Milestones
| Phase | Scope | Exit criteria |
|---|---|---|
| 1 — MVP | BYOK settings, sidebar chat, context injection, read_range/write_range/list_sheets tools, Suggest + Autonomous mode toggle, basic audit log |
Owner can install the add-on in their own Google account and successfully run a prompt that reads a range and writes a result back, in both modes |
| 2 — Hardening | add_comment, create_sheet/rename_sheet, protected ranges, undo button, prompt presets |
All MVP tools available plus comments/tab creation; undo works end-to-end |
| 3 — Landing page | cld-ext.dibly.me live with marketing page, this PRD rendered, Privacy Policy, Terms of Service | Site live over HTTPS with working PRD viewer |
| 4 — Marketplace prep | OAuth consent branding, listing assets, scope minimization pass | Submission-ready package (review timeline outside our control) |
Risks & Open Questions
- No true streaming: Apps Script's
UrlFetchAppis request/response, not streaming — responses to long generations will appear all at once after a delay rather than token-by-token. Acceptable for MVP; revisit if it hurts UX. - Apps Script execution/quota limits: daily
UrlFetchAppcall quotas and the 6-minute execution ceiling cap how large/complex a single request can be. Mitigation: chunking guidance and clear error messages rather than silent failures. - Tool-call correctness: the model could call
write_rangewith a target range that doesn't match user intent (e.g. off-by-one row). Suggest mode exists specifically to catch this before Autonomous mode is trusted; Autonomous mode should default to off for new installs. - Marketplace scope review: broad spreadsheet scopes may trigger Google's "sensitive scope" verification track even for a personal-use app if ever submitted; Phase 4 explicitly budgets for this rather than assuming it is quick.
- Should a backend ever be added (for true streaming, or for a future "we manage the key for you" tier)? Deliberately deferred — not needed for the BYOK, personal-use scope of this PRD.
Success Metrics (personal-use phase)
- Time-to-result for a "read selection → ask Claude → get answer back in the sheet" loop: materially faster than the manual copy/paste/switch-tabs workflow it replaces.
- Zero data-loss incidents from Autonomous mode (validated via the audit log / undo mechanism working correctly in testing).
- Add-on remains usable purely with the owner's own API key, with no dependency on any cld-ext-operated server, for the entire personal-use phase.