Skip to content
This repository was archived by the owner on Oct 14, 2026. It is now read-only.
fulldotdevPublic archive

About

Edit your Fulldev website from any coding agent

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Fulldev CLI

Moved. The Fulldev CLI is now developed in Fulldev's own workspace and still released to npm as fulldev: run npx -y fulldev. This repository is archived and no longer updated. Add the agent skill from the npm release: npx skills add https://cdn.jsdelivr.net/npm/fulldev/skills/fulldev/SKILL.md.

Use Fulldev apps from a terminal or an AI agent. The CLI discovers the full HTTP API from OpenAPI and is a thin client of the Fulldev MCP server at https://app.full.dev/mcp, which has the tools of every app your organization gives you: it reads the tools, their schemas, and the instructions from the server each time, so it stays in step with the apps. Each app's tools start with its name, such as cms_.

App For
cms Editing your website through the Fulldev CMS
connect Your business tools, such as Shopify, through Fulldev Connect
scan Scanning websites with Fulldev Scan, for administrators only
sites A finished website from Fulldev Sites, for administrators only
pages Reports and plans as web pages with Fulldev Pages, for administrators only
contacts Daily synchronization of your Google contacts across multiple accounts with Import and Export
send Customer message scenarios and deliveries
meet Your meetings, transcripts and screenshots for follow-up with Fulldev Meet
work Tasks, projects and goals in your organization

Install

Run it from npm. It needs Node.js 24 or later.

npx -y fulldev --help
pnpm dlx fulldev --help

Or install it once:

npm install -g fulldev
fulldev --help

Add the agent skill, which tells an agent when and how to use the CLI:

npx skills add fulldotdev/cli

Sign in

fulldev login               # once, for every app and organization
fulldev status              # signed in, valid, email, organizations, expiry
fulldev logout

fulldev login opens your browser at app.full.dev, where you sign in with your Fulldev account, with a code sent to your email or with Google, and choose the organizations fulldev may work in: all of yours at first. It waits up to 10 minutes. Add --no-browser to only print the link.

On a computer without a browser, such as over SSH, run fulldev login --no-browser and open the link on your own computer. The page after sign-in does not load there, because it is meant for the computer that runs fulldev: copy its address from the address bar and paste it into the terminal.

One sign-in covers every app of the organizations you chose: the tokens are for the Fulldev MCP server, which checks on every call which apps you may use in which organization. To change the organizations, run fulldev login again. fulldev status lists them, with their slugs and the apps you may use in each.

fulldev logout revokes the refresh token at the authorization server (access tokens cannot be revoked and expire within 15 minutes) and deletes the tokens from this computer. When revoking fails, for example offline, it still deletes them and says so.

How it works:

  • Browser sign-in uses OAuth with PKCE (S256) and a redirect to http://127.0.0.1:<random port>/callback, or the pasted address of that redirect, after checking that it belongs to this sign-in. It asks for the server's MCP URL as the resource, so the token is only valid there.
  • The CLI is a public OAuth client that needs no registration: its client id is the address of its Client ID Metadata Document, which the authorization server at https://app.full.dev/api/auth reads. It never registers a client, so sign-in to a server that does not support such documents fails with CLIENT_METADATA_UNSUPPORTED.
  • Tokens are stored in the OS keychain (macOS Keychain, Windows Credential Manager, or the Secret Service on Linux) under the service fulldev, one entry per server. Where no keychain is available, such as in many containers and CI runners, they go to ~/.config/fulldev/auth.json (or $XDG_CONFIG_HOME/fulldev/auth.json), readable only by you; fulldev status says which one is used.
  • Access tokens are refreshed when they expire. Parallel commands take turns through a lock file next to it, so they never refresh the same token twice.

Commands never start a sign-in without a terminal (when stdin or stdout is not a TTY): they fail at once with exit code 3 and say to run fulldev login. At a terminal they open the browser sign-in themselves; --no-login turns that off.

Use

fulldev instructions                    # how to use every app you may use, from the server; read first
fulldev tools                           # name, title and description of every tool
fulldev call cms_list_repositories
fulldev cms instructions                # the overview and the CMS's own part
fulldev cms tools                       # the CMS's tools only
fulldev cms tools commit_files          # description, input schema, output schema, annotations
fulldev cms call read_file '{"branchId":"<id>","path":"src/content/home.md"}'
fulldev cms call commit_files --file changes.json
echo '{"branchId":"<id>"}' | fulldev cms call get_preview -
fulldev cms form wait <branchId> <formId> --timeout 60
fulldev help cms call                   # help for any command

After fulldev <app>, a tool's name may leave out the app's prefix: fulldev cms call read_file calls cms_read_file.

