MCP Setup

Connect Claude or Codex to Grain, save private artifacts and internal apps, and choose sharing explicitly.


Grain gives coding agents tools to create, edit, save, verify, and share grains. Connect the local stdio server with grain mcp; run grain login separately when authentication is needed. The local server is not an HTTP endpoint and does not use the OpenAPI document. To connect a remote MCP client, such as a web chat client, see Remote MCP. Initialization writes recognized project configuration. Optional desktop onboarding and Settings → Integrations provide local plugin installation commands for Claude Code or Codex. The desktop app bundles the Grain skill and MCP launcher; users run their chosen agent’s commands. Personal defaults are a separate preference with preview and explicit consent.

Default destination

With the optional preference installed, use Grain in place of Claude Artifacts or Codex Sites for saved artifacts and internal apps. New grains default to the docs folder in the selected Grain organization. Each grain is its own workspace; docs is not a folder inside a previously selected grain. User instructions can choose another folder, organization, existing grain, or local-only output. Skill installation alone cannot guarantee automatic selection.

Personal instructions preserve unrelated content and upgrade only exact known Grain blocks. A user-edited block or skill is not overwritten. Setup reports Codex overrides that would shadow the target personal file. MCP registration alone does not change personal preferences. The complete client snippets and native plugin commands are on Integrations.

Transport, authentication and schema discovery

The supported server is a local process. A client starts grain mcp, keeps JSON-RPC messages on stdin/stdout, and discovers the server name (grain) and tool definitions with the MCP initialize and tools/list flow. Every tool has a title and explicit read-only, destructive, idempotent and open-world hints, so clients can ask for approval before tools that change or delete work. The server's instructions are short enough for clients that truncate them (Claude Code keeps 2,048 characters); the full workflow comes from the read-only grain_guide tool. The tool schemas in the generated inventory below are the same registry the server advertises; clients should still use their negotiated schema rather than hard-coding a copy.

The server uses the CLI’s local authentication and workspace access. Run grain login before asking an agent to create, edit or share a workspace. Do not put mca_ or another raw credential into an MCP config. A project config only contains the executable and mcp argument. For the hosted HTTP server, which signs in with OAuth instead, see Remote MCP.

To verify a client connection, start a fresh client session after writing its config, ask it to list Grain tools, and run a private artifact request. A tool list proves registration; a returned webUrl plus filesSynced, revisionRecorded and commitOutcome: confirmed proves an artifact save. Sharing is a separate explicit mutation.

Raw project configuration

grain init writes the following entries while preserving unrelated servers. If no recognized file exists it creates .mcp.json; use grain init --no-agent-config to skip repository wiring.

.mcp.json:

{
  "mcpServers": {
    "grain": { "command": "grain", "args": ["mcp"] }
  }
}

.codex/config.toml:

[mcp_servers.grain]
command = "grain"
args = ["mcp"]

.cursor/mcp.json:

{
  "mcpServers": {
    "grain": { "type": "stdio", "command": "grain", "args": ["mcp"] }
  }
}

The project entry does not install the CLI, sign in, create a workspace or modify the optional default-artifact preference. Do those steps through Install and Integrations.

Command-line setup

To configure Grain for your account across projects, run:

grain setup

This signs in through your browser, installs the bundled Grain plugin for detected Claude Code or Codex clients, checks the MCP server, and launches Grain. To install just the agent plugin or choose clients explicitly:

grain mcp install --claude --codex
grain mcp status --json
grain setup --check --json

Production installation uses each agent’s native plugin commands and includes the Grain skill and MCP tools. It requires Claude Code 2.1.269+ or Codex 0.154.0+. Existing direct Grain MCP entries are preserved; setup reports the migration command to review and run before retrying. Disabled or ambiguous plugins require review in Settings → Integrations. Development checkouts retain isolated direct MCP registrations. Restart an already-running agent after installation.

The initialization command recognizes .mcp.json for Claude Code, .codex/config.toml for Codex and .cursor/mcp.json for Cursor. Existing recognized files are updated; when none exists, .mcp.json is created.

grain mcp

With no subcommand, this is a long-running stdio process that responds to MCP requests. It does not print a share URL by itself. The install and status subcommands manage client registration; they do not start the stdio server.

Available tools

Grain exposes 41 MCP tools. This table is generated from the operation registry; workspace operations require an explicit ID.

