Reference
MCP endpoint, authentication, resources, tools, and runtime behavior.
For setup instructions, see Connect.
Endpoint
| URL | https://api.reforma.ai/mcp |
| Transport | Streamable HTTP, stateless JSON-RPC |
| Protocol | MCP specification 2025-03-26 |
Reforma does not expose an SSE endpoint and does not use API keys.
Clients should connect using the MCP server URL directly.
Authentication
Reforma MCP uses OAuth 2.1 with PKCE S256.
Access tokens are issued for the signed-in Reforma user, with:
aud=reforma-mcpThe token can access every workspace the user belongs to.
A Reforma application session cookie cannot be used to call the MCP endpoint.
| Resource | https://api.reforma.ai/mcp |
| Protected resource metadata | https://api.reforma.ai/.well-known/oauth-protected-resource/mcp |
| Authorization server metadata | https://api.reforma.ai/.well-known/oauth-authorization-server |
| Authorization endpoint | https://api.reforma.ai/oauth/authorize |
| Token endpoint | POST https://api.reforma.ai/oauth/token |
| Dynamic client registration | POST https://api.reforma.ai/oauth/register |
| JWKS | https://api.reforma.ai/.well-known/jwks.json |
Clients that support an HTTPS client_id metadata document can use it directly. Other clients can register dynamically through /oauth/register.
Requests with a missing, invalid, or wrong-audience Bearer token return 401 with a WWW-Authenticate header pointing to the protected resource metadata.
To revoke a client, open Profile → Security and login → Connected apps in Reforma.
Project lifecycle
Most tools operate on a project sandbox.
A typical session is:
- Call
list_projects. - Call
open_projectwith a projectid. - Use that
project_idfor subsequent project tools.
open_project provisions or reuses the project's dev sandbox.
The Reforma editor and MCP share the same sandbox and worktree.
If the sandbox has been idle for one hour, it is stopped automatically. Call open_project again to resume.
There is no close_project tool.
Resources
These are MCP resources provided by Reforma. They are not files in the project sandbox.
| URI | Description |
|---|---|
reforma://fonts | Font rules and available font configuration. Fonts belong under app/fonts; do not use next/font, CDN font links, or font @imports elsewhere. |
reforma://tokens | Project design tokens. |
reforma://project.md | Project-level implementation rules. After open_project, prefer AGENTS.md from the worktree when it exists. |
Tools
Unless noted otherwise, project tools require a positive integer project_id and an active sandbox created by open_project.
create_upload and complete_upload require a project_id, but do not require the sandbox to be running.
The worktree lives in Reforma's cloud sandbox, not on the client machine.
Do not start or stop the managed Next.js development server through bash.
Identity and projects
get_me
Returns the signed-in Reforma user.
Arguments: none.
{
"id": 1,
"email": "you@example.com",
"name": "You"
}list_projects
Returns projects available to the current user, grouped by workspace.
Arguments: none.
{
"workspaces": [
{
"id": 1,
"name": "Acme",
"status": "active",
"projects": [
{
"id": 10,
"name": "Site",
"status": "active",
"workspaceId": 1
}
]
}
]
}Pass a project id from this response to open_project.
open_project
Provisions or reuses the project's dev sandbox and returns its preview URL.
| Argument | Description |
|---|---|
project_id | Required project ID. |
{
"id": "…",
"previewUrl": "https://…",
"status": "active"
}Files
File paths are relative to the project sandbox unless an absolute project path is supplied.
read
Reads UTF-8 text or PDF files.
Text is returned in windows of up to 200 lines by default. PDFs use pages instead of lines. The total field indicates whether more content remains.
| Argument | Description |
|---|---|
path | File to read. |
limit | Optional. Maximum lines for text or pages for PDF. Default: 200. |
offset | Optional. 1-based starting line or page. |
write
Creates or overwrites a file.
| Argument | Description |
|---|---|
path | Destination path. |
content | Complete file contents. |
edit
Replaces text in an existing file.
Read the file before editing it. Multiple replacements for the same file can be sent in one call.
| Argument | Description |
|---|---|
path | Existing file. |
edits | Between 1 and 32 { search, replace } operations. |
replace_all | Optional. Replace every occurrence of each search value. |
list_directory
Lists files and directories.
| Argument | Description |
|---|---|
path | Optional. Defaults to the project root. |
recursive | Optional. Default: false. |
only_files | Optional. Default: false. |
sizeBytes is returned for files only.
glob
Finds paths matching one or more glob patterns. Results are ordered newest first.
| Argument | Description |
|---|---|
pattern | Required array of glob patterns, OR'd together. Example: ["**/*.ts", "app/**/*.tsx"]. |
path | Optional directory to search. |
recursive | Optional. Default: true. |
only_files | Optional. Default: true. |
grep
Runs ripgrep against the project worktree.
| Argument | Description |
|---|---|
pattern | Required regular expression. Alternation is supported. |
path | Optional file or directory. |
glob | Optional path filters, for example ["*.ts"]. |
type | Optional ripgrep file type, for example js. |
output_mode | Optional: files_with_matches, content, or count. |
case_insensitive | Optional. |
multiline | Optional. |
create_directory
Creates a directory.
| Argument | Description |
|---|---|
path | Directory to create. |
move_file
Moves or renames a file or directory.
| Argument | Description |
|---|---|
from_path | Existing path. |
to_path | Destination path. |
overwrite | Optional. |
remove_file
Removes one or more paths.
| Argument | Description |
|---|---|
paths | Required array of paths. |
Shell and dependencies
bash
Runs a command in the project sandbox.
Each invocation has its own working directory unless cwd is provided. Quote paths containing spaces and use shell operators such as && when commands must run sequentially.
Foreground commands default to a 120-second timeout and may run for up to 600 seconds.
Background commands return:
{
"id": "…",
"pid": 123,
"log": "…"
}Use the returned id to poll or stop the process. Do not use the OS pid.
| Argument | Description |
|---|---|
command | Command to run. Required unless polling or killing by id. |
description | Short human-readable label. Required with command. |
background | Optional. Run asynchronously and return a process registry id. |
id | Process registry ID used for polling or stopping a background command. |
kill | Optional. Stop the process identified by id. |
timeout | Optional timeout in milliseconds. |
cwd | Optional working directory. |
tailLines | Optional number of trailing stdout/stderr lines to retain. |
A successful stop reports status: killed on the kill call.
install_deps
Installs project dependencies using Bun and restarts the managed development server.
Use this tool instead of running bun install through bash.
| Argument | Description |
|---|---|
packages | Optional package names to add. Omit to install or update existing dependencies. |
dev | Optional. Add packages as devDependencies. |
force | Optional. Uses bun --force. |
resetLockfile | Optional. Uses bun update --no-cache. Ignored when packages is provided. |
reason | Optional logging context. |
The response includes the executed command, Bun output, and whether the development server was restarted.
read_lints
Formats and validates changed files.
The tool runs:
biome check --write
tsc --noEmitBecause Biome runs with --write, this tool may modify files.
| Argument | Description |
|---|---|
paths | Optional files or directories to check. Omit to run against the whole workspace. |
Prefer passing only the files or directories changed during the task.
Development server
The project's Next.js development server is managed by Reforma.
Do not start or stop it using bash.
dev_server_status
Returns the current development server state and recent logs.
| Argument | Description |
|---|---|
tailLines | Optional number of recent log lines. |
dev_server_restart
Restarts the managed development server.
| Argument | Description |
|---|---|
reason | Optional logging context. |
Assets
There are two ways to add an asset, depending on where the source file lives.
Use import_asset when the source is already reachable by Reforma:
- an
http://orhttps://URL; - a file under
public/; - a scratch file under
/tmp/reforma.
Use create_upload → upload the bytes → complete_upload when the file exists on the client machine, such as a generated image, screenshot, or video.
Do not send file bytes through JSON-RPC or data URLs.
import_asset
Imports an existing asset into Reforma.
| Argument | Description |
|---|---|
source | HTTP(S) URL, public/ path, or absolute /tmp/reforma scratch path. |
destination | Optional: cdn or filesystem. Default for images: cdn. |
path | Required for explicit filesystem destinations. Fonts belong under app/fonts/assets/*.woff2. |
filename | Optional basename when path is omitted or points to a directory. |
Scratch files can only be imported to the CDN.
create_upload
Creates a presigned PUT URL for a client-local file.
Maximum file size: 50 MB.
The PUT URL expires after 15 minutes.
| Argument | Description |
|---|---|
project_id | Required project ID. |
filename | Basename including extension, for example hero.png. |
content_type | MIME type, for example image/png. |
size | Exact file size in bytes. |
{
"asset_id": "…",
"put_url": "https://…",
"headers": {
"Content-Type": "image/png"
},
"expires_in": 900
}Upload the file bytes directly to put_url:
curl -T ./hero.png \
-H "Content-Type: image/png" \
"$PUT_URL"complete_upload
Confirms that the uploaded object exists and adds it to Reforma's CDN.
Call this only after the PUT request succeeds.
| Argument | Description |
|---|---|
project_id | Required project ID. |
asset_id | asset_id returned by create_upload. |
{
"ok": true,
"destination": "cdn",
"id": "…",
"url": "https://cdn…/…",
"filename": "hero.png",
"mediaType": "image/png",
"size": 12
}If the object has not been uploaded yet, the call fails instead of creating an empty asset.
Versions and publishing
commit
Creates a version checkpoint.
| Argument | Description |
|---|---|
message | Required short imperative commit message. |
Before creating the checkpoint, Reforma runs lint validation.
If validation fails, no version is created and the response returns reason=lint with diagnostics.
If there are no uncheckpointed changes, the call is a no-op with reason=clean. Autosave may already have created the latest checkpoint.
Use list_versions to inspect the current state.
list_versions
Returns the project's current, draft, and published versions.
This is the same version state shown in the Reforma version panel.
No arguments other than project_id.
publish
Publishes the project using the same pipeline as the Reforma Publish button.
The call waits until deployment succeeds or fails.
On success, it returns the live URL. On failure, it returns deployment logs.
No arguments other than project_id.
Runtime behavior
| Branch | open_project always uses dev. |
| Sandbox | MCP and the Reforma editor share the same sandbox and worktree. |
| Concurrency | There is no sandbox lock. |
| Close | There is no close_project tool. |
| Idle timeout | The sandbox stops after one hour without a sandbox-touching call. |
| Upload size | Maximum 50 MB. |
| Upload URL lifetime | 15 minutes. |
| Uploaded asset ownership | ownerType=project, source=agent. |