Skip to content
Tools— browse docs
On this page

Tools

What a tool is, what it owns, and the two places people meet it.

Say your table keeps rolling dice in a chat window and losing the results. You want a dice tray that lives in the world, remembers every roll, and shows the same numbers to everyone at the table. In vvd, that's a tool.

A tool is a capability that edits one kind of document. You declare which kind, you write a React component, and the platform handles the rest: connecting, syncing, merging two people's edits, undo, presence, permissions. Here's the whole thing — the code on the left is live, so change a number and watch the tray change.

You will learn

  • What makes a tool a tool, and what a single documentTypes line dispatches
  • Why one component renders both the panel and the embedded block
  • Which two files carry a tool, and what vvd.json declares about it
  • Where to go next for blocks, host capabilities, and server endpoints
A dice tray, entire
src/tool.tsx

Edit and the example re-runs. Tab indents; press Escape to leave the editor.

Running · your edits, live
Starting the example…

That example is the whole surface area of a working tool. Everything else in this section is a thing you can add to it.

A tool claims a document type

documentTypes is the only registration a tool needs. It's a list of slugs, and it means "when the world opens a document of this type, mount me."

documentTypes: ["dice-tray"]

Nothing else routes to your tool. There is no registry to edit, no route to add, no place where the platform learns your name twice. A world that installs your tool can create dice-tray documents; opening one mounts your render. That's the whole dispatch.

Most tools claim exactly one type. Claim more when they genuinely share an editor — a tool that renders both stat-block and stat-block-npc, say. Two types that need two different components are two tools.

Note:

One document at a time

Your render is handed one document and only ever sees that one. A tool that wants to show a list of other documents reads the world instead — see world blocks — but it still owns exactly one document of its own, or none.

One render, two faces

Here's the part that surprises people. You wrote one component, and the platform mounts it in more than one place:

  • As a document. Someone opens the dice tray from the sidebar and gets the panel — the full working view.
  • As a block. Someone drops the tray into a card body, a project page, or a wiki page, and the same component renders there, block-sized.

You don't write the second one. Your render reads context.view to find out which of the three views it's in — "editor", "embed", or "fullscreen" — and lays itself out accordingly.

This matters more than it sounds like it does, because the embed is where most people will meet your tool. A session-prep card with a dice tray in it gets opened far more often than the tray does on its own. Blocks is the page about designing for that first.

Where the code lives

A tool is a normal npm project the vvd CLI scaffolds and bundles for you. Two files carry everything this section talks about:

dice-tray/
├── vvd.json        the manifest — id, documentTypes, capabilities, needs
├── src/
│   ├── codec.ts    the document's shape (the ONE definition)
│   └── tool.tsx    defineTool + your component
└── api/            optional — server endpoints (see Server endpoints)

vvd.json for the tray above:

vvd.json
{
  "id": "dice-tray",
  "name": "Dice tray",
  "kind": "tool",
  "version": "0.1.0",
  "documentTypes": ["dice-tray"],
  "entryModule": "@/tool",
  "codecModule": "@/codec",
  "needs": [],
  "capabilities": { "readsWorld": false, "writesWorld": false, "sharing": false }
}

codecModule points at the one place your data model is written down. It's how vvd save derives what an agent can do with your documents and what's queryable about them, with nothing declared twice — see Making it agentable.

Note:

This section assumes Getting Started

Codecs, useDocument, reading the world, presence, and the CLI loop (vvd create → run → save → publish) are all in Getting Started. Everything here is what's specific to tools.

Recap

  • A tool is a capability that edits one kind of document; documentTypes is the only registration it needs.
  • One render is mounted in three views — "editor", "embed", "fullscreen" — and reads context.view to lay itself out.
  • src/codec.ts and src/tool.tsx carry a tool; codecModule in vvd.json points at the one place your data model is written down.

Next steps