When the sign-in is for more than one organization, a call names the organization to work in with --org <slug>; without it the tool answers ORGANIZATION_REQUIRED. fulldev tools and fulldev instructions show the tools of every organization together. --all-orgs calls a tool that only reads in every organization that has its app and prints the answers together, each with its organization:

fulldev cms call list_repositories --org het-clubhuis
fulldev cms call list_repositories --all-orgs   # {"organizations":[{"organization":{...},"result":{...}}, ...]}

On the server the organization is the tool's organization argument, which every app tool takes when the sign-in is for several; fulldev_list_organizations lists them.

call prints the tool's result as JSON on stdout. When the tool fails, it prints the error on stderr and exits with 1.

Exact text

For Markdown and other text, --text-file <field>=<path> puts a file's exact UTF-8 content in one field of the input, and --raw <field> prints one text field of the result as it is, without JSON quotes or an added newline. Both work with call and api. Nothing is trimmed, and line endings stay as they are.

fulldev cms call commit_files '{"branchId":"<id>","expectedRevision":"<sha>","changes":[{"path":"src/content/home.md"}]}' \
  --text-file changes.0.content=home.md
fulldev cms call read_file '{"branchId":"<id>","path":"src/content/home.md"}' --raw content > home.md
fulldev pages call export_page_markdown '{"pageId":"<id>"}' --raw markdown > page.md

To change a task's notes only when nobody else did, read them first and send back the notesVersion from that same result as expectedNotesVersion. This short token also works for large notes; without a guard, the update works as before:

fulldev work call get_task '{"taskId":"<id>"}'
fulldev work call update_task '{"taskId":"<id>","expectedNotesVersion":"<notesVersion>"}' --text-file notes=notes.md
  • A field is a dotted path, such as content.blocks.0.markdown. Objects on the way are made; arrays must be in the JSON, with the item.
  • The JSON leaves that field out, and each field is named once. - reads stdin, for one input only.
  • Names such as __proto__ and constructor, an existing field, a missing array item, and text that is not UTF-8 are usage errors (exit 64), before anything is sent.
  • When the tool's output schema or the API's response schema shows the field can never be text, --raw refuses before sending (exit 64). It does not work with --all-orgs.
  • When the request succeeded but its field is missing or not text, --raw prints nothing on stdout and exits with 1. The error has "succeeded": true and the full result, such as a new page's id: use it, and do not send the request again.

fulldev cms form wait keeps calling cms_wait_for_form until the person sends the form, with a progress line on stderr each round, then prints the result. After --timeout minutes (default 30) it stops, also in the middle of a request, prints the form id, and exits with 2, so you can run it again.

Output and exit codes

Data is JSON on stdout. instructions and help are plain text. Progress lines go to stderr. Every error, including a wrong command, is one JSON object on stderr:

{
  "error": {
    "code": "SIGN_IN_REQUIRED",
    "message": "Not signed in to Fulldev. Run: fulldev login",
    "command": "fulldev login"
  }
}
Code Meaning
0 Done
1 Error, from the tool or the CLI
2 form wait timed out
3 Sign-in needed
64 Usage error

Deploy previews

--url <mcp url> or FULLDEV_URL selects another server, such as a deploy preview's, which serves it at /mcp. Each server has its own sign-in.

FULLDEV_URL=https://deploy-preview-12--fulldev-app.netlify.app/mcp fulldev login
fulldev cms tools --url https://deploy-preview-12--fulldev-app.netlify.app/mcp

Develop

pnpm install
pnpm check   # format, lint, type check, tests, and that dist/ is up to date
pnpm build   # writes dist/cli.mjs

An app is one entry in src/apps.ts; the server's address is server there. The OAuth client id is clientMetadataUrl in src/oauth.ts; the document at that address is published with the full.dev website.

dist/ is committed, because npx github:fulldotdev/cli runs it without a build step. Run pnpm build and commit dist/ with every source change.

Releases

Every change that users get adds a changeset with pnpm changeset. The fulldev package is published only from fulldotdev/cli: merging a change with its changeset to main opens a release pull request, and merging that publishes to npm from GitHub Actions with trusted publishing and provenance, without an npm token.

License

MIT

Full HTTP API

MCP shortcuts remain the curated tool interface. On a server exposing OpenAPI, the same CLI can discover and call every product HTTP operation, including ones omitted from MCP:

fulldev api contacts
fulldev api contacts.accounts.list '{}' --org my-company
fulldev contacts api accounts.list --file input.json --org my-company

Use an operation id from fulldev api <app>. Input is a JSON object, a file with --file, or stdin with -, with --text-file and --raw as for call. Reads send query parameters; changes send JSON. An error keeps the server's details, such as status and a conflict's data. Existing OAuth credentials and organization grants cover both interfaces. The CLI refuses redirects and paths outside the selected app before sending credentials. Servers without OpenAPI continue to support the existing MCP commands.

About

Edit your Fulldev website from any coding agent

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages