Documentation
Everything you can do with Forward.
Forward keeps your UI design, backend documentation, architecture, data models and project work together as plain JSON in .forward/, inside your own git repository. You author it from the canvas, VS Code, or an AI agent. This guide walks through every layer and every surface.
Start here
Getting started
Set Forward up in an existing repository, open the canvas, commit the project, and connect your editor and agents.
- Install the CLI. Forward needs Node 22 or newer. Install it globally with
npm i -g forward-mcp, which adds two commands to your PATH:forward-mcp(the MCP server) andforward(the CLI). Or skip the install and prefix each command withnpx -y -p forward-mcp. - Initialize your repository. In the repository root, run
forward init. It creates.forward/, the agent wiring (AGENTS.md,CLAUDE.md,.mcp.json,.cursor/mcp.json) and the GitHub workflow.--no-agentsand--no-githubskip those. - Open the canvas. Run
forward serve. It serves the design editor athttp://127.0.0.1:4747(add--opento launch your browser) and writes every edit straight to.forward/. - Commit the project. Add
.forward/and the generated files and commit them with your code. From here on, Forward changes travel through branches and pull requests like any other change. - Connect an agent. Claude Code and Cursor pick up the generated configs; for others see AI agents. Restart the agent session after adding the server.
- Install the VS Code extension. Get Forward on the VS Code Marketplace; it finds
.forward/in the open repository on its own (see VS Code extension).
# in the root of your repository (Node 22+)
npm i -g forward-mcp
forward init
forward serve # http://127.0.0.1:4747
git add .forward/ AGENTS.md CLAUDE.md .mcp.json .cursor/ .github/
git commit -m "Add Forward"What lands in your repository
The whole project is one directory, one file per record, so merges stay clean and pull-request diffs stay readable:
| Path | Holds |
|---|---|
| forward.json | The project manifest: id, name, format version. |
| design/<id>.json | Design elements, each with its optional apiBinding docs. |
| history/<elementId>/… | Append-only API-doc history, one file per version. |
| infra/nodes, infra/edges, infra/flows | The infrastructure graph and narrated flows. |
| data/entities, data/relations | The ER data model. |
| agents/agents, agents/servers | Agents and the MCP servers they call. |
| tasks/<id>.json | The task tracker. |
| checkpoints/<id>.json | Named, restorable snapshots of design and infra. |
| dismissed/<id>.json | Code drafts someone deleted, so capture doesn't recreate them. |
| assets/<sha256>.<ext> | Image bytes for image fills, named by their hash (PNG, JPEG, WebP, GIF or AVIF, up to 5 MB; location metadata stripped). |
The project id is the id in .forward/forward.json. Every tool finds the project by looking for the nearest .forward/ above the current directory (or the repository named by FORWARD_REPO).
Mental model
Core concepts
Forward is built from seven intentionally-separate layers. The design layer is primary and stands on its own; every other layer is optional and either attaches to a design element or links to one by id.
Understanding these seven layers makes the rest of the product obvious: every feature is one of them, and every surface (canvas, VS Code, agent, CI) speaks the same shapes, validated by the same schemas on every read and write.
| Layer | What it is |
|---|---|
| Design | The frames, shapes, text, components and instances a designer draws, with geometry and a parent/child hierarchy. The primary artifact; everything else hangs off it. |
| API binding | An optional title + Markdown description attached to a design element. Docs-first and framework-agnostic; an endpoint is never a first-class canvas object. |
| Infrastructure | A project-wide graph of nodes (apps, services, databases, caches, queues) and edges, rendered as an overlay. |
| Flows | Narrated, ordered hops across the infra graph; a hop can tie to an endpoint. Serializes to a Mermaid sequence diagram. |
| Entities (ER) | A project-wide data model of tables, fields and crow's-foot relations. Serializes to a Mermaid erDiagram. |
| Tasks | A tracker of work items that can each link into another layer: an element, a flow or an endpoint. |
| Checkpoints | Named, restorable snapshots of the whole canvas (design + infra), each with a note and per-layer change counts. |
Links between layers are soft references, resolved on read and never enforced as foreign keys. forward validate reports dangling ones as warnings.
A related, project-scoped Agents layer lets you document the MCP servers and AI agents your project builds or consumes (see AI agents), modelled the same way as the seven above.
On top of the layers sit the timelines: a per-element history of documentation changes and a project event feed built from git log. Together they power the History view, doc diffs and the catch-up digest (see History & checkpoints).
Design layer
The design canvas
A design editor for the interface. Draw it, then let every other layer attach to what you drew.
The canvas is where the design layer lives and where the API, infra, data and task overlays render on top of it. Run it with forward serve, open it inside VS Code with Forward: Open Design Canvas, or browse the read-only copy your GitHub Pages site publishes.
Element types
Every element you draw is one of six types:
| type | What it is |
|---|---|
| frame | A container / screen; establishes hierarchy, nest anything inside it. |
| rectangle | A generic box: buttons, cards, inputs. |
| ellipse | A circle / oval, drawn within its bounding box. |
| text | A text label. |
| component | A reusable master definition. |
| instance | A placed copy of a component (links back via componentId). |
What an element stores
| Field | Meaning |
|---|---|
| id, type, name | Identity and the element type above. |
| x, y, width, height | Absolute geometry in canvas space. |
| z | Stacking order among siblings: higher paints on top. |
| rotation | Degrees clockwise about the element's center (default 0). |
| parentId | The containing element, or null at the top level; this is the layer tree. |
| text | Text content (for text elements). |
| style | Fill, stroke (width/style, per-side), corner radius (uniform or per-corner), font size/weight/family/color. |
| componentId | For an instance: the source component's id. |
| apiBinding | The optional backend documentation attached to this element (see below). |
| origin | Set on drafts generated from frontend code (see Designs from code); gone once a draft is adopted. |
| updatedAt | ISO-8601 timestamp of the last write, stamped by Forward rather than the client. |
Because geometry is absolute and hierarchy is a plain parentId, the layer rail reflects a real tree. Select an element to open its API drawer, inspect its overlays, or view its history.
Toolbar, overlays & view controls
The left rail doesn't hold drawing tools; shapes come from the keyboard or the right-click menu. Instead it toggles the panels and overlays that sit on top of the design:
| Toggle | Opens |
|---|---|
| Layers | The design-tree sidebar (the element hierarchy). |
| Docs | Endpoint badges on documented elements + the API drawer. |
| Infra | The infrastructure graph overlay and its editing drawer. |
| Data | The entity/ER overlay and its editing drawer. |
| Flows | The narrated flows as sequence diagrams (Mermaid), one per flow. |
| Agents | The agent / MCP-server wiring diagram. |
| History | The project timeline panel (see History). |
| Tasks | The task-tracker panel. |
| Theme | The view-theme editor: per-user, stored locally, never committed. |
| People | The read-only list of git contributors (see Access & sync). |
A zoom bar (− / + / Fit) sits over the stage, and a live-sync indicator shows the connection to the local server. Changes an agent writes through MCP while the canvas is open show up within a couple of seconds. Right-click anywhere on the canvas for the Add element menu: the same catalog the keyboard shortcuts arm, nested at the point you clicked.
Drawing & keyboard shortcuts
Select is the default mode. Press a tool key, then drag on the canvas to size the new element (single-key shortcuts; they're ignored while you're typing in a field):
| Key | Action |
|---|---|
| V | Select / move. |
| F | Draw a frame. |
| R | Draw a rectangle. |
| O | Draw an ellipse. |
| T | Add text. |
| ⌘S / Ctrl+S | Save a checkpoint (opens the save modal; see Checkpoints). |
| Delete / Backspace | Delete the selected element. |
| Escape | Deselect / close the open dialog. |
API binding layer
API documentation
Attach framework-agnostic Markdown docs to any design element, so an endpoint stays tied to the interface it powers and the docs can't drift away from the UI.
An API binding is just a title and a Markdown description. Most elements never get one; the ones that do become the anchor for backend documentation. You can author bindings from the canvas, but the intended home is the VS Code extension and the MCP server, where the backend actually lives.
The binding shape
A binding is deliberately tiny, two fields:
| Field | Meaning |
|---|---|
| title | A one-line label, e.g. POST /api/checkout. |
| description | The full Markdown body: request/response shape, status codes, notes. Anything the reader needs. |
That's it. There's no enforced HTTP method or path: you can write GET, POST, PUT, PATCH or DELETE in the title, or document a GraphQL resolver, a gRPC call, a CLI command or a background job the same way. The Markdown carries the meaning.
Why docs-first
- Framework-agnostic. There's no OpenAPI import or route scanner to keep happy.
- Tied to the UI. The doc is attached to the element it describes, so it's discoverable from the design.
- Versioned. Every edit is appended to the element's history as its own file, with a reviewable, git-style diff (see History). Two branches that both document endpoints merge without conflicts.
Who wrote each version is decided by Forward, not the client: your git user.name (or FORWARD_AUTHOR), plus via <agent> when FORWARD_AGENT is set.
Infrastructure & flow layers
Infrastructure & flows
Model your architecture as one project-wide graph, then narrate how a request travels across it.
The infrastructure graph
Add nodes and connect them with edges. Unlike the design layer, the infra graph is project-scoped and isn't attached to any one element; it renders as its own overlay and serializes to a Mermaid component diagram. Each node has a kind that drives its colour and icon:
| kind | Represents |
|---|---|
| frontend | Web / mobile client. |
| backend | API server / app service. |
| database | SQL / NoSQL store. |
| cache | Redis, Memcached… |
| queue | Kafka, SQS, RabbitMQ… |
| service | Internal microservice. |
| devops | CI/CD, container, IaC, monitoring. |
| external | Third-party dependency. |
| actor | A person (user, admin) who starts a journey; not a system component. |
| group | A container box that visually groups other nodes. |
A node carries a label, an optional tech tag (e.g. "v15", "Node 20"), a Markdown description, geometry, and a parentId to nest it inside a group. An edge is just from → to node ids with an optional label.
Narrated flows
A flow has a name, a Markdown overview and an ordered list of steps. Each step is a hop from one infra node to another ("place order", "register", "checkout") and can carry an endpointId that ties the arrow to a documented endpoint (turning a generic arrow into "called by POST /auth/verify"). Every step has a call style:
| kind | Meaning | Mermaid arrow |
|---|---|---|
| sync | A request that waits for a response. | ->> |
| async | Fire-and-forget / a publish. | -) |
| reply | A response back to the caller. | -->> |
A step can also carry an optional condition, a branch guard like "session valid" or "409 duplicate". Consecutive steps that share one condition render together as a Mermaid alt/else block, so a flow can show conditional paths, not just a straight line.
Flows render as numbered arrows across the graph and serialize to a Mermaid sequenceDiagram you can drop straight into a design doc. Agents get both diagrams as Mermaid from list_infra and list_flows.
Entity layer
Data models
Entity-relationship diagrams with tables, fields and crow's-foot cardinality, versioned with the rest of the project.
Define entities (tables with fields) and relations between them. Like infra, the data model is its own project-scoped graph.
Fields & keys
Each entity holds a list of fields, and every field has a name, a free-form type (e.g. "uuid", "varchar", "int"), an optional note, and zero or more key roles:
| key | Role |
|---|---|
| PK | Primary key. |
| FK | Foreign key. |
| UK | Unique key. |
Relationships (crow's-foot)
A relation is directed (from → to entity), carries a verb label, and has a cardinality at each end:
| cardinality | Meaning |
|---|---|
| zero-or-one | Optional single (|o). |
| exactly-one | Required single (||). |
| zero-or-many | Optional many (}o). |
| one-or-many | Required many (}|). |
An identifying flag picks the line style: solid when the child can't exist without the parent, dashed otherwise. The whole model serializes to a Mermaid erDiagram, easy to review in a pull request, version alongside code, and keep next to the API docs and architecture it supports.
Task layer
Task management
Track the work next to the system it belongs to. Every task can link to a design element, a flow or an endpoint, for traceability from planning to implementation.
Status, type & priority
Three independent enums classify every task:
| Field | Values |
|---|---|
| status | todo · in_progress · blocked · done |
| type | bug · feature · task · milestone (a zero-duration marker, drawn as a diamond) |
| priority | low · medium · high · urgent |
What a task carries
| Field | Meaning |
|---|---|
| key, title | A short human key (e.g. FWD-12) and the title. |
| description | Free-form Markdown detail. |
| labels | Free-form label names (e.g. "backend"). |
| assignees, reporter | The people doing the work (contributor names from list_members), and who filed it, stamped from your git identity. |
| startDate | Optional planned start, an ISO date (2026-11-02). Without it the timeline starts the task on the day it was filed. |
| dueDate | An ISO date (2026-11-06); for a milestone, its target date. A free-form label is rejected. Tasks filed before this rule keep their old label until it's changed, and forward validate warns about them. |
| dependsOn | Ids of tasks that should finish before this one starts (finish-to-start). |
| elementId | Optional link to the design element the task concerns. |
| flowId | Optional link to the narrated flow it implements. |
| endpointId | Optional link to the element whose apiBinding defines the endpoint. |
| activity | Chronological feed of comments and events (oldest first). |
| createdAt, updatedAt | Timestamps stamped by Forward. |
forward validate flags it as a warning.Views
Work the list in the canvas's Tasks panel. Because tasks link into the other layers, you always know which design, flow or endpoint a piece of work maps to. Agents use create_task, update_task and comment_task on the same tracker.
Switch the panel to Timeline for a Gantt chart: each task is a bar from its start date to its due date, grouped by status and filled by progress; milestones are diamonds; and dependencies are connectors, drawn red when a task starts before something it depends on is due. The exported read-only site shows the same timeline. get_task_timeline returns the schedule as a Mermaid gantt chart with its warnings, and the PR digest lists tasks whose dates moved. forward validate warns about dependency cycles, and about assignees who aren't on the contributor roster.
Timelines & snapshots
History & checkpoints
The project remembers everything: every documentation edit is a reviewable diff, the activity feed is your git log, and you can snapshot and restore the whole canvas.
The History timeline
Two timelines drive it: an append-only, per-element history of API documentation (one file per version under .forward/history/), and a project event feed built from git log plus your uncommitted changes, so commit messages show up in it. Forward flattens them into one chronological stream, lays it out as a git-graph, and colours each event by the layer it came from:
| domain | Source |
|---|---|
| design | Design-element changes. |
| api | API binding (documentation) changes. |
| infra | Infrastructure node/edge changes. |
| flow | Narrated flow changes. |
| agent | Agent / MCP-server changes. |
Each event records its action (created, modified or deleted) plus the author, timestamp and a one-line detail, so you can see who changed what, when, across every layer.
Doc diffs
Each edit to an API binding is a git-style diff: a title change plus a line-level Markdown diff between two versions. Expand any revision to review exactly what moved: added rows are green, removed rows red, and a +a −r badge summarizes the change on the collapsed card. A diff can also be flagged breaking, which surfaces a warning callout so consumers know clients may need changes. Even a deleted endpoint stays labelled, because each history entry keeps a snapshot of the endpoint as it was written.
Catch-up digest
Pick a baseline (the last day, week, month, or all time) and Forward collapses the event stream into a digest of what's to integrate, to modify and to remove: the fast way for a frontend dev to catch up on backend changes. The canvas timeline and get_catchup_digest show the same digest.
To compare against a git ref instead, run forward diff origin/main (any branch, tag or commit). It lists new, changed and removed endpoints with doc diffs, plus a per-layer summary of everything else, as Markdown or JSON. Agents call the same comparison as get_changes_since_ref, and the GitHub Action posts it on every pull request.
Checkpoints
A checkpoint is a deliberate, whole-canvas save: a title, a Markdown note, and a frozen copy of the design + infra graph you can restore later. Create one from the canvas with the Save button or ⌘S / Ctrl+S. Each is tagged milestone, checkpoint or wip, and its card shows per-layer change counts (e.g. DESIGN +8 API +3). Checkpoints are files too (.forward/checkpoints/), so they're committed and shared like everything else.
Design layer · from code
Designs from code
Ideally the frontend is built from the design. When a screen was built first, Forward can draw it for you from the running app.
forward capture renders your running frontend, reads back what the browser actually painted (position, size, colours, borders, corners, fonts, text, stacking) and turns it into canvas elements: one frame per route, a box for everything that paints, text for every run of text. Wrappers that paint nothing are dropped, so the layer tree stays readable. React dev builds also report which component rendered each node, so repeated components become a component plus instances.
forward capture --browsers # which browsers it can use here
forward capture http://localhost:5173 / /login /settings --dry-run
forward capture http://localhost:5173 / /login /settings
forward capture http://localhost:5173 /settings --auth state.json --viewport 390x844
forward capture http://localhost:5173 / --browser edgeWhich browser it uses
| Engine | When |
|---|---|
| The project's Playwright | Used first when the project has Playwright installed. |
| An installed Chromium browser | Chrome, Edge, Brave, Chromium, Vivaldi or Opera. Nothing is installed or downloaded. It runs headless with a fresh, temporary profile (never your own cookies, logins or extensions), is controlled over a pipe so nothing listens on the network, and is closed with its profile deleted when the capture ends. |
| The forward-capture companion | Only when there is no Playwright and no Chromium browser (a server, a container, some CI). It runs npx -y forward-capture@<version> at the CLI's exact version and downloads Playwright's headless Chromium once (about 100 MB); npx -y forward-capture install fetches it ahead of time. |
| Any browser, by hand | Firefox and Safari can't be driven this way. forward capture --script prints a snippet to paste into the DevTools console; it downloads forward-snapshot.json, which forward capture --from forward-snapshot.json imports. |
--browser picks one explicitly (a name or a path), FORWARD_BROWSER sets the default, and FORWARD_NO_DOWNLOAD=1 forbids both downloads. Agents call the same capture as import_design_from_code.
Drafts, and what a re-capture never does
- Drafts. Generated elements are marked from code on the canvas. Re-running a capture updates them in place, and API docs attached to a draft are kept.
- Stable identity. An element keeps its identity by its
data-testid,id, the JSX line that rendered it (React dev builds) or itsaria-label; failing those, by its position under the nearest element that has one. When the page around a draft shifts, drafts are re-matched by type, name or text, size and contents, as long as the match is unambiguous. - Docs never move on a guess. If a documented draft can't be matched for certain, it stays where it was (stale, docs intact) and the capture reports it. Test ids on repeated or generic elements make identity certain.
- Edits win. A draft someone has moved, restyled or renamed is never overwritten; the import reports it as a conflict. Adopt draft (inspector or right-click menu) turns a draft into an ordinary element that imports never touch again.
- Deletions stick. Deleting a draft remembers it in
.forward/dismissed/, so the next capture doesn't bring it back;--restoredoes. - Stale drafts. Drafts the code no longer renders are reported as stale.
--pruneremoves them, but never one that is documented, edited, adopted, or holds something that stays. - Anchors, opt-in.
--anchorsadds// @adc <id>markers above each component's declaration in your JS/TS source, soresolve_anchorslinks code to design. It edits source files, so it is off by default.
--auth state.json loads a saved browser state for pages behind a login.Surface · editor
VS Code extension
Document the backend where the backend lives. Attach Markdown docs to design elements without leaving your editor.
- Install the extension. Get Forward from the VS Code Marketplace and open your repository.
- Initialize, if needed. If the repository has no
.forward/yet, run Forward: Initialize Project in This Repository, orforward initin a terminal (which also writes agent configs and the GitHub workflow). - Document. Use the Forward commands to document an endpoint on an element, edit infra, flows and agents, and file, schedule or update tasks, all from the editor. What
forward validatewould flag in CI shows in the Problems panel as you work. Insert Anchor at Cursor drops an@adccomment (pick the element by name) so the code↔element link lives in the source: the same anchor CI and MCP agents resolve.
.forward/ in-process. There is no server URL or project picker, and access is whatever your git host grants.Everything you write is a file change in .forward/. Commit it with the code it describes, and the canvas, your teammates and any agent read the same files. Open Design Canvas shows the design with your API docs and diagrams overlaid, right inside VS Code, and its Timeline opens the endpoint git-graph and catch-up digest.
Surface · AI agents
AI agents (MCP server)
Give any AI assistant full parity with the canvas and the extension: 49 tools over the same .forward/ files, over MCP or from the shell.
The forward-mcp server exposes 49 tools so an agent can create and maintain every artifact (documentation, architecture, data models, tasks, even the design) exactly as a human contributor does. It runs over stdio from the repository root and finds the nearest .forward/; there is nothing else to configure. The full list is in the reference.
Connect it
forward init (or forward agents later) writes the wiring into your repository:
| File | For |
|---|---|
| AGENTS.md | Instructions every agent reads: when and how to document endpoints, infra and schema. |
| CLAUDE.md | Imports AGENTS.md for Claude Code. |
| .mcp.json | Registers the Forward MCP server for Claude Code. |
| .cursor/mcp.json | Registers it for Cursor. |
| .vscode/mcp.json | Registers it for VS Code / Copilot (forward agents --vscode). |
To register by hand with Claude Code, run this from the repository root (the extension's Forward: Set Up MCP for AI Agents copies the same line):
claude mcp add forward -- npx -y forward-mcpCodex reads AGENTS.md; register the server in ~/.codex/config.toml:
[mcp_servers.forward]
command = "npx"
args = ["-y", "forward-mcp"]
env = { FORWARD_AGENT = "codex" }Any other MCP client runs npx -y forward-mcp over stdio. Set FORWARD_REPO only when the client doesn't start the server inside the repository, and FORWARD_AGENT to tag writes with the agent's name.
Without MCP: the same tools from the shell
The CLI calls the very same tool code in-process, so a script or an agent without MCP gets identical behaviour:
forward tools # list all 49 tools
forward tools write_documentation # one tool's arguments
forward call write_infra_node '{"kind":"cache","label":"Redis"}'
forward call get_changes_since_ref '{"ref":"origin/main"}'Any tool also runs as a command of its own, with its arguments as flags; forward tools <tool> lists them.
Finding the right element
Good first calls are project_info, find_element, write_documentation, validate_project and get_changes_since_ref. There are two ways to answer "which design element does this code belong to?":
- Fuzzy:
find_element. Ranks elements against a feature description. No setup, but confirm with the user when the score is low or two candidates are close. - Deterministic:
resolve_anchors. Resolves@adc <elementId>markers in your source to their elements, and flags anchors whose id doesn't exist, catching typos and stale links.
Document the agents your project uses
Beyond connecting an agent, Forward has an Agents layer for documenting the AI surface your project builds or consumes, its own project-scoped graph like infrastructure. You can model:
| Node | What it captures |
|---|---|
| MCP server | A label, transport (stdio · http · sse), origin (built by your project vs consumed third-party), and the list of tools it exposes. |
| MCP tool | A name + Markdown description; an optional endpointId ties the tool to the documented endpoint it wraps. |
| Agent | A label, the model it runs on, a diffable systemPrompt, and the ids of the MCP servers it's wired to. |
An agent's system prompt versions and diffs in the History timeline like an API binding, so your agent definitions get the same reviewable history as the rest of the project.
Git-native
Access & sync
There is no central server and no database. Git is the sync, the history and the access control.
Every surface speaks one REST contract. Forward serves it from the files in .forward/: in-process for the MCP server, CLI, VS Code extension and CI, and over a small local HTTP server that forward serve runs for the canvas.
Who can change the project
- Push access is edit access. Whoever can push to the repository can change the project, and branch protection and required reviews apply to
.forward/like any other path. - The roster comes from git. The canvas's People view and
list_memberslist everyone who has committed to.forward/, with.mailmapapplied. To assign work to someone before their first commit, declare them withadd_person(a file in.forward/people/); it grants no access. A shallow clone sees only part of the history, and says so. - Authorship is stamped, not claimed. An author a client sends is ignored. Your git
user.namedecides who wrote it (FORWARD_AUTHORoverrides, andFORWARD_AGENTappendsvia <agent>).
How changes travel
Edits land as file changes in your working tree. Everyone on the same checkout (you on the canvas, an agent over MCP, the VS Code extension) sees them straight away; everyone else gets them through commits, pull requests and merges, exactly like code. One file per record and separate history files keep those merges clean, and git checkout -- .forward/ is the undo.
The local canvas server
forward serve keeps no user list, so it defends itself instead:
- It binds to loopback (
127.0.0.1) by default. - Every API call must carry a random per-session key that only the served page knows, so another site can't drive it.
- It rejects unexpected
Hostheaders, which defeats DNS rebinding.
--host 0.0.0.0 (or ::) exposes the canvas on your network and turns off the Host check. Anyone who can reach the port can open the page and edit the project, and so can any website you visit while it runs (DNS rebinding). Keep the default unless you need it, and stop the server when you're done.Fit it to your process
GitHub Action & CI
Validate the project on every pull request, post a catch-up digest for reviewers, publish a read-only canvas to GitHub Pages, and optionally let your own AI write the docs.
The Forward workflow
forward init (or forward github later) writes .github/workflows/forward.yml, which uses Forward's composite action:
- On pull requests it runs
forward validate, annotating schema errors inline, then posts one comment, updated on every push, listing new, changed and removed endpoints with doc diffs and a per-layer summary of everything else. - On the default branch it builds a static, read-only canvas with
forward exportand deploys it to GitHub Pages. Turn Pages on with Source: GitHub Actions.
Action inputs
| Input | Meaning |
|---|---|
| path | Repository root that contains .forward/ (defaults to the checked-out repository). |
| validate | Run forward validate and fail on schema errors (default true). |
| strict | Also fail on warnings: dangling cross-layer links, assignees who haven't committed to .forward/, task due dates that aren't ISO dates, dependency cycles (default false). |
| comment | On pull requests, post or update one comment with the catch-up digest (default true). |
| base | Git ref to diff against; defaults to the pull request's base commit. |
| export | Directory to write the static canvas into, for GitHub Pages; empty skips it. |
| cli-version | forward-mcp version to run from npm; empty builds the CLI from the action's own source. |
| github-token | Used to post the PR comment (defaults to the workflow's token). |
The digest's Markdown path is exposed as the digest output and also written to the job summary, so fork pull requests (which get a read-only token) still see it.
Let your own AI write the docs
The bring-your-own-AI pipeline, forward-docs, keeps API docs, ER, infrastructure, flows and agents in sync with the code on every pull request, without locking you into any particular AI:
- Your AI writes a plan. Any provider reads the diff plus the
FORWARD_DOCS.mdinstructions and writesforward-docs.json. It never edits.forward/itself. forward-docs applywrites it. Deterministic, no AI: it fills in geometry and timestamps, re-validates every object against the schema, and writes nothing if the plan is malformed. Re-runs update in place via@adcanchors and stable ids.- The result is committed back to the PR. Reviewed and merged with the code; git is the undo.
# .github/workflows/forward-docs.yml (from the template)
- uses: dsasante1/forward/apps/docs-ci@docs-ci-v2
# inputs: commit, commit-message (see the template)The template runs on pull requests from the same repository; your AI step needs your provider's key as a repository secret. A pull request's diff is untrusted input, so give the agent the narrowest tools that work (file read/write rather than a shell). An agent that has the Forward MCP server connected can skip the JSON plan and edit through its tools instead.
forward diff <release-tag> the release tag itself becomes a natural "since last release" baseline.Reference
CLI & settings
Quick lookup for the CLI commands, environment variables, VS Code commands and the MCP tools.
CLI commands
| Command | What it does |
|---|---|
| forward init | Create .forward/ here, plus agent configs and the GitHub workflow. Flags: --name, --id, --no-agents, --no-github. |
| forward serve | Open the canvas editor on .forward/. Flags: --port 4747, --host 127.0.0.1, --open. |
| forward validate | Check every file (CI runs this); exits 1 on errors, or on warnings too with --strict. Flags: --format text|json|github, --strict. |
| forward diff <git-ref> | What changed since a ref: the catch-up digest for a PR. Flags: --format markdown|json, --out <file>. |
| forward export | Build a read-only static site for GitHub Pages (images the design uses go to images/). Flags: --out _site, --no-history. |
| forward assets [prune] | List the images in .forward/assets/ and whether anything uses them, or delete the unused ones. Flags: --dry-run, --json. |
| forward capture <url> [route …] | Generate design drafts from a running frontend. Flags: --browser, --viewport 1440x900, --auth state.json, --prune, --restore, --anchors, --images, --no-components, --dry-run. |
| forward capture --browsers | List the browsers live capture can use on this device. |
| forward capture --script | Print a DevTools snippet that captures the page in any browser (--route /path). |
| forward capture --from <snapshot.json> | Import snapshots saved by that snippet (with --prune, --restore, --anchors, --dry-run). |
| forward agents | Write AGENTS.md / CLAUDE.md and MCP configs (all by default). Flags: --claude, --cursor, --vscode, --agents-md. |
| forward github | Write .github/workflows/forward.yml. |
| forward mcp | Serve the agent tools over MCP stdio (same as forward-mcp). |
| forward tools [<tool>] | List the agent tools, or one tool's arguments (--json). |
| forward call <tool> ['<json>' | -] | Run an agent tool from the shell (same code as MCP). Each tool also runs directly as a command, with its arguments as flags; forward <tool> --help shows them. |
| forward call --batch <file | -> | Run many tool calls in one process: a JSON array or JSON Lines of {"tool", "args", "as"} steps, where "$name.id" in an argument is an earlier step's result. |
Environment variables
| Variable | Purpose |
|---|---|
| FORWARD_REPO | Use this repository instead of searching up from the working directory. |
| FORWARD_AUTHOR | Name stamped on writes (default: git user.name, then your OS login name). |
| FORWARD_AGENT | Agent name added to the author, e.g. Ada via claude. |
| FORWARD_BROWSER | Default browser for live capture: a name (chrome, edge, brave, chromium, vivaldi, opera) or a path. |
| FORWARD_NO_DOWNLOAD | Set to 1 to forbid fetching the forward-capture companion and Playwright's Chromium. |
| FORWARD_CAPTURE_BIN | Path to a specific forward-capture companion to run, e.g. for air-gapped setups. |
VS Code commands
| Command | What it does |
|---|---|
| forward.initRepo | Initialize a Forward project in this repository. |
| forward.setupMcp | Copy the claude mcp add … line that connects an AI agent. |
| forward.openCanvas | Open the design canvas. |
| forward.connectEndpoint | Document an API on a design element. |
| forward.insertAnchor | Insert an @adc anchor at the cursor; pick an element by name, no id to transcribe. |
| forward.removeDocumentation | Remove API documentation from an element. |
| forward.showHistory | Show an endpoint's documentation history. |
| forward.catchUp | Catch up on endpoint changes since a baseline. |
| forward.addInfraNode | Add an infrastructure node. |
| forward.linkInfraNodes | Link two infrastructure nodes with an edge. |
| forward.removeInfraNode | Remove an infrastructure node. |
| forward.addFlow | Add a narrated flow (sequence diagram). |
| forward.addFlowStep | Add a step to a flow. |
| forward.removeFlow | Remove a flow. |
| forward.addMcpServer | Add an MCP server to the Agents layer. |
| forward.removeMcpServer | Remove an MCP server. |
| forward.addAgent | Add an agent to the Agents layer. |
| forward.removeAgent | Remove an agent. |
| forward.createTask | Create a task, with optional start and due dates, dependencies and an element link. |
| forward.updateTaskStatus | Update a task's status. |
| forward.updateTask | Change a task's dates, dependencies, priority or type. |
| forward.showTaskTimeline | Open the canvas on the task timeline (Gantt). |
| forward.validate | Check .forward/ as forward validate does; problems show in the Problems panel and update as files change. |
The one setting, forward.openCanvasOnStartup, opens the design canvas when VS Code starts (only in a folder with a .forward/ project).
MCP tools
The 49 tools the Forward MCP server exposes to an agent, by area. forward tools <tool> shows any one's arguments.
| Area | Tools |
|---|---|
| Project | project_info validate_project get_changes_since_ref list_members add_person remove_person |
| Design | list_design_elements find_element resolve_anchors create_design create_element update_element delete_element import_design_from_code set_element_image list_images |
| API docs | get_documentation write_documentation remove_documentation get_history get_catchup_digest |
| Infrastructure | list_infra write_infra_node connect_infra remove_infra_node |
| Flows | list_flows write_flow add_flow_step remove_flow |
| Data models | list_entities write_entity relate_entities remove_entity |
| Agents layer | list_agents write_mcp_server write_agent remove_mcp_server remove_agent |
| Tasks | list_tasks get_task get_task_timeline create_task update_task comment_task delete_task |
| Checkpoints | list_checkpoints create_checkpoint restore_checkpoint delete_checkpoint |