Product Requirements Document

cld-ext — Claude for Sheets

← Back

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:

  1. 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).
  2. 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").
  3. Sends the prompt + context straight to the Anthropic API (direct call from Apps Script — no middleman backend needed for the MVP).
  4. 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.
  5. 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").
  6. 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 Range API) 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 from list_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_sheetsread_rangecreate_sheetwrite_range in 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 UrlFetchApp does 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.currentonly if feasible instead of broad spreadsheets, plus script.external_request for 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 in apps/addon/ in the repo.
  • UI: HtmlService sidebar (HTML/CSS/vanilla JS — no heavy framework needed given Apps Script's sandboxed iframe constraints), communicating with server-side .gs functions via google.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 the x-api-key header. 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_log sheet 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.cloud and command-center.thinkn.cloud set up earlier on this server.
  • Requires a DNS A record for cld-ext.dibly.me pointed at the server's IP before deployment (the dibly.me zone 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. UrlFetchApp calls 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 UrlFetchApp payload/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 UrlFetchApp quota).
  • 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_log from 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 UrlFetchApp is 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 UrlFetchApp call 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_range with 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.