Releases

The latest updates and improvements to Simple Product.

Simple Product can read web pages now

What shipped

Web page reading. Following on from last week's web_search, Simple Product can now deep-fetch a specific URL and return its main content as clean markdown. Point it at a blog post, documentation page, GitHub README, product page, or any URL — it'll read the full body and use it as context.

Same "build once, available everywhere" property: sp3k chat, MCP (Claude Desktop, Cursor, etc.), the skills engine, and integrations all pick up the new tool automatically. A skill can now compose "search for X → pick the best result → read it in full → synthesize into a doc," which is a much bigger unlock than either tool alone.

Handles most JS-rendered pages via Firecrawl under the hood. 1 credit per page, metered under the Tools bucket right next to search.

What this unlocks

  • Sp3k chat: "Read this URL and summarize the pricing model" or "Compare these two pages and tell me the differences."
  • Skills: chain search + read to build up context automatically — competitor blog monitoring, changelog watching, industry-signal roundups.
  • MCP surfaces: Claude Desktop and Cursor users get the tool automatically the moment they open SP's connector.

What's next

Building on this: deep research — either as a first-class SP tool (long-form reports with citations) or as a "brief + external agent + writeback" workflow where SP is the durable memory across research projects. More soon.

sp3k can search the web now

What shipped

Web search for sp3k (and every other SP surface). Ask sp3k anything that needs current information — "what's the latest release of X library", "who's discussing Y online", "what did people say about Z last week" — and it'll go to the web, search, and summarize. Available anywhere you use SP tools: sp3k chat, MCP (Claude Desktop, Cursor, etc.), the skills engine, and integrations.

Two small polish fixes:

  • The bare /app URL used to 404 if you didn't have a workspace in the path. Now redirects to your workspace picker.
  • Feedback captured externally (via the widget SDK, public API, Slack integration, or MCP) now shows a Source row in the sidebar — "Slack", "Widget", "API", etc. — instead of confusingly showing the workspace admin who owns the API key as the creator.

What's next

More tools land under the Tools bucket over the coming weeks:

  • web_read — deep-fetch a specific URL and get clean markdown back. Combined with web_search, sp3k can now research → deep-read → synthesize.
  • reddit_search — structured queries against subreddits, with posts and top comments. Useful for anyone who wants to survey a community's opinion on a topic and pull the signal into SP as feedback.

Card-to-card linking, now available as an MCP tool

Agents can now link cards to other cards through the Simple Product MCP. Three new tools are live on the connector:

  • link_card_to_card — create a link between two cards
  • unlink_card_from_card — remove a link between two cards
  • get_linked_cards — list every card linked to a given card (both directions)

Why this exists

The MCP already had link_doc_to_doc for connecting docs to each other, but no equivalent for cards — even though the underlying cardLinks schema and the "Related Cards" section in the card panel UI already used it. If you were working with an agent and wanted it to wire up "this bug blocks this feature" or "this card is a follow-up to that one," you had to open the app to make the connection manually.

Now the whole trio is symmetric with docs, and same-type card relationships are fully reachable from agent workflows.

When to use it

  • Block/blocked-by relationships — "this task depends on that one"
  • Follow-up work — a bug fix card linking back to the epic that discovered it
  • Related epics — cards on different boards that ship together

Bonus: workspace switching now sticks

We also fixed a related bug: switch_workspace was silently reverting on the next tool call for MCP clients that don't preserve session headers across requests — most notably Claude mobile and web connectors. If you tried to switch to a different workspace from your phone and your next tool call still returned the wrong workspace's data, that was this bug. It's fixed. switch_workspace(persistAsDefault: true) now actually persists.

Ship path

Both changes are server-side and picked up the moment you restart or reconnect your MCP client.

Linked Objects: consistent linking across every record

We've unified how you link things in Simple Product. Every object detail view — Docs, Cards, People, and Organizations — now has the same Linked Objects surface with the same seven sections in the same order:

Cards · Docs · Releases · Skills · People · Organizations · Feedback

The chrome around it stays different where it should (a card is a slide-out, a doc has a right rail, People and Orgs have their properties column on the left). But the linking surface inside all of them is one consistent thing.

What this means for you

Link anything to anything, everywhere. The link flow is now identical from every record:

  1. Open any record — a doc, a card, a person, an org.
  2. Find the object type you want to link to (Cards, People, Skills, whatever).
  3. Search and link an existing one, or create a new one on the spot.

No more remembering which page has which linking options where.

Same-type linking is now real. You can link:

  • Doc to Doc — tie a feedback item to the spec it produced, or a release note to its design doc.
  • Card to Card — block/blocked-by, follow-up work, related epics.
  • Person to Person — peer relationships, referrals, decision-maker + champion pairs.
  • Org to Org — parent / subsidiary, partner, competitor.

Doc-to-doc and card-to-card were technically possible before but had no UI to reach them. Person-to-person and org-to-org are brand new.

Info block on docs and cards

Docs and cards now show a compact info block in the sidebar:

  • Created by (hover for the author's email)
  • Created (date)
  • Last updated (date — hover for the editor's email)

Small, but grounds every record with the "who and when" without cluttering the main content.

Section caps: 5 with "Show all"

Each linked-objects section shows the first 5 items with a Show all N button. Expanding caps at 50, with a Show less to collapse back. Keeps the sidebar scannable even when a single card has dozens of linked things.

Skills — write English, ship agents

Skills

Simple Product is your product brain — the place you already store every conversation with customers, every idea, every card, every release. Now, skills lets you automate that work. Write English instructions once; agents run them against the same context you already have.


Skills are natural-language docs that agents can run. Write what should happen — read this card, draft an email, create a release — and Simple Product will run it either automatically when something triggers it, or manually when you (or an external agent like Claude Code) invoke it.


What you can do

Write a skill in plain English. Create a doc of type skill, describe the workflow, save. That's it — the doc is the skill.

Two ways to use every skill:

  • Manual (default): the skill is a prompt template. External agents — Claude Code, Cursor, the in-app chat — can read the skill body and execute the steps themselves using Simple Product tools. Or you click Run Now on the skill doc.
  • Automated: click Automate and Simple Product wires the skill to its triggers. It fires on its own when the event happens — no more attention required from you.

Change your mind whenever. When you update the text of a skill that is automated, the skill will keep running based on the old instructions. That way, you can edit a skill without breaking it. When you're update is ready, the Update skill button re-reads the skill and updates the automation from your latest edits. Stop automating turns off the trigger listening without deleting the skill.


What agents can do inside a skill

Triggers (things that fire an automated skill):

  • Card moved between stages — "when a card lands in Done…"
  • Feedback received — "when a customer submits feedback…"
  • Doc created, updated, published, unpublished, deleted
  • Release published
  • Person or org added
  • Card created or updated

Actions (things a skill can do):

  • Read: cards, docs, feedback, linked people, board structures, full-text search across docs and cards
  • Create: cards on any board (by name), release docs, email drafts to specific people
  • Update: card titles and descriptions, move cards between stages
  • Link: docs to cards, cards to people
  • Save a run summary explaining what happened

All actions stay inside your workspace — no cross-workspace access, no external APIs (yet), no auto-sent emails (drafts only, for review).


Run history + transparency

Every skill run — automated or manual — records a full transcript. See it at Skills → Runs. Each row shows:

  • The trigger that fired it ("Feedback received — …", "Card moved to Done — …")
  • The agent's own summary of what it accomplished
  • Duration + token cost
  • Expandable full transcript with every tool call and result

Something surprising happened? The transcript is the answer.


Example skill bodies

Auto-triage incoming feedback

When new feedback is created:

  1. Classify as a bug or feature request.
  2. If a bug, search the SP Bugs board for a similar existing card.
  3. If a feature, search the User Feedback Ideas board.
  4. If a similar card exists, link the feedback to it. If not, create a new card and link the feedback.

Draft release + customer follow-ups when a card moves to Done

When a card moves to Done:

  1. Read the card's details.
  2. Find feedback docs linked to the card.
  3. For each customer behind that feedback, draft a personal email thanking them and describing what shipped.
  4. Create a release doc summarizing what shipped.
  5. Save a one-sentence summary of the run.

Skills are prose, not code. Write like you're briefing a smart teammate.


Learn more

Full details for humans and AI agents:

Both docs are public, so any external agent with your MCP can read them and know how to write and run skills correctly.


Coming next

  • External integrations — Slack, Gmail, GitHub — so skills can act outside SP
  • Inbound webhooks — Stripe, Vercel, anything with an HTTP POST — become skill triggers
  • Cron / scheduled triggers — "every Monday at 9am, do X"
  • Persistent memory for long-running skill lifecycles

The engine is designed for these — each one plugs into the existing event and tool registries without engine changes.


Try it now: create a skill doc, describe a workflow in plain English, click Run Now to test, then Automate when it's doing what you want. Head to Skills in your workspace to get started.

Resize and reorder columns — your layout, remembered

Resize and reorder columns — your layout, remembered

Ever stared at a People row showing johnathan.d... because the Email column was 180px and the address was longer? Or wanted Last Active sitting right next to Name instead of three columns away?

The People and Organizations tables now bend to your layout:

  • Drag the right edge of any column header → that column resizes, live as you drag
  • Drag a column header by its grip icon (left side) → reorder columns
  • Widths and order persist → set your layout once; it's there next visit

How it feels

Resize. Hover the right edge of any header — the cursor switches to ↔ and a faint primary-color strip appears. Click-drag and the column updates as you drag (not just on release), so you can dial in the exact width you want.

Reorder. Every header has a grip icon (⋮⋮) on the left. Drag a header onto another header's position; they swap. Same gesture you already use for properties elsewhere in the app.

Persistence is per-workspace, per-table, per-browser. Widths you set on the People table in your SP workspace are remembered for SP's People specifically — Org widths in SP are separate, People widths in your other workspaces are separate, and your laptop and your phone each get their own layouts (which is what you probably actually want — different screen sizes deserve different column widths).


This is a small change but the kind you notice once it's gone. If there are other tables in the app where you'd like the same treatment, ping us — adding it elsewhere is mostly a one-line prop on the table.

Doc chats now save — pick up where you left off

Doc chats now save — pick up where you left off

You know that AI chat that lives next to a doc — the one where you ask "what's a better way to phrase this?" or "summarize the key points" or just brainstorm next steps with the doc as context? Until today it was in-memory only. Have a great exchange, refresh by accident, lose it. We've all been there.

Doc chats now persist. Open a doc → Chat tab → your last conversation is right there, ready to continue. Refresh, close the browser, come back tomorrow — same chat, same context.

How it works

One conversation per doc, automatically loaded when you open the chat tab. No "new chat" buttons to think about, no history sidebar to manage. The chat just remembers what you were talking about.

Under the hood, doc chats use the same storage as your SP3K conversations — but they don't clutter the SP3K list (you don't want every "fix this typo" thread in your main thinking inbox). They're per-user private, so your chats about a shared doc are yours alone. And when you delete a doc, the chat goes with it.

Two small input polishes

While we were in there, two things that had been quietly bugging us:

  • Cursor stays in the input when you hit Enter to send. Used to lose focus the moment a response started streaming, which meant clicking back in every time you wanted to follow up. Modern chat tools don't do that. Now neither do we.
  • The input grows with what you type. Was a thin one-line strip even when your text wrapped to four lines. Now expands up to about 5-6 lines of comfortable typing room.

Two tiny things you only notice when they're broken — and now they're not.

Trade-offs worth naming

There's one chat per doc today, not many. We considered multiple ongoing threads per doc (gives you a "new chat" reset for fresh context) but landed on simpler. The mental model is just "open doc, see your chat." No new surface to manage. If you want to wipe a chat and start over, that's a button we can add when somebody actually asks for it.

Each chat also has a quiet 15-message cap when sent to the model — the full conversation stays in your UI, but the model only sees the recent slice. Keeps cost and latency from growing unbounded as chats get long. A smarter version (using Haiku to summarize older turns so the model gets to keep that context cheaply) is its own future piece of work — already designed, just not built yet. Let us know how you're using doc chat.

Small polish updates that add up to a big product experience

Small polish updates that add up to a big product experience

We take the polish of Simple Product really seriously. We keep a backlog of small "polish" items — papercuts, inconsistencies, behavior that doesn't quite match muscle memory — and crank through them in batches. None of these changes is a big feature on its own. Stacked together, they're the difference between a product that feels precise and one that feels noisy.

This release is one of those passes. Here's what landed:

Every Create modal speaks the same language now

Every Create modal in Simple Product — boards, docs, releases, skills, people, organizations, feedback — now follows the same shape:

  • Title: "Create a new <thing>"
  • Description: one sentence about what the thing is for
  • Input: one labeled field with an example placeholder

That's it. Open the modal, type a title, hit enter. The doc (or board, or person) opens. You go from there.

Feedback got a bigger change. The old modal asked for a title and a body up front. We dropped the body — manually creating feedback now matches every other doc-backed resource: enter the title, the doc opens, type from there. Better for the main use case (typing live during a customer call) and consistent with how the rest of the app works.

Search bars that remember

Three changes to how search works on every table in the app:

  • Your query persists in the URL. Type "puppies" on /docs, click into a doc, hit Back — the search box still says "puppies" and the list is still filtered. No more re-typing the same search you just ran.
  • Esc behaves like macOS Finder. First Esc clears the query (cursor stays in the field, ready for a new search). Second Esc unfocuses.
  • Active filters are visible. When the search field has a value, the bar tints primary-colored — easy to spot a stale filter, especially on a long page of results.

Applies across boards, docs, releases, skills, customers, organizations, feedback, and projects.

A handful of UI wins

  • Theme picker shows a check mark next to the active choice (Light / Dark / System). If you're on System and your OS is dark, you can now tell at a glance whether SP is matching the OS or just defaulted.
  • Board column titles truncate instead of wrapping when they're long. Hover for the full name. The card count stays pinned right where it should be.
  • Analytics page is full-width like every other page. The stickiness chart was getting visually squished by a layout hack — we rewrote it to measure its container and draw in real pixel coordinates, so slopes are honest and the hover dots are round.
  • Skill detail "Back" button returns you to /skills instead of falling through to /docs (where it was going because skills are docs under the hood and the back logic didn't know better).

MCP setup docs got an overdue refresh

The MCP setup page (public docs and in-app Settings → MCP) had drifted from the product. Caught it up:

  • Custom Connector section now leads with a prominent "Add in Claude" button that opens the connector modal in claude.ai with one click.
  • Claude Code snippet updated to current syntax (--transport stdio, --scope user).
  • VS Code config example fixed — the root key is servers, not mcpServers. VS Code silently rejects the wrong key, so this was a real footgun for anyone copy-pasting the old example.
  • Authentication section now describes the browser-based flow we actually ship. The old text described a device-code copy step we removed weeks ago.
  • Available Tools list went from a stale 13-tool subset to the full 56-tool registry, sourced directly from our server-side tool definitions and grouped into 12 categories. So it's a real reference now instead of a teaser.

Polish is one of those things you can't market exactly — you just feel it when it's there, and notice when it isn't. We'll keep cranking through the backlog.

Skills — a dedicated home for the tasks your AI agents run

Skills — a dedicated home for the tasks your AI agents run

Skills now have a real home in Simple Product: a new sidebar item, a dedicated /skills view, and a Create dialog shaped for the way skills actually get written.

What is a skill?

A skill is a markdown doc that describes a task you want an AI agent to perform on your workspace. Examples:

  • Every morning, read the last 24 hours of feedback and draft email outreach for anything mentioning feature X
  • When a card moves to Done, draft release notes from the linked work
  • Categorize incoming feedback into feature requests / bugs / questions

The skill itself is the artifact. The runtime that actually executes it is the next chunk of work — but you can write the skill now and it'll run as the runtime comes online.

What's shipped today

  • Skills sidebar item — 💡 icon, sits between Releases and Customers
  • /skills view — list of every skill in your workspace, search, cards/list layouts
  • Create dialog tuned for skills — placeholder text asks for a name like "Feedback analyzer" or "Spec writer," not a version number; blank doc by default so you can describe the task however you like
  • Skill docs hidden from /docs — they live in /skills only, so your general Docs view stays focused on actual reference material

What's coming

The skills runtime — what actually executes the markdown — is next:

  • Cron triggers — schedule a skill ("every morning at 8am")
  • Event triggers — bind a skill to a webhook event ("on feedback.created, run this skill")
  • Two execution paths — SP runs it natively for tasks fully inside SP's tool surface, or webhook out to your own runtime (Claude Code, Cursor, your own LLM service) for skills that need tools SP doesn't have access to (local files, IDE, custom MCPs)
  • Execution receipts — every run writes back to SP as a comment or linked doc, so you can see what happened, what tools were called, and what credits got spent

Write skills now; they'll start running as the runtime lands. No migration, no porting — the skills you author today are the same artifacts the future runtime will pick up.

Suggested format

There's no spec yet, but skills read best when they're structured like a clear prompt:

## What this does
One paragraph plain-English description.

## When to run
- Trigger conditions (event, cron, manual)

## Inputs available
- Data the agent should pull (cards, docs, feedback, etc.)

## Steps
1. Numbered, ordered actions

## Output
What gets produced and where it lands (a draft doc, a comment, an email draft, ...)

## Constraints
What NOT to do. (E.g. "always leave as draft, never auto-publish")

We'll publish a fuller skills spec alongside the runtime.

Related: webhooks shipped the same day

Skills are one half of Simple Product's automation story. Webhooks — also shipped today — are the other half: events your own services can react to. Together with cron (coming), they're the three primitives we'll build all automation on.

What we'd love to hear

  • Which trigger should we ship first — cron or events? (Cron is simpler. Events feel more useful for reactive workflows.)
  • What skills do you want to write first? The most-requested ones are the most likely to shape how the runtime works.

Send feedback in-app or drop a note in the Skills view directly.

Webhooks — react to your workspace from any service

Webhooks — react to your workspace from any service

Simple Product now supports outbound webhooks. Subscribe a URL from your service to Simple Product events, and we'll POST you a signed payload every time something happens — a release publishes, a customer sends feedback, a card moves to Done.

Use it to send emails, post to Slack, revalidate caches, mirror content on your own site, or kick off any other workflow you'd otherwise need to poll for.

📖 Full documentation: simpleproduct.dev/docs/webhooks — receiver templates for Node / Next.js / Python, signature verification code, retry semantics, and the full payload format.

What you can subscribe to

Twelve events at launch:

  • doc.created, doc.updated, doc.published, doc.unpublished, doc.deleted
  • release.published — convenience alias that fires when the doc is a release
  • feedback.created — customer feedback received (widget, REST, in-app form)
  • card.created, card.updated, card.moved — includes previousStageId so you can detect "moved to Done" without a follow-up query
  • person.created, org.created — for CRM sync

Subscribe to specific events, or pass ["*"] for everything.

How to subscribe

Get a secret API key from Settings → API Keys, then:

curl -X POST https://simpleproduct.dev/api/v1/webhooks \
  -H "Authorization: Bearer sk_ws_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-service.example.com/webhooks/sp",
    "events": ["doc.published"]
  }'

The response includes a secret (shown once) — you'll use it to verify incoming requests are from us via the X-SP-Signature header.

Using an AI agent to set it up

If you've installed the Simple Product MCP in Claude Code, Cursor, or another agent, just say: "set up webhooks so I get an email when a release publishes."

The agent calls get_setup_guide({ feature: "webhooks", framework: "nextjs" }) (or node / python) and gets back a complete copy-pasteable receiver template — signature verification included.

What this unlocks

  • Email customers when you ship a release. Subscribe to doc.published, filter on data.type === "release", fetch the content via the public docs API, send the email from your own service.
  • Mirror SP content on your own site with surgical cache revalidation. No polling — your ISR pages update the moment something publishes or unpublishes.
  • Cross-tool automations. When feedback arrives, trigger your support workflow, customer success tool, or AI categorizer.
  • Slack / Discord / wherever. Push events to where your team already is.

Also in this release

  • Switch workspaces directly from Claude (web, mobile, desktop). If you've added Simple Product as a custom connector, you can now say "switch to my Acme workspace" and the connector handles it server-side. Previously this only worked via the CLI install — connector users were stuck on whichever workspace they first auth'd with.

  • list_workspaces actually lists your workspaces. Before this fix, the tool returned just the count and current workspace name — Claude had no way to discover the other workspaces you have access to. Now you get the full list with slugs, so the agent can pick one and switch into it.

  • Feedback recovery. Feedback submitted between May 13 and May 19 wasn't appearing in the feedback list because of a metadata field that got left off at insert time during a recent refactor. Fix shipped, and a one-shot backfill recovered every affected item. If your feedback list looked empty during that window — sorry, it's all back now.

What's next on the webhooks side

A few things will land as customers ask:

  • A UI for managing subscriptions in Settings (today: REST API only — fine for technical setup, less fine for non-engineers)
  • More event types — release.*, person.updated, custom-type events
  • Server-side filtering (today: subscribe by event type, filter further in your handler)
  • Self-service secret rotation

Full reference + receiver templates: simpleproduct.dev/docs/webhooks.

Questions, requests, or new event types you'd like to see? Send feedback in-app.

Simple Product now installs as a custom Claude connector — no terminal required

Simple Product now installs as a custom Claude connector

Until today, using Simple Product in Claude meant editing a JSON config file and running an npx installer — which assumed you had Node installed and were comfortable in a terminal. That was fine for engineers, less fine for everyone else.

Now you can add Simple Product as a custom connector directly inside Claude Desktop. Paste a URL, sign in once, and you're done. And once it's installed, it works everywhere you use Claude — including mobile.

What this unlocks

  • Anyone can install it. No terminal, no Node, no config files. Open Claude Desktop, paste a URL, approve.
  • Works on every Claude surface once installed — including mobile. Triage your roadmap from your phone, capture feedback the moment you hear it, move cards from the couch. The MCP-via-JSON path was desktop-only end to end.
  • Same tools, friendlier door. All the things Claude could already do in the SP workspace — search docs, manage cards, draft from feedback, post releases — just without the setup tax.

How to install

Claude Desktop (one-time setup)

  1. Open Claude Desktop → side nav → CustomizeConnectors
  2. Click Add custom connector
  3. Paste the Simple Product MCP URL:
    https://simpleproduct.dev/api/mcp/v1
    
  4. You'll be redirected to Simple Product to sign in (if you aren't already) and approve access for your workspace
  5. Done

The connector is tied to your Claude account, so it's immediately available on Claude.ai in your browser and on the Claude mobile app — no separate install needed.

Other MCP-compatible clients (Cursor, Windsurf, ChatGPT Connectors)

Same URL works as a remote MCP server:

https://simpleproduct.dev/api/mcp/v1

The OAuth flow handles authentication automatically — no API keys to manage, no config files to edit.

Existing mcp_* API key + npx users

Your existing setup keeps working. No action required. When you're ready, you can switch to the custom connector flow for a smoother experience (no key rotation, scoped permissions, easier revocation, and it shows up on mobile).

What's under the hood

The connector implements OAuth 2.1 with Dynamic Client Registration (RFC 7591), so any MCP-compatible client can connect without us pre-registering it. Tokens are scoped to the workspace you authorize and rotate automatically. Built on the open Model Context Protocol spec.

What's next

  • Submission to the Claude Connectors Directory so Simple Product shows up in the in-app browse experience and installs in one click
  • Inline UI rendering — view kanban boards and roadmaps directly in Claude chat
  • Bundled Claude Code plugin with slash commands for fast common workflows
  • More granular OAuth scopes for teams that want tighter access controls

Questions or hit a snag? Email support@simpleproduct.dev.

Public docs API + /share on simpleproduct.dev (dogfooded)

Public docs API + /share on simpleproduct.dev (dogfooded)

Every published doc in your workspace now has a stable public URL, no matter what type it is — and we built /share on simpleproduct.dev itself to prove the API does what it says.

The public docs API: type is now optional

Previously the public docs endpoint required a type query param. Any doc without a type — or whose type wasn't one of the "known" system types like blog or release — was unreachable through public surfaces. That made the whole publish flow narrower than it needed to be.

New shape:

GET /api/v1/docs/public/<slug>?workspace=<ws>             → doc by slug, any type
GET /api/v1/docs/public/<slug>?workspace=<ws>&type=<t>    → guard rail; 404 if doc.type !== <t>
GET /api/v1/docs/public?workspace=<ws>                    → all published, any type
GET /api/v1/docs/public?workspace=<ws>&type=<t>           → filter to one type

Slugs are now unique per workspace (not per (workspace, type)), so a slug alone uniquely identifies a doc. Type, when you do pass it, is purely an optional filter — never a disambiguator, never required.

SP dogfoods it: /share/<slug>

We added a /share route on simpleproduct.dev that renders any published doc via the public REST API — exactly the same fetch a customer would make from acme.com. No special workspace access, no internal Convex path, no auth header. The publish button is the auth.

Try it: a feedback review we wrote for Andrew Harrison at Stable Kernel — published as a regular doc in our SP workspace, with an embedded interactive slide-deck summary at the top. Same fetch you could make from your own site.

html-render code blocks now auto-resize

The html-render fenced-code block (introduced previously) sandboxes plain HTML/CSS/JS in an iframe — useful for embeds like the slide deck above. Until now the iframe was clamped at 200px regardless of content, so tall content got an inner scrollbar and felt small.

The iframe now sizes itself to its content via postMessage, with ResizeObserver and MutationObserver keeping it accurate as content reflows (slide decks switching slides, expanding panels, etc.). Sandbox unchanged: allow-scripts only, no same-origin access.

Why this matters (and how we use it ourselves)

Two of the things we say about Simple Product are:

  1. "Your product team's content can live next to your product work, not stuck in a separate marketing/CMS tool."
  2. "Any customer can pull that content into their own site."

We needed to prove #2 — and now we have. The /share route on simpleproduct.dev is literally the dogfood: we built it the way any customer would build their own equivalent on acme.com, with the same public API and the same workspace-slug-based fetch. We publish docs internally (release notes, customer-specific feedback reviews, blog posts, anything), and they're immediately shareable at simpleproduct.dev/share/<slug> — for visitors, customers, partners, whoever.

For our own use case it means: write a customer a thoughtful feedback review inside SP, embed a slide deck if it helps, hit publish, send them the URL. The whole loop — capture → write → publish → share — lives in one workspace.

For yours: same API, same call shape, just workspace=<your-slug> instead of sp. A customer-facing changelog, a public docs section, individual share links for customer reviews — anything you can author as a doc in SP, you can render on your own site with one fetch.

Try it yourself

  • curl "https://simpleproduct.dev/api/v1/docs/public?workspace=sp&limit=5" — list our recently published docs
  • curl "https://simpleproduct.dev/api/v1/docs/public/<slug>?workspace=sp" — fetch a single one by slug
  • Or visit any of the /share/<slug> URLs we publish from now on

Renderable code blocks, doc-to-doc linking, and quiet groundwork for skills

Renderable code blocks, doc-to-doc linking, and quiet groundwork for skills

This release is a mix: one genuinely new product capability (live HTML/CSS/JS inside docs), one piece of infrastructure agents will lean on heavily (linking docs to each other), and a few small things that make the docs surface feel more deliberate.

Renderable code blocks in docs

Any fenced code block marked html-render now executes inline in a sandboxed iframe instead of rendering as typeset code. The browser is the runtime — no extra setup, no bundler, no library to add.

```html-render
<button onclick="alert('it works')">click me</button>
<style>button { padding: 8px 16px; }</style>
```

Save the doc and the block renders as a working button between the surrounding prose. Three things this unlocks today:

  • Prototype demos as docs. Paste output from Claude/v0/Cursor into a doc and the doc itself becomes the interactive prototype. Stakeholders click through the actual thing instead of reading screenshots.
  • Tiny one-off dashboards. Pull data via fetch, render with canvas or vanilla HTML. The doc is the dashboard.
  • Better changelog entries. A release note can embed an actual working component showing what just shipped instead of describing it.

What's supported: any browser-native JavaScript — DOM APIs, fetch, localStorage, canvas, WebGL, web audio. You can even import npm packages from esm.sh as ES modules. What's not supported in this version: React/JSX with imports (no transform layer), TypeScript (no transpilation), Node APIs (browser-only by definition). A more capable tier using Sandpack is the planned follow-up if customers want React component embedding.

Sandboxing is real: iframe sandbox="allow-scripts" with no allow-same-origin. The block can run JavaScript inside the iframe but can't reach the parent page's cookies, localStorage, or DOM. Standard browser primitive.

Doc-to-doc linking

Until this release, you could link a doc to a card, a person, an org — but not to another doc. That was a real gap, because feedback items and release notes are both docs in Simple Product (stored with type="feedback" and type="release"). The doc-to-doc linking gap meant a feedback summary doc couldn't formally link to the underlying feedback items, and a release note couldn't link to its design doc.

Now it can. Three new MCP tools for AI agents:

  • link_doc_to_doc(docId1, docId2) — symmetric, idempotent. Doesn't matter which doc you list first.
  • unlink_doc_from_doc(docId1, docId2) — remove the link.
  • get_linked_docs(docId) — get every doc linked to a given doc, with title, type, excerpt, and last-update time.

The underlying junction table works the same way as the existing card↔card links. Workspace-scoped, deduped, no cross-workspace linking.

This is the kind of feature that's invisible until you need it, then suddenly powers a class of workflow. The first place it lands naturally: AI-drafted customer feedback summaries that need to point back at the specific feedback items they cover.

skill is now a recognized doc type

We didn't ship skills as a feature yet. But we added skill to the list of doc types that AI agents recognize when creating new docs. Drafts for skill specs and skill prompts now land with the right type marker, ready for the actual skills runtime that's coming next.

UI: "Category" is now "Type"

The doc type field had been labeled "Category" in the UI but called type everywhere else (API, schema, MCP). The mismatch was creating quiet confusion when reading code or talking about doc types. Renamed across the doc detail menu, the type dialog, and the publishing popover so the UI matches the underlying contract.

Unrelated "category" concepts (integrations, GSD setup actions) are unaffected.

Architecture footnote: typeOrigin discriminator

For the curious. We added a typeOrigin: "system" | "workspace" field to docs. It distinguishes system-defined types (feedback, release, blog, docs, skill — types with built-in product behavior) from workspace-defined custom categories (anything else, including categories that happen to share a name with a system type).

This is the protection layer that means a workspace can now create a custom category called "blog" without those docs accidentally appearing in the public blog feed. The discriminator gates which docs participate in system surfaces; user categories pass through cleanly. It also future-proofs us — when we ship more system types (skills with execution semantics, automation primitives, etc.), there's no name-collision risk with whatever customers have already named their own categories.

Backfill ran cleanly across existing data; nothing else changes from your perspective.

Have fun

If you've been using SP daily, the most visible thing this week is probably the renderable code blocks — drop an HTML demo into your next doc and see what comes out. It's surprising how much vanilla HTML/CSS/JS can do once the browser is the runtime.

Smarter back button + optional board context for AI agents

Smarter back button + board context for AI agents

Two small improvements that go together — one polish, one quietly leveraged feature for the AI parts of Simple Product.

Back button now goes back to where you came from

Previously, the back arrow on a person's page or an organization's page always took you to the corresponding listing — even if you got there by clicking through from another record. So if you went Person → linked Org → back, you ended up on the Orgs listing instead of returning to the Person you were on. Surprising, mildly disorienting, and a quiet papercut every time you navigated through linked records.

Now the back button checks whether you got here from inside Simple Product. If yes, it returns you to wherever you came from. If you landed via an external link (Slack, email, refreshed the page), it falls back to the listing — same as before. So:

  • Person → Org → Back returns to the Person ✓
  • Org → Person → Back returns to the Org ✓
  • Listing → Detail → Back returns to the Listing ✓
  • Email/Slack link → Detail → Back returns to the Listing (no in-app history) ✓

Same fix should land on other detail pages (cards, docs, releases) — that's a quick follow-up.

Boards can now hold context for AI agents

Each board can now carry an optional context — a small free-form description of what the board is for, who works in it, or how cards on it are formatted. Examples:

This board tracks customer outreach, not features. Cards follow Name → Company → Status → Last touch.

This is for raw ideas to research; don't expect them to be well-formed.

Engineering bug board. Cards link a reproducible repro and a stack trace.

The context is hidden in the UI by design — there's no header banner showing it on the board page. Instead, it's stored alongside the board and surfaces in agent prompts when AI is working with that board's cards. The agent reads the context, adapts its behavior, and produces output that fits the conventions of the specific board.

That last part is the load-bearing piece. Today, when you ask Claude or any MCP-connected agent to "draft a card on the customer outreach board," it has no way to know that board has different conventions than your features board. Context closes that gap without forcing every prompt to re-explain it.

How to use it

Setting context when creating a new board: the create dialog now has an optional Context textarea below the name. Skip it and you get the same lightweight board you've always created. Fill it in and AI agents working on the board pick up the conventions.

Setting context on an existing board: open the board, hit the [⋮] menu in the header, click Add context (or Edit context if one's already set). Same textarea, same behavior. Save it and you're done.

Clearing context: open the same dialog, empty the field, save. The menu label flips back to "Add context."

Note on the AI side

The data and UI for context are live in this release. The wiring that injects board.context into agent prompts is queued as a follow-up — small change, planned soon. Any context you write today is captured and waiting for that wiring to land. No need to redo it later.

The MCP get_board tool will also include context in its response after the next MCP server-side update — happens automatically; no SDK reinstall needed (this is the "ship without npm publish" architecture from the V1 MCP rebuild).

Multi-org for people — your contacts can belong to multiple companies

Multi-org for people

People in Simple Product can now belong to multiple organizations. Contractors with several clients, advisors on multiple boards, employees with side gigs, customers who've changed companies — all model correctly now without forcing you to pick one and lose the rest.

What's new

The Organizations section on a person's page is now a list, not a single picker:

  • [+] next to the section header opens a search popover to add another org (or create one inline if it doesn't exist yet)
  • Each row clicks through to that org's page
  • The [⋮] menu per row offers "Remove" — surgically removes that one affiliation, leaves the rest

The same shape exists on the org page. Linked people show up there with their own [⋮] menu and a "Remove from this org" option. So whether you're managing affiliations from a person's perspective or from an org's, the experience is symmetric — the relationship is genuinely many-to-many in both directions.

Why this matters

Most CRM-style tools force a 1:1 person→company mental model: each contact has one company. That's a reasonable simplification for many cases, but it breaks the moment you encounter:

  • A contractor who consults for three of your customer companies
  • An advisor who sits on the board of multiple portfolio companies
  • A buyer who switched jobs since you first met them — do you lose their old affiliation?
  • A founder who's involved in two startups simultaneously

Forcing any of these into a single-org model means losing data the moment you record reality. Multi-org lets you track all of it without special workarounds.

It also fixes a real bug we'd been carrying: linking a person to a second org from the org's page used to silently replace their existing primary affiliation. So adding "Alice" to Beta Inc's people list when she was already at Acme would invisibly demote Acme. Now it adds Beta as an additional affiliation; Alice's existing relationships are preserved.

Upgrade

Nothing required on your end. The change is purely additive — existing people with one org continue to display correctly, just in the new list format. The first time you add a second org to someone, you'll see the list grow.

If you'd like to bulk-link people to multiple orgs via the SDK or REST API, that surface comes next — for now, multi-org management is UI-only.

New MCP tool: list_workspace_members — find your team, not your customers

New MCP tool: list_workspace_members

You can now ask any MCP-connected AI client (Claude Desktop, Cursor, Claude Code, etc.) about your workspace teammates and get an answer. Previously, asking "who's on my team?" or "find Alice on my team" routed agents to search_people — which searches your customers, not your team — and returned nothing useful, even when the person was sitting right there as a workspace member.

What's new

A single tool: list_workspace_members.

  • No args → returns everyone with login access to the active workspace, with their role (owner/admin/member) and the caller marked as isYou
  • Optional query arg → filters by name or email substring

That's it. One tool, two behaviors, picked between by whether you pass an argument.

Why it's a separate tool from search_people

In Simple Product:

  • People = your customer / CRM contacts. Created automatically when your SDK fires identify(). Tracked via the people table. This is what search_people searches.
  • Workspace members = the humans with login access to your Simple Product workspace. Your team. Tracked via the workspaceMembers table. This is what list_workspace_members returns.

These are two genuinely different tables for two genuinely different concepts. We didn't want to overload one tool to do both — agents would have to guess which one you meant, and would be wrong half the time. So they're split, with descriptions that explicitly contrast.

How to use it

In any MCP-connected AI client:

"Who's on my team?"

"Find Alice on my team."

"List the admins of this workspace."

"Show me workspace members whose email is at acme.com."

The agent will pick list_workspace_members (with or without the query arg). Your team comes back with names, emails, and roles.

How this got here

Arthur Torres at Stable Kernel hit the gap and reported it as a bug — they were trying to look up themselves as a workspace member via search_people, came up empty, and very reasonably assumed the search was broken. It wasn't broken; we just hadn't exposed the right tool. Thanks Arthur — this one's yours.

Architectural footnote (for the curious)

This tool shipped with zero changes to the npm package — we added it server-side to /api/mcp/v1 and every existing 0.2.x bridge picked it up on its next session. No npm install, no version bump, no nag to upgrade. That's the model we settled on with the MCP V1 work last week, and this is the first time we used it in response to specific customer feedback — feedback to fix to ship in a single afternoon, no friction for anyone running the SDK.

If you're already on @simple-product/mcp@0.2.x, just restart your AI client and ask it about your team.

MCP V1: hosted endpoint, thin bridge, and tools that ship without reinstalling

MCP V1: hosted endpoint, thin bridge, and tools that ship without reinstalling

We rebuilt the Simple Product MCP. Tool definitions now live on simpleproduct.dev itself, served from a hosted MCP endpoint at /api/mcp/v1. The npm package becomes a thin stdio↔HTTP bridge that authenticates and forwards.

Why this matters

Until today, every change to an MCP tool — adding one, fixing a description, tightening an input schema — meant publishing a new npm version and asking everyone to reinstall. That's a long feedback loop for something that should be invisible.

Now, when we add or improve a tool server-side, every existing install picks it up on the next session. No npx … --install, no version bump, no nag to upgrade. We used this immediately to ship two new tools — whoami and list_workspaces — that don't appear in any npm package. They just showed up in everyone's installed bridge.

What's in 0.2.x

@simple-product/mcp@0.2.0 is the bridge. It:

  • Reads ~/.simple-product/config.json for auth (same install flow as before)
  • Connects to simpleproduct.dev/api/mcp/v1 over HTTPS
  • Forwards tools/list → server returns the live tool catalog
  • Forwards tools/call → server runs the tool and returns the result
  • Stays out of the way otherwise

The install path is unchanged. npx @simple-product/mcp@latest --install still detects every supported AI client (Claude Desktop, Claude Code, Cursor, Windsurf, VS Code, etc.) and writes config; only the runtime behavior is different.

0.2.1 adds back switch_workspace. Tools that mutate local state (rewriting your project's workspace pinning) still need to live in the bridge code itself, so this one did need a publish. The bridge advertises it in tools/list and intercepts the call locally instead of forwarding it.

New tools available right now

Live for every 0.2.x install with no reinstall:

  • whoami — Confirms which user and workspace your MCP is authenticated as. Quick sanity check when juggling multiple workspaces.
  • list_workspaces — Every workspace you're a member of, with the active one flagged.
  • switch_workspace — Bumps to 0.2.1 of the bridge, but functionally unchanged from 0.1.x.

Try them: in any AI client connected to Simple Product, ask "use whoami to confirm which workspace I'm in."

Coexistence and rollback

@simple-product/mcp@0.1.x (with tools baked into the package) is still on npm and still works. The legacy /api/mcp/execute endpoint stays alive indefinitely — both 0.1.x and 0.2.x clients have a stable, supported home.

If the new bridge misbehaves on your machine:

# Drop back to the legacy bundled-tools build
npx @simple-product/mcp@0.1.19 --install

Or, in-place, without reinstalling — pass --legacy to the 0.2.x runtime to switch to the old bundled-tools mode for the current session.

What's next

With tool changes shipping server-side, the bottleneck for new MCP capabilities is now the SP server, not the npm release cycle. Expect more tools, faster, with no install nag — and a few quality-of-life additions to the install flow itself as we use it more.

This release ships in @simple-product/mcp@0.2.1.

MCP install: one less step, no more device-code copy

Small but nice: installing the Simple Product MCP no longer makes you copy a device code between your terminal and your browser. The CLI passes the code in the URL automatically, the browser auto-fills it, and you just confirm a workspace and click Authorize.

What changed

Before:

  1. Run npx @simple-product/mcp --install
  2. Terminal shows a device code
  3. Press Enter, browser opens
  4. Browser asks you to type the code into a form field
  5. Pick a workspace, click Authorize
  6. Wait for CLI to confirm

Now:

  1. Run npx @simple-product/mcp@latest --install
  2. Browser opens straight to the workspace picker (code already known)
  3. Click Authorize, done

One less step in your terminal, one less form field in your browser, one less variable to keep track of. The whole install runs in about 15 seconds without you typing anything you didn't already.

Why we kept the npx installer (and didn't switch to a different OAuth flow)

A quick architectural note for anyone curious. We considered a few alternatives:

  • Localhost-callback OAuth — what most modern CLIs (gh, vercel, supabase) use. Marginal UX gain, but works in fewer environments (some locked-down corporate networks block port binding) and the success page lives on a localhost:NNNN URL that looks weird. Net not better than what we shipped.
  • Pure browser-side OAuth via the MCP Authorization Spec — the eventual destination for spec-compliant clients (Claude Desktop, Code), which can handle their own OAuth in-protocol. We're set up to support that on the server side, but it doesn't replace the npx installer for two reasons. First, multi-tool fan-out: our installer detects every MCP-supporting tool on your machine (Claude Code, Claude Desktop, Cursor, Windsurf, VS Code, etc.) and writes config to all of them in one auth step. Spec-native flows do per-tool credential isolation by design — you'd auth once per tool. Second, pre-auth at first launch: by the time your AI client boots, MCP is already authenticated. No first-call 401, no /mcp interruption mid-conversation.

So the npx installer stays as the primary install vehicle. We just shaved the friction off it.

Upgrade

npx @simple-product/mcp@latest --install

If you have an existing install, this will detect and update your client configs. After install, restart your AI client (Claude Code, Claude Desktop, Cursor, etc.) once and the new tools/auth are picked up.

This release ships in @simple-product/mcp@0.1.19.

What's next

The bigger picture: a hosted MCP endpoint at simpleproduct.dev/api/mcp/v1 that becomes the substrate behind the npx installer. New tools and updated descriptions ship server-side and reach every existing install instantly — no more "please reinstall the MCP" when we improve a tool. Coming soon.

Emails via MCP, author bylines, and a smarter command palette

Big batch of changes since the Categories release. The headline: Simple Product can now draft and send email through your AI agent, and every email touch becomes a contact relationship — no orphaned drafts, no "where did that email go?" surprises.

Email workflows via MCP

Three new tools shipped in @simple-product/mcp@0.1.17:

draft_email

Tell your agent "draft a follow-up to Sarah about pricing" and it composes the email, saves it as a draft on Sarah's contact record with an "AI Draft" badge, and you click Send when you're ready. Defaults to drafting (not sending) unless you explicitly say "send."

send_email

For when you want to fire it off. Sends through your connected Gmail, automatically saves the sent email to the contact's communication history. Tool description is firmly directive — agents only send when you explicitly ask, never on a guess.

list_drafts

"Who was that follow-up email to?" — your agent can now answer. Lists your pending drafts newest first, with subject, recipients, linked contact, and a body snippet. Pair with draft_email's draftId arg to update or send a previously drafted message.

list_emails

Returns the full email history for a contact, both sent (from SP) and received (synced from Gmail). Use it for context-aware replies — your agent reads the prior conversation before drafting.

Every email touch is a contact

The product principle: Simple Product is a customer tracking system, not an email client. So when you draft or send an email, the system makes sure there's always a contact record:

  • If the recipient is already a contact → the email links to them
  • If the recipient (in to, cc, or anywhere else addressed) matches an existing contact → links to that one
  • If no recipients match → creates a new contact from the primary address (name = local part of the email; you can rename later)

Drafts always land on a contact's Communication tab. Sent emails always show up in the contact's history. No orphan messages floating in the void. The customer-relationship view is always complete.

Author bylines on published docs

Published docs (blog posts, release notes, anything in your category feeds) now show the author on the public page and in the API response.

  • simpleproduct.dev/blog posts render "by Author Name · Date" under the title
  • /api/v1/docs/public responses include { author: { name, image } } per doc
  • JSON-LD schema uses Person instead of Organization when an author is set, improving SEO and social previews

If you're rendering a blog or knowledge base on your own domain using the public API, the author field is now there for the taking.

Smarter command palette (Cmd+K)

The cmd+k search now surfaces all 10 settings pages — Members, Billing, API, MCP, Integrations, Profile, AI, Analytics, Customers, General — in a dedicated "Settings" group. Type "billing" or "api keys" or "claude desktop" and jump straight there.

Settings entries render as Settings › Billing so they're visually distinct from top-level navigation entries with overlapping names (e.g. the top-level "Analytics" page vs. "Settings › Analytics").

Polish wins

  • Mobile navigation finally feels right — hamburger sheet under md breakpoint with body scroll lock and route-change auto-close. Logo box pinned square; "Simple Product" wordmark scales down so it doesn't crowd the right-side controls. The Account button shrinks on mobile too.
  • Visual consistency across /docs, /blog, and /releases pages — same heading style, same spacing, same left-aligned typography. The mismatched icons and centered layouts are gone.
  • Comments use initials instead of OAuth profile images. Cleaner look, consistent with the rest of the product. (If you want avatars back, there's a single flag at the top of CommentItem.tsx that flips it.)
  • Doc publishing got more reliable. Auto-slug-on-publish means a published doc can never be unreachable: even if you (or an agent) skip the slug field, the server derives one from the title. Listings always have a working link, even for legacy posts without slugs. The publish popover now pre-fills slug and excerpt from the title and content respectively — no more empty fields you have to remember to populate.
  • create_doc and update_doc MCP descriptions are now directive. Agents reliably set the right category and publish state from natural language: "blog post" → type=blog, publish=true; "save these notes" → no type, no publish. Closes a class of "I published a blog post but it didn't show up" bugs caused by ambiguous instructions.

Upgrade

npx @simple-product/mcp@latest --install

Restart your MCP client (Claude Code, Claude Desktop, etc.) to pick up the new tools. Existing tools work unchanged.

How to use it

A representative workflow now possible:

  1. "Read the recent feedback from Sarah and draft a follow-up about her API limit ask"

    • Agent reads Sarah's feedback via get_feedback
    • Agent reads prior emails via list_emails
    • Agent calls draft_email with personId=Sarah's record
    • Draft lands on Sarah's Communication tab, AI Draft badge, ready for your review
  2. "What drafts do I have pending?"

    • Agent calls list_drafts
    • Shows you everything you've drafted recently with subject, recipient, last edited
  3. "Send the email I drafted to Acme last night"

    • Agent calls list_drafts to find it
    • Agent calls send_email with that draftId
    • Goes through your Gmail; lands in the contact's communication history

The pattern: read context → draft from context → review → send. Same loop a thoughtful human would run, just faster.

Categories, publishing, and a public docs API

Every doc can now have a category and be published to a public feed. The two built-in categories — feedback and release — work the same as any category you make up. Underneath, it's all one primitive: a doc with a type, an optional slug, and a publish state.

This unlocks a lot. The most obvious use is what we just shipped: simpleproduct.dev/blog is built entirely on the new public API — no special blog infrastructure, no separate database, just docs with category: "blog". You can do the same on your own site for a blog, knowledge base, public roadmap, case studies, RFCs, anything.

What's new

Categorize any doc

Open a doc, hit the menu, choose a category. Free-form: type blog, changelog, case-studies, whatever fits. Categories normalize on save (Blogblog) so Blog and blog are never two separate buckets.

Publish from the doc editor

The Publish button (in the toolbar) opens a popover where you set a slug, an excerpt, and toggle the publish state. Published docs are immediately reachable via the public API.

Public docs API

Three new endpoints, no auth required:

  • GET /api/v1/docs/public?type=<category>&workspace=<slug> — list published docs in a category
  • GET /api/v1/docs/public/<slug>?type=<category>&workspace=<slug> — single published doc by slug
  • GET /api/v1/docs/rss?type=<category>&workspace=<slug> — RSS feed for a category

Existing /api/v1/releases/public and /api/v1/releases/rss keep working unchanged.

Authenticated docs API now does everything

POST /api/v1/docs and PATCH /api/v1/docs/:id accept type, slug, excerpt, and publish (boolean shorthand for status). Pass null to any optional field to clear it.

MCP tools (@simple-product/mcp@0.1.14)

create_doc and update_doc accept type, slug, excerpt, and publish. Your coding agent can publish a doc into any category in one tool call. Update by running npx @simple-product/mcp@latest --install and restarting your MCP client.

Comments via MCP

create_comment is now a first-class tool. get_card / get_doc / get_feedback include the existing comment thread inline. Agents can read and post comments on behalf of the user.

How to use it

  1. Pick a category name. Anything URL-safe — blog, changelog, guides, etc.
  2. Set it on a doc via the menu, fill in a slug + excerpt, click Publish.
  3. Read it back from /api/v1/docs/public?type=<your-category>&workspace=<your-workspace-slug>.
  4. Render however you want — your stack, your design.

If you want a head-start, the simpleproduct.dev/blog code is intentionally minimal and uses the same public endpoints any customer would. Same pattern works for any category.

April 27 — Publishable keys for feedback, sidebar polish, chat focus fix, MCP analytics guide

What's new

A bundle of security, polish, and developer-experience improvements.

Publishable keys now handle feedback submissions

Publishable keys (pk_ws_) used to only carry the track scope — analytics events only. They now also include feedback:write, so the same key can power both tracking and feedback widgets in your app.

This means: one pk_ws_ key, exposed safely in your client-side bundle, drives both your analytics and your feedback collection. No more reaching for a full-access secret key just to submit feedback from the browser.

We rotated Simple Product's own feedback widget over to a publishable key as part of this. The old full-access key is being retired.

If you have existing publishable keys, they got the new scope automatically — no action needed.

MCP setup guide for analytics

The get_setup_guide MCP tool now has an analytics option. Ask your agent something like "set up Simple Product analytics in my Next.js app" and it'll get a real, copy-paste-able guide for your framework — including which key to use, which env var, where to put the provider, how to identify users, and how to track custom events.

Frameworks covered: React, Next.js, Vue, plain HTML, Node.js, Python.

The guides explicitly call out the publishable key pattern, so agents recommend the safe key by default — no more telling people to bake sk_ keys into client code.

MCP 0.1.12

Two patches to @simple-product/mcp:

  • Setup guide for analytics (the one above)
  • Fix for Claude Desktop: switch_workspace was crashing on sandboxed MCP hosts (Claude Desktop, etc.) because it tried to write to a read-only filesystem. Now it gracefully degrades — switching is in-memory only when persistent storage isn't available, and writes are best-effort otherwise.

Update with npx @simple-product/mcp@latest.

Sidebar polish

Two small but meaningful tweaks:

  • The top-left now shows your workspace name next to the logo instead of "Simple Product." If the name's long, it truncates with a tooltip on hover.
  • The bottom-left user card now shows your email under your name (instead of repeating the workspace name, which was already up top).

The workspace name is the most useful identifier when you're switching between several — it's now the most prominent thing on the screen.

Chat focus fix

In SP3K, hitting Enter to send a message used to blur the textarea — you'd have to click back into it before typing again. The input is no longer disabled while the agent's responding, so you can type your next message right away. (Same pattern as ChatGPT and Claude.ai.)

Homepage copy refinement

Tightened the hero copy on the marketing site to lead with the "Product Brain for building with AI" framing.


Small batch, but each one is a friction point removed. Keep the feedback coming.

MCP v0.1.11 — Claude Desktop fix (switch_workspace on sandboxed hosts)

What changed

A quick patch to @simple-product/mcp (v0.1.11) fixing a crash when running the MCP inside sandboxed hosts like Claude Desktop.

The bug

switch_workspace was crashing with:

EROFS: read-only file system, open '/.simple-product.json'

Cause: when running in a sandboxed MCP environment where process.cwd() is / (filesystem root), our project-config path resolver fell through to path.join('/', '.simple-product.json') — trying to write to the filesystem root, which is read-only.

The fix

Three small changes:

  1. In-memory state is now the source of truth. The workspace switch happens immediately on every call, regardless of whether we can persist it.
  2. Only persist when there's a real project context — an existing .simple-product.json or a nearby .git. No more silent fallthrough to filesystem root.
  3. Writes are best-effort. If the filesystem is read-only (Claude Desktop, other sandboxed hosts), we skip the write without crashing. switch_workspace tells you whether it persisted or if it's session-only.

What users see

  • Claude Code / Cursor / terminal installs: no change. Project-level workspace persistence works as before — switching in one project doesn't affect another.
  • Claude Desktop and other sandboxed hosts: switch_workspace now works. The message says "(Not persisted — this workspace applies for the current session only.)" so you know the switch is in-memory only.

Update

Existing installs via Claude Code or similar pick this up automatically on the next call. For Claude Desktop configs that pin to a specific version, update to @simple-product/mcp@latest (or 0.1.11).


Thanks to the friend who filed a really clear repro including the stack trace and a correct root-cause guess — made this a one-sitting fix.

April 21 — Publishable keys, MCP tracking, better boards + agent UX

What's new

A big batch of improvements focused on safer API keys, richer analytics, and a smoother experience for both humans and AI agents.

Publishable API keys (pk_ws_)

Simple Product now has two kinds of API keys, following the pattern you're used to from Stripe, PostHog, and others:

  • Secret keys (sk_ws_, sk_usr_) — full access. Keep these server-side.
  • Publishable keys (pk_ws_) — tracking only. Safe to expose in client-side code.

Publishable keys can only send analytics events — no read or write access to anything else. That means you can drop them into your React / Next.js bundle without worrying about someone inspecting the source and grabbing full access to your workspace.

Create one at Settings → API Keys → Create Key → Publishable.

We're eating our own dog food — Simple Product's own SDK now ships with a publishable key.

MCP usage tracking (automatic)

Every time an agent calls into Simple Product via the MCP server, a heartbeat now fires for the user whose token was used. That means MCP activity finally shows up in Analytics — Daily Active Users, Last Active times, retention — all without any client-side changes. Existing MCP installs pick this up automatically.

MCP server updates (v0.1.10)

We published a new version of @simple-product/mcp with a handful of improvements:

  • New getting_started tool — an onboarding guide agents can read to understand what Simple Product is and how to use the other tools effectively. Positioned as "read this first."
  • New get_card tool — fetches a card's full content including its description/body, so agents can actually read cards instead of just listing them.
  • Much better tool descriptions — every tool now explains when and why to use it, not just what it does. Helps agents pick the right tool on the first try.
  • Global install scopenpx @simple-product/mcp now installs the MCP at user scope, so it shows up across all your projects instead of just the directory you installed from.

Update existing installs with npx @simple-product/mcp@latest.

Board improvements

  • "Move to top" action on each card's ... menu. Great for curating long lists.
  • Smoother card drag-and-drop — the drop indicator no longer pushes layout around, so dragging feels stable instead of jumpy.

Navigation

  • Boards is now the default landing page when you enter a workspace.
  • SP3K moved to /sp3k alongside Chats and Projects, keeping the main nav focused on the product-building primitives (boards, docs, releases, customers, feedback, analytics).
  • App no longer shows the marketing footer — it only appears on public pages now.

Keep the feedback coming — the more we hear about what works and what doesn't, the faster we can iterate.

MCP Workspace Switching & Bug Fixes

MCP Workspace Switching

You can now switch between workspaces directly in conversation without restarting your AI coding assistant.

New tools:

  • list_workspaces - See all workspaces you have access to
  • switch_workspace - Switch to a different workspace instantly

How it works:

You: "What workspace am I in?"
AI: "You're in sp (Simple Product)"

You: "Switch to nexlayer"
AI: "Switched to Nexlayer! All subsequent commands will use this workspace."

You: "Create a doc called API Notes"
AI: [Creates doc in Nexlayer workspace]

No restart required - switching is instant and persists for future sessions.

How to Update

To use the new workspace switching feature, you'll need to update your MCP installation:

1. Reinstall the MCP package

npx @simple-product/mcp@latest --install

2. Restart your MCP-enabled app

  • Claude Code: Restart the terminal/CLI
  • Claude Desktop: Quit and reopen the app
  • Cursor/VS Code: Restart the editor or reload the window

After restarting, the new list_workspaces and switch_workspace tools will be available.


Bug Fixes

Google OAuth Integration Fixed

Fixed an issue where the Google OAuth redirect URI was incorrectly set to http://0.0.0.0:3000 instead of the production URL. This was blocking Google's OAuth verification process and could prevent Gmail/Calendar integration from working.

Last Active Date Now Updates Correctly

Fixed a bug where the "Last Active" date on contact profiles wasn't updating on subsequent visits. Previously, it only updated on the first heartbeat of each day - now it updates on every activity.


Technical Changes

  • Consolidated NEXT_PUBLIC_APP_URL into NEXT_PUBLIC_SITE_URL (one less env var to manage)
  • Added /api/mcp/workspaces and /api/mcp/switch endpoints
  • MCP package now uses mutable config state for hot switching
  • Updated to MCP package version 0.1.7

Projects - Organize work with AI-powered context

What's New

Projects let you group related items together and chat with AI that understands the full context of what you're working on.

Create Projects

  • Name your project and add custom instructions for AI
  • Link boards, cards, documents, feedback, people, organizations, and releases
  • Everything in one place for focused work

Project Chat

  • Chat with AI that has full context of your project
  • AI knows about all linked items, instructions, and relationships
  • Ask questions, get summaries, brainstorm ideas

AI Summaries

  • Generate AI summaries of your entire project
  • Based on linked items and project instructions
  • Refresh anytime as the project evolves

Board Linking

  • Link entire boards to a project
  • All cards from linked boards are automatically included in AI context
  • No need to link cards individually

Navigation Updates

  • New collapsible sidebar for SP3K (home view)
  • Route-based navigation for chats and projects
  • Improved URL structure: /chats, /chats/[id], /projects, /projects/[id]

Other Improvements

  • Document editor: double-click to edit, cleaner card styling
  • Better empty states throughout the app

GSD Feed & Setup Actions

What's New

⚡ GSD (Get Stuff Done) Feed

The workspace home now features an AI-curated feed that surfaces your most relevant work:

  • Smart ranking - Items scored by recency, ownership, and assignment
  • Unified view - See cards, docs, and feedback in one place
  • Quick navigation - Click any item to jump directly to it

🚀 Setup Actions

New users now see helpful onboarding tasks in the GSD feed:

  • Create your first board, card, and doc
  • Add a customer
  • Install the SDK and MCP
  • Set up feedback collection
  • Connect Google integration
  • Invite teammates
  • Customize AI instructions

Tasks automatically disappear as you complete them.

🔧 Improvements

  • Fixed MCP installation detection (no longer requires first use)

MCP: Claude Desktop Auto-Configuration

What's New

The Simple Product MCP installer now automatically detects and configures Claude Desktop.

How It Works

When you run npx @simple-product/mcp --install, the installer now:

  1. Detects if Claude Desktop is installed (macOS, Windows, or Linux)
  2. Automatically adds Simple Product to your claude_desktop_config.json
  3. No manual configuration needed

Supported Tools

The installer auto-configures all of these:

  • Claude Desktop (new!)
  • Claude Code (CLI)
  • Cursor
  • Windsurf
  • VS Code

Get Started

npx @simple-product/mcp --install

Then restart Claude Desktop to start using Simple Product tools.

Domain Migration & Bug Fixes

What's New

New Domain

Simple Product is now live at simpleproduct.dev! The old URL automatically redirects to the new domain.

Bug Fixes

  • Fixed chat scroll issue - Chats no longer scroll off the top of the screen
  • Fixed chat deletion race condition - Empty chats are now properly cleaned up using server-side validation
  • Fixed draft save errors - No more "Chat not found" errors when saving drafts

Performance Improvements

  • Optimized AI token usage - Reduced tokens per request from ~11k to ~4k by limiting message history to 15 messages and truncating long messages at 4000 characters. This helps stay within rate limits with more concurrent users.

Infrastructure

  • Added redirect server for seamless migration from old URL

Workspace Invite Notifications

What's New

When you add an existing Simple Product user to your workspace, they now receive an email notification letting them know they've been added.

Details

  • New users still receive an invite email with a link to create their account
  • Existing users now receive a "You've been added" email with a direct link to the workspace
  • No more wondering if your teammate knows they have access - they'll get notified automatically

Card Links Now Open Sidebar

What's New

When you click on a linked card from a document, you now go directly to that card with its details panel open - no extra clicking needed.

Before

Clicking a linked card took you to the board, but you had to find and click the card again to see its details.

After

Clicking a linked card takes you to the board with the card's sidebar already open, so you can immediately see all the details, linked docs, people, and related cards.


This is part of our ongoing work to make navigating between linked items feel seamless.

Hello World

Simple Product is now alive for testing and feedback!