Your notes app has a second user, and it isn't a person.
Fastpad is a block editor with an MCP endpoint and an fp CLI. Agents search, read and traverse your notes with a token scoped to the notes you picked. Every write they make lands as a proposal beside your text. Accepting is a separate call, and a token can make it only if you minted it with that grant — and then every accept is on the record for you to review or undo.
POST https://mcp.fastpad.aiMCP revision 2026-07-28
Every capability, from both sides.
There is no agent mode bolted onto a human app. The block tree, the links, the typed properties and the search index are one thing. The browser and the tool surface are two doors onto it.
Twelve composite tools, not thirty-two narrow ones, in a frozen and deterministically ordered list that must fit inside 5,000 tokens — a budget paid on every single conversation, and asserted in CI rather than intended.
| What you do | What an agent calls |
|---|---|
| Read your account page | fastpad_capabilitiesanyIdentity, granted scopes, your writable note set, limits. |
| Search from the command palette | fastpad_searchsearch:readIds, titles, paths, anchors and a snippet. Never bodies. |
| Open a note | fastpad_fetchnotes:readMarkdown with block anchors, or a digest with the prose stripped. |
| Follow backlinks until you have the picture | fastpad_contextnotes:readSeed retrieval, graph expansion, dedupe, rerank, packed to a budget. |
| Filter a collection view by property | fastpad_querynotes:readJSON filters, not a query language. Never bodies. |
| Open the backlinks panel | fastpad_graphgraph:readOne hop, every edge with its evidence. |
| Type | fastpad_proposenotes:proposeThe only write. Returns a turn id and a review URL. |
| Check a proposal you made | fastpad_turnnotes:readStatus and diff, on one of your own turns. |
| Open the review lane | fastpad_changesnotes:readThe change feed since a cursor. |
| Hover a block to see who wrote it | fastpad_historynotes:readOne entry — author, origin tier, review state. |
| Click Accept | fastpad_turn { action: "accept" }turns:acceptApplies the proposal to the note — only under a token you minted with this scope. The blocks it ratifies are marked agent-accepted, and the accept is listed for you to review.The scope is never in a default grant and only a person can mint it. What a token accepts stays marked agent-accepted — no retrieval floor above "any" admits it — until you mark it reviewed on the Agent activity page, where you can also revert it. Revert is a human session only. Without the scope, fp accept exits 8: "policy denied", and the documented meaning names the scope it lacked. |
An agent's write is a proposal. Accepting is a second, separate call.
When an agent writes, its ops commit to a container beside your block, not into it. The proposal is durable the moment it is made and it carries a turn id and a review URL. Your document is untouched until someone accepts — you, in a browser session, or the agent itself, but only under a token you minted with the accept scope. Either way the accept names who made it and how, and an agent's shows up on your Agent activity page.
This is not caution about model quality. An op applied to a note is durable and replicated to every connected device the instant it lands — so if injected content steered the agent, the injected text is on your phone before anyone has seen a diff. A proposal is the only shape where review happens before replication rather than after it, and that is why a token can neither write nor accept by default: both are grants you make on purpose.
There are exactly two exceptions, and both are grants.
Auto-apply: a token whose writes go straight into the document. Those blocks stay marked agent-written and unreviewed forever, so they never become something another agent can cite back to you as established fact. Accept: a token that may ratify its own proposals. Those blocks are marked agent-accepted, which no retrieval floor above "any" admits, and every such accept is written to the audit log and listed on the Agent activity page until you mark it reviewed or revert it. Neither grant makes a token a person, and neither can revert.
The same write, through three doors.
One proposal, made from a shell, from a model, and from curl. The payload is the same because the surface is the same — there is no second-class path for the CLI.
fp propose 01JBQ7W3ZK6MXNZ8V2Q4T7 \
--op 'replace:01JBQ7W3ZK6MXNZ8V2Q4T8' \
--text "Postgres 18.6, not 19 — pgvector 0.8.6 needs it."
# → turn 01JBQ8A1M4WPVR0C6E9H2K status open
# → review at https://www.fastpad.ai/turns/01JBQ8A1M4WPVR0C6E9H2K{
"name": "fastpad_propose",
"arguments": {
"note_id": "01JBQ7W3ZK6MXNZ8V2Q4T7",
"ops": [
{
"kind": "replace",
"block_id": "01JBQ7W3ZK6MXNZ8V2Q4T8",
"text": "Postgres 18.6, not 19 — pgvector 0.8.6 needs it."
}
]
}
}curl -sS https://api.fastpad.ai/mcp \
-H "authorization: Bearer $FASTPAD_TOKEN" \
-H "content-type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{"name":"fastpad_propose","arguments":{ }}}'Three things a token cannot do, structurally.
Not policy, not a prompt, not a model choosing to behave. Each one is enforced somewhere you can go and read.
It cannot widen its own reach.
Scope resolves to a concrete set of note ids when the token is minted, never to a live tag selector. An agent that can write and can tag cannot tag its way into a note you did not give it.
It cannot approve without being told it may — and you can see every time it does.
Accepting needs the accept scope, which is never in a default grant and which only a person can mint. Every accept a token makes is attributed to the agent and the token, written to the audit log, and shown on the Agent activity page. Reverting is a human session only, so the last word is always yours.
It cannot read a secret you wrote down.
Redaction is deterministic and happens on egress, never in your document. Your text keeps the token you pasted; the agent receives a placeholder.
Type in it. Nothing is saved.
This is the real editor — the same one the app mounts, not a picture of it. Press / for the block menu, or type three backticks and pick a language. There is no account, no note, no network request and no server on the other end of it.
Press / for the block menu. Everything you type stays in this browser tab.
Underneath it is a note app that takes structure seriously.
Structured blocks with typed properties, and collections and views over them. Real links and real backlinks from typed edges, not a text search run at render time. An outline, a command palette, and full-text and vector search behind one retrieval path the app and your agent both use.
Every block has a ULID minted at creation, and it survives editing — split a block and the id stays with the first half. That is what makes a link into the middle of a paragraph, or an agent's citation, still mean the same thing next month.
And it opens outward. Markdown export, a .md route for every note, and llms.txt for the whole workspace. Your content is not held hostage by the format it is stored in.
If you keep a vault
The same note, read twice.
One Markdown note, four wikilinks. Read it the way Obsidian does, then the way Fastpad does. Not a character changes — not a link, not the count. What changes is what each link is allowed to remember: which kind of connection it is, who made it, and the evidence for it. Pick a link and ask.
- [[ and @ open the link menu
- Backlinks, grouped, in a panel
- A local graph, two hops out
- Markdown you can export
- Stable ids that survive an edit
A link is a link.
Q3 pricing decision
· · ·
Why is this connected?
Pick a link to ask what it is.In this reading there is only one answer.
The ten relations an edge can be:
links_tomentionschild_oftaggedcitesderived_fromsupersedescontradictssemantically_nearagent_inferred
If you keep a vault, you already know how to use this. Obsidian got wikilinks, backlinks, the graph and plain files right, and we did not change them. In Obsidian a link is a link, and that simplicity is why a vault is quick to build and easy to trust. We changed one thing: what a link is allowed to remember. The same link here also carries a relation — one of ten, including supersedes and contradicts, two things a wikilink has no word for — plus who made it, whether it was asserted or only inferred, and the evidence, stored when the edge was made rather than invented when you look at it. Inferred edges are drawn as guesses and fade unless you solidify them, so an agent can suggest a connection without touching your graph. That is the same rule as the rest of this page: propose, never overwrite.
What you give up, in both directions.
Notion's structured blocks, Obsidian's linking and file ownership, and an agent platform neither ships — that is an honest description of the ambition, not of the maturity.
If you are not running agents against your notes, this page is solving a problem you do not have.
If you are, the alternative today is handing a model your whole vault and hoping. The exit codes exist for the same reason: a CLI that always exits 0 cannot be used in a shell script with set -e without parsing prose.
We have no logos to show you.
Fastpad launched this year. Any customer wall, usage figure or testimonial here would be invented, and on a page about whether you can trust a write boundary, one invented number would poison every real claim around it.
So here is what a new product can honestly offer instead: a surface that describes itself, and documentation that pins down what it does — including the parts that are unflattering.
Call fastpad_capabilities before you sign up. It answers without a token.
Mint a token. Point something at it.
Three steps, and the third one is a person clicking Accept — or reading what an agent accepted.