Platform · Design notes

Designing products Claude can drive

The screen is one way in, not the only one. We are building every product so that anything it can do is reachable from a chat with Claude or another assistant. Here is the design, and why it is shaped the way it is.

The AI4Everyone team4 min read

Status: this post describes a design we are building. The shared layer it depends on does not exist yet. We will write again when it ships.

A lot of people now start their work in a chat window. They ask Claude to draft something, check something, or pull a few things together. If your product only works when someone opens its dashboard and clicks through it, it is invisible from where that work happens.

So we made a rule for the whole platform: every capability must be reachable from MCP and from chat, without a browser. No feature may live only behind a screen.

Getting that right is mostly a question of what you expose, and how. Here is the design.

Surfaces are adapters

The app, the HTTP API, an MCP server and a chat assistant are all surfaces. None of them is allowed to hold the real logic. Each one is a thin adapter that calls the same thing underneath:

app | HTTP | MCP | chat
  → surface adapter
  → operation
  → application service
  → domain
  → database

An operation calls the application service directly, with plain arguments. It never calls a web request handler. That keeps the work identical no matter how you arrived, and it means a new surface is an adapter, not a rewrite.

MCP is a protocol from one vendor, so we do not shape our declarations around it. The declaration is ours. MCP is one of the things we generate from it.

Operations are curated, not derived

The tempting shortcut is to turn every API route into a tool. We decided against it. Product Reviewer alone has hundreds of route handlers. Hand an assistant hundreds of tools and it spends its effort choosing between near-duplicates instead of doing the job.

Instead, each product will declare a curated set of operations, aiming for twenty to forty, that map to real jobs: "start an investigation", "draft a script from this idea", "schedule this approved video". One operation may span several routes. Simple lookups are exposed as MCP resources rather than tools, so they do not crowd the list of actions.

Each operation is declared with:

  • a namespaced name, and a summary and description written for a model to choose on;
  • input and output schemas, reusing the product's existing contracts;
  • the permission it requires, from the permission model we already have, not a second one;
  • its effect: read, write, external or costly;
  • which inputs must be resolved to real records, whether it is safe to retry, and how to undo it, where that is possible.
Close-up of hands soldering a small circuit board at a workbench
Most of the work is in the seams, not the screens. Image: AI-generated illustration.

Resolve first, then offer

If you ask Claude to "schedule the deep-sea video for Friday", something has to work out which video and which channel. That will not be left to the model's guess.

Every input an operation marks as needing resolution goes through entity resolution before the operation is offered. The system finds the actual record, or asks you to pick. Only then does the assistant get an action it can propose.

Writes are proposals

Reaching a product through chat changes nothing about who decides. An operation whose effect is write or external produces a proposal with a plain-language summary. Executing it is a separate, audited step. A model never writes directly.

This matters more in chat than anywhere else, because chat is full of text from elsewhere: pasted emails, crawled pages, forwarded messages. All of it is treated as data, never as instruction. We wrote about that rule in more detail here.

One registry, two kinds of server

We plan to run one MCP server per product, plus one platform server that exposes every product's operations together. Both will be generated from a single registry. Two hand-written servers that slowly drift apart is the mistake we are designing out.

Tool names stay fully qualified in both, so an operation behaves the same whether you connect to one product or to the whole platform.

The platform server composes; it never authors. It can list your Video and Product Reviewer work side by side, but it will not invent a tool that reads one product and writes into another. Each product owns its data and its rules, and can be split out on its own later without untangling the others.

Identity follows the same line. Each product keeps its own workspace records. The platform server is the only place that knows the same Google account owns a workspace in two products, and that knowledge never leaks into the products themselves.

What we are building now

The shared piece is a small layer for the operation type, the registry, and the generators that turn the registry into servers. It is the one thing we allow into the shared core before a second product needs it, because the platform server cannot exist without it. That layer is what we are building. Until it lands, none of this is something you can connect to.

There is a trade-off. A curated list means some things a route can do will not be reachable from chat until someone writes an operation for them. We think a short list of operations that a model can choose between reliably beats a long list it cannot.

The goal is simple to state. Whether you click, call the API or ask Claude, you reach the same operation, with the same permissions, and with the same proposal waiting for your approval.

Early access

Use it from the app, or from your assistant.

Tell us which product you want first and we will let you in as it opens.

Request early access