ToolTitleCLI commandRequired fieldsOptional fieldsRead-onlyDestructive
app_connections_connectGet a link to connect an appgrain connectionsappreadOnly, organizationNoNo
app_connections_executeUse a connected appgrain connectionsapp, toolarguments, account, organizationNoYes
app_connections_listList app connectionsgrain connections—app, organizationYesNo
app_connections_search_toolsFind tools for a connected appgrain connectionsappquery, limit, organizationYesNo
grain_app_restartRestart app preview servergrain app restartworkspace—NoNo
grain_app_statusCheck app preview servergrain app statusworkspace—YesNo
grain_artifactSave HTML graingrain artifactname, htmlfolder, organizationNoNo
grain_artifact_updateUpdate HTML graingrain artifactworkspace, htmlname, expectedRevisionId, title, descriptionNoYes
grain_checkoutCheck out workspace for editinggrain checkoutworkspace—NoNo
grain_checkpointRecord checkpointgrain checkpointworkspacemessageNoNo
grain_commandManage app commands (combined)grain commandworkspace, request—NoYes
grain_command_listList app commandsgrain commandworkspace—YesNo
grain_command_runRun app commandsgrain commandworkspace, commands—NoYes
grain_command_schemaGet app command schemagrain commandworkspace, commandId—YesNo
grain_configManage app configuration (combined)grain configworkspace, request—NoYes
grain_config_inspectInspect app configurationgrain configworkspace—YesNo
grain_config_open_tabOpen app tabgrain configworkspace, tabId—NoNo
grain_config_updateUpdate app configurationgrain configworkspace, expectedHash, patch—NoYes
grain_config_validateValidate app configurationgrain configworkspace, patch—YesNo
grain_execRun sandbox commandgrain execworkspace, command—NoYes
grain_feedbackSend feedback to the Grain teamgrain feedbacksource, kind, textworkspace, toolNameNoNo
grain_guideRead Grain workflow guide———YesNo
grain_historyRead revision historygrain historyworkspacelimit, before, revisionYesNo
grain_listList workspaces and foldersgrain list—organization, folder, query, workspaceYesNo
grain_logsRead dev server logsgrain logsworkspacelines, sourceYesNo
grain_metadataRead workspace title and descriptiongrain metadataworkspace—YesNo
grain_newCreate workspacegrain newnametemplate, folder, organizationNoNo
grain_openOpen in Grain appgrain openworkspace—NoNo
grain_operationCheck or cancel operation (combined)grain operationkind, operationId, workspaceactionNoYes
grain_operation_cancelCancel operationgrain operation cancelkind, operationId, workspace—NoYes
grain_operation_statusCheck operation statusgrain operation statuskind, operationId, workspace—YesNo
grain_pullPull remote changesgrain pullworkspace—NoYes
grain_pushPush checkout changesgrain pushworkspacereload, title, descriptionNoYes
grain_releaseRelease local checkoutgrain releaseworkspace—NoYes
grain_runStart long-running sandbox commandgrain jobcommand, workspacetimeoutMs, requestIdNoYes
grain_screenshotCapture app screenshotgrain screenshotworkspacemaxWidthYesNo
grain_share_createCreate share linkgrain share createaudience, workspacepassword, name, path, reuseExistingNoYes
grain_share_listList sharesgrain share listworkspace—YesNo
grain_share_revokeRevoke sharegrain share revokeshareId, workspace—NoYes
grain_share_updateUpdate sharegrain share updateshareId, workspacemode, password, name, path, regenerateSlugNoYes
grain_upgradeAdd app runtimegrain upgradeworkspacetarget, idempotencyKeyNoNo

Create and update

For a complete single-page HTML document up to 256 KiB, grain_artifact creates and saves it in one call. It returns the actual private workspace link and publication state. Do not push again unless you make another edit.

To revise an artifact, call grain_artifact_update with its existing workspace ID and the full new html instead of creating a duplicate. grain_artifact itself is create-only and not destructive; grain_artifact_update is marked destructive (it replaces content) and idempotent (repeating the same HTML is a no-op), and uses the same CLI path as grain --workspace <id> artifact. It replaces index.html in the grain's latest revision and keeps every other file. expectedRevisionId is optional and used when given. Set it to the revisionId from your previous grain_artifact or grain_artifact_update result: if anyone changed the grain since then, the call returns remote_drift and writes nothing, like the hosted update_grain tool's expected_revision_id. Without it, only a change that lands during the call is detected; edits made earlier are replaced (they remain in history). Optional title and description are recorded on the new revision. Unchanged HTML returns already_correct without a new revision. The result reports created: false and updated: true when a new revision was recorded, and its revisionId is the value to pass next time. A clean local checkout of the grain is brought up to the new revision; one with local changes is left alone and the result carries a stale_checkout warning with its path. Only html grains can be updated this way: runtime grains return runtime_required and other templates such as wiki return unsupported. Updates never rename or move a grain: omit name, or pass the current name. There is no CLI or MCP rename; rename a grain with Rename in the Grain app. Use grain_checkout and grain_push for grains this cannot update.

For iterative or multi-file work, use grain_new, edit its returned checkout, and grain_push when complete. Pass a template explicitly: html and wiki are sandboxless managed-content workspaces; empty supplies a Vite runtime; nextjs supplies Next.js. The react-vite template is a promotion target, not a selectable new-workspace template.

For existing work, discover with grain_list, retain its explicit workspace ID, and use grain_checkout before editing. Keep existing grains in their location. MCP workspace tools never fall back to a machine default. Organization ambiguity returns candidates for selection; viewers can discover accessible grains but cannot create them.

For a small complete document, grain_artifact accepts the required name and html fields and returns a private workspace URL without creating a share. A request conceptually looks like this in an MCP client:

{
  "name": "Quarterly report",
  "html": "<!doctype html><h1>Quarterly report</h1>",
  "folder": "docs"
}

For multi-file work, use grain_new and edit the returned checkout. Every workspace operation requires the explicit workspace field; a machine default is not a substitute.

A checkout is a local editing copy. Push changes before runtime installs/builds/tests with grain_exec; never run those in the local copy. HTML has no sandbox. grain_run starts bounded longer commands and returns an operation ID for polling/cancellation. Jobs survive MCP disconnect on the same host, not host failure. Pull and review runtime-authored changes before checkpointing.

App configuration and commands have separate read and write tools. grain_config_inspect returns the manifest and its hash, grain_config_validate checks a patch without saving, grain_config_update applies a hash-checked command/tab patch, and grain_config_open_tab opens a named tab. grain_command_list and grain_command_schema discover registered commands, and grain_command_run invokes them through the existing authorized API. grain_operation_status polls an upgrade or long-running command, and grain_operation_cancel requests cancellation. The combined grain_config, grain_command and grain_operation tools accept the same requests through an action field and remain available for existing workflows. Script authors read JSON stdin; Grain owns temporary input files. Saving configuration does not open tabs.

Completion and recovery

Return data.webUrl and data.workspaceUrl for private delivery. data.webUrl is an https://rungrain.com/w/<workspace ID> link that opens in any browser or chat and offers to open the workspace in the Grain app; it grants no access by itself. data.workspaceUrl (also data.openUrl) is the grain:// link that opens the desktop app directly, and tabOpenUrl follows an explicit named-tab opening. grain_list and grain_metadata also return a webUrl for each workspace. Check filesSynced, revisionRecorded, and commitOutcome; an upload and a confirmed history revision are separate outcomes. Use grain_history before retrying uncertain saves and recover the same grain rather than creating duplicates.

On remote_drift, pull and review while preserving wanted local changes. A configuration conflict requires a new inspection/hash and a merged patch. Pending upgrades are not ready: poll until success with runtimeReady: true. Follow next_action on structured errors. Login failure requires grain login, not opening a workspace or bypassing authentication.

grain_screenshot requires a Grain desktop on the same computer and uses its existing content session. It does not navigate to or publish a URL.

The full machine-readable operation snapshot is generated at docs/generated/grain-operations.json in the repository. It is a development artifact for checking registry parity; MCP clients should use tools/list at runtime.

Sharing

Grains remain private unless sharing is requested. Building an internal app alone does not authorize distribution. Save, verify, and checkpoint completed work before creating a share with an explicit audience:

  • public: anyone with the link.
  • password: anyone with the link and password.

New grains start restricted: only the organization and invited guests, signed in, can open the canonical link https://rungrain.com/w/<id>. Public or password opens it to anyone with the link. Guests and restricted access are managed in the desktop Share dialog. grain_share_list is read-only and reports the grain link's general access, its guests (builders and owners only), and each share; create can reuse an existing target and change its access. Update/revoke require a share ID. MCP share calls accept a password as a tool input and deliver it to the CLI through GRAIN_SHARE_PASSWORD, rather than putting it in argv. The server never prints the password in tool results. Return the actual shareUrl and canonicalUrl; do not invent a public URL or expose a raw private preview URL. Revocation cannot retract downloaded copies. For a raw CLI share, use the hidden-prompt --password-env flow in First Artifact; --password <value> is intended only for disposable test values.