Skip to main content
Model Context Protocol connects tools in two directions. A Fimo project can use tools from a remote MCP server, and an MCP client can connect to Fimo.

Add MCP tools to a project

Add a remote Streamable HTTP server, then inspect and run its current tools:
Fimo can connect to public servers and servers that advertise browser sign-in. The command opens the authorization page when sign-in is required. Add --no-open to print the URL instead. Use a bearer token when the server provides one:
Remote MCP connections require HTTPS. Local commands such as npx are not supported.

Use the connection

The server becomes a project Connection. You can inspect its tools from the CLI and make it available to supported Studio or agent work. An agent bundle must enable the connection in its own configuration before the agent can use it. The connection gives the agent tools. A trigger or manual run still decides when the agent starts. Manage the same project connections visually in Connections.

Connect an MCP client to Fimo

Fimo provides a hosted project MCP server at:
Add that URL to a compatible remote MCP client. The client opens Fimo sign-in and asks you to approve access. The operations available through search and execute depend on the access you grant and your existing project permissions.

Search and execute

Hosted Fimo connections expose exactly two tools: search and execute. This keeps the MCP catalog small while preserving Fimo’s normal permission checks and portable operation contracts.
  • search runs isolated JavaScript over fimo.spec(). Use it to find permitted operations and inspect their input and output schemas. It cannot read project data or make changes.
  • execute runs isolated JavaScript against the operations permitted by the connection. Fimo still checks OAuth scopes, project permissions, tenant isolation, and every operation’s input and output.
The search program is the query. If the client does not know which area owns a request, it can list the domains available to the current connection:
Common starting points are projects, branches, sessions, schemas, and files for project work; entries, singles, labels, locales, assets, and forms for content; and agents, schedules, publications, preview, analytics, billing, and domains for operations. This is an orientation, not the complete catalog. The domain query above returns the exact list permitted by the current connection. Each descriptor contains id, domain, summary, accessScope, effect, inputJsonSchema, and outputJsonSchema. Once the client knows the likely domain, it can combine the domain with words from your request:
Operation IDs map directly to the execute API. For example, assets.uploadFromUrl becomes fimo.assets.uploadFromUrl(input). The client preserves the exact camelCase domain and method returned by search. The portable set covers project discovery; durable Branch creation, status, bounded diffs, and diff details; schema list/get and session-scoped create/update/delete; file read/glob/grep and session-scoped write/edit/delete; the complete work-session lifecycle; collection entries including search and bounded bulk mutations; Singles; labels; locales; form definitions and submissions; Media Library reads, folders, moves, deletion, and generic image or video generation; and asset import from a public URL; project agents and run status; publication, Preview, and sandbox-log reads; Branch-scoped analytics with annotations; and the project’s AI credit balance. Use search instead of relying on this list: it returns the operations and schemas permitted for the current connection. There is no portable identity operation. OAuth sign-in and caller identity stay with the MCP host and are not exposed to generated JavaScript through fimo.*. Each program runs in a fresh environment with no filesystem, environment variables, caller credentials, or general network access. Work that changes files, schemas, or project dependencies still uses an explicit work session.

Contact Fimo support

Ask your MCP client to contact Fimo support only when you want to send a report. The client can discover support.report with search, then submit the exact approved message with execute:
message is required and can contain up to 20,000 characters. projectId is optional, but a branch requires one. Without a project, Fimo files the report under your default organization. Reports stay in Fimo’s internal support queue.

Use hosted work sessions

When you ask an MCP client to change a project, Fimo prepares an isolated draft and applies it to main after validation. You do not need to create or manage a Branch for ordinary changes. Ask for a durable Branch only when you want lasting parallel work or another explicit target. Fimo implements each isolated draft as a work session with a temporary Branch and sandbox. That is normally an internal detail: you ask for a change, and Fimo runs the session for you. The lifecycle operations below are for integration authors who drive the session themselves. The target Branch stays unchanged until the session merges.
Work sessions require the code access scope. It authorizes isolated file and schema changes, approved project operations, and merging or discarding the session result. Read-only access is selected by default. If a connector was connected before work sessions were available, reconnect it and approve the code scope.
1

Start a session

Call fimo.sessions.start with the project and, optionally, a target Branch. Save the returned sessionId, expiresAt, and onExpire values.
2

Make isolated changes

Pass sessionId to fimo.files.write, fimo.files.edit, fimo.files.delete, fimo.schemas.create, fimo.schemas.update, or fimo.schemas.delete. Use fimo.assets.uploadFromUrl to import a public URL into the draft’s Media Library. You can also run an approved operation with fimo.sessions.runOperation.
3

Read back and review

Pass the same sessionId to fimo.files.read, fimo.files.glob, or fimo.files.grep to see the session’s own files, including the change you just made. Call fimo.sessions.changes to review the complete change set, then call fimo.sessions.validate. Fix any reported issues in the same session and validate again before closing it.
4

Finish the session

Call fimo.sessions.close with action: "merge" to apply the changes to the target Branch, or action: "discard" to remove them. A merge conflict answers closed: false and keeps the session open. See Resolve a merge conflict.

Resolve a merge conflict

A conflicting merge writes nothing to the target Branch. The response reports outcome: "conflicts", closed: false, a mergeId, a conflictCount, and up to five conflicts inline so you can plan the next call. The session stays open on a fresh lease.
1

Inspect the conflicts

Call fimo.sessions.conflicts with the mergeId. The full list is cursor-paginated. Code conflicts carry their path. Pass codePath to add the three-way detail for that one file: the merge base, the target Branch version, the session version, and the merged result with conflict markers. Reading conflicts does not refresh the lease.
2

Choose a side for each conflict

Call fimo.sessions.resolve with the same mergeId and one resolution per conflict. parent keeps the target Branch value, child takes the session value, and pick writes an explicit pickedValue. Content and label row conflicts also accept per-field picks.
3

Poll the same session

Accepted resolutions run a successor merge, so do not call fimo.sessions.close again. Poll fimo.sessions.get. The session becomes merged when the successor lands, or returns to ready with a new mergeId and a fresh set of conflicts.
Pass the mergeId the session currently carries. A mergeId the session has moved past is rejected, and fimo.sessions.conflicts returns the current one. fimo.sessions.close with action: "discard" remains available at any point and leaves the target Branch unchanged.

Session-scoped and stateless operations

Reads and ordinary content mutations do not need a session. This includes fimo.schemas.list, fimo.schemas.get, and the Branch-scoped entry, Single, label, locale, media, and form operations. Branch-scoped calls use projectId and branch; their mutations keep the same project permissions as the corresponding API routes. Entry, asset, and form-submission lists return { items, nextCursor, total }. Pass limit, then send a non-null nextCursor back as cursor. An explicit non-negative offset is also accepted, but cursor and offset cannot be used together. Entry bulk create, update, and delete calls accept at most 1,000 entries. fimo.schemas.get returns a complete { typeName, definition } pair with Fimo-managed fields removed. Start a session, then pass that pair directly to fimo.schemas.update after changing the definition. This avoids rebuilding a schema from the abbreviated list response. Schema mutations return the current session envelope plus schema: { typeName, generatedPaths, tip }. A rejected mutation restores both schema source and generated files before returning the rejection. Agent operations are project-scoped, not Branch-scoped. fimo.agents.list and fimo.agents.run take only projectId: Fimo syncs agent bundles from the main Branch and always runs them from it, so there is no Branch to choose. Manual runs require the agents access scope. Pass the returned sessionId to fimo.agents.status to read status, the final report, and safe checkpoint metadata. Fimo does not expose provider storage references, capability snapshots, or run cost internals through that response. File and schema mutations, URL asset imports, approved operations, and the session lifecycle use sessionId. A mutation changes the session’s working Branch and remains invisible on the target Branch until merge.

Check what is published and what is running

Read-only operations answer questions about hosting without changing anything. No portable operation publishes, unpublishes, deploys, or starts a sandbox: those actions stay in the CLI and Studio. You can ask an MCP client for: Publication is project-scoped, so the publication operations take only projectId. fimo.sandbox.logs and fimo.preview.location take projectId and branch. Logs answer with a status rather than an error when there is nothing to read. fimo.publications.logs reports unavailable when the publication is still running, never created a deployment, or its deployment has been reclaimed by the host. fimo.sandbox.logs reports unavailable when the Branch has no running sandbox. Reading logs never starts one, which is what keeps the evidence of a failed deploy intact. fimo.preview.location returns the Fimo Studio Preview page for a Branch. It is a page behind Fimo sign-in, not a public site address and not a shareable token, and asking for it does not start, wake, or extend a sandbox. Opening the page in a browser is what starts the Preview. For the public address of the live site, read fimo.publications.state or fimo.publications.get. fimo.publications.list and fimo.sandbox.logs use the same pagination as the other list operations: pass limit, then send the returned nextCursor back as cursor. fimo.publications.logs returns a bounded tail and takes limit only.

Check AI credits

fimo.billing.credits takes only projectId and returns the same balance as fimo credits: what is available now, the daily, monthly, purchased, and awarded breakdown that adds up to it, and the daily allowance when one applies. The daily allowance is a cap, not extra balance to add on top.
It needs the read scope and the same project access as any other project read. There is no portable operation for organization usage, buying credits, or changing a subscription: those stay in Studio.

Read site analytics

Analytics operations take projectId and branch. fimo.analytics.pageviews returns the headline metrics, time series, top breakdowns, and annotations for a preset or custom date range. fimo.analytics.top returns one of pages, browsers, devices, countries, or sources. fimo.analytics.annotationsList reads notes in the selected range; setting or deleting a note uses fimo.analytics.annotationsSet or fimo.analytics.annotationsDelete and requires the write scope. Custom ranges require both from and to. The days shortcut accepts 7, 30, or 90.

Choose what a file read looks at

fimo.files.read, fimo.files.glob, and fimo.files.grep accept exactly one selector next to projectId: Passing both is rejected, and so is passing neither. A session read needs the same project access as a Branch read, plus ownership of that session: another user’s session is not readable, and neither is a session Branch named directly through branch. A session read answers from the revision the session recorded, so a file you just wrote or edited is immediately readable, globbable, and greppable through sessionId while the target Branch still shows the old content. Reads never refresh the session lease. While a mutation is still running, a read is refused rather than answered from a half-written state; retry once the mutation returns.

Import an asset from a URL

Call fimo.assets.uploadFromUrl with a public HTTP or HTTPS URL and your owned sessionId while making an isolated change. You can provide a filename, Media Library name, destination folder, alt text, and caption. Fimo blocks private-network destinations and limits the download to 50 MiB. The imported asset reaches the target Branch only when the change merges. Local paths are not accepted.

Keep the session lease alive

Each session has a 60-minute inactivity lease. Successful mutations refresh the lease. Reads do not. Validation runs synchronously in the session sandbox and returns its terminal result in the same execute call. Every session response includes expiresAt and onExpire: "discard". When the lease expires, Fimo discards the temporary session. If the client loses the ID of a session this conversation already started, or fimo.sessions.start times out before returning one, it can use fimo.sessions.list to recover its work. Sessions returned by that list are not automatically part of the current request. The client must leave any session it cannot tie to its own request untouched, including during cleanup. For a new request, it starts a new session unless you explicitly ask it to continue existing work. Fimo allows up to five live sessions per user and project, and up to eight session Branches per target Branch. If a limit blocks a new session, the client can discard a session it created for the current request. It must not discard other work to make room.

Use durable Branches for lasting work

Call fimo.branches.create when you want a deliberate, durable Branch for parallel work. Temporary changes belong in work sessions. A durable Branch remains available for later work; a session Branch is removed when the session is merged, discarded, or expires.

Compare two durable Branches

These operations are plain reads. They take projectId and branch, never a session. against picks the Branch to compare with and defaults to the Branch’s parent, or main. Fimo compares a Branch with a target and reports what differs. It does not work out whether the target moved on, so fimo.branches.status has no behind or diverged to report. Each detail operation takes a key that fimo.branches.diff listed for its surface. Code takes the file path, schemas a typeName, assets an assetId, and forms a formName. Content keys read <collection>:<rowId> and label keys read <locale>:<key>; split them and pass the parts. A side comes back null when the item exists on only one Branch. Reading a key that is not in the diff answers a not-found error rather than an empty result.
The fimo.branches.diff index is bounded. A surface with more changes than the index holds answers truncated: true, and Fimo cannot list the keys it left out. The detail operations still work for any key you already know.
fimo.branches.diffCodeFile compares committed Branch code in Fimo’s Git storage. It is not a local checkout diff, and it does not see a work session’s uncommitted state. fimo.branches.diffForm returns a form’s label and fields only: email notification settings and recipient addresses are never returned, and submissions never merge between Branches.

Approved operations and exclusions

fimo.sessions.runOperation accepts only these operations, with no arguments:
  • dependencies_install
  • schemas_sync
Hosted work sessions do not provide a shell operation and cannot deploy or publish. Branch-scoped operations require both projectId and branch. Paginated entry, asset, search, and form-submission operations return items, nextCursor, and, when available, total. Pass nextCursor back as cursor to continue. Cursors are opaque and should not be decoded or edited. Numeric offset inputs cannot be combined with cursor. Portable operations validate their outputs before returning them to generated code. The outer search and execute tools return the same JSON as text and structured content. A few contracts are worth knowing before you call them:
  • fimo.labels.setMany upserts. Every record is created or overwritten, exactly like fimo.labels.set, and the result reports upserted with how many labels were written.
  • fimo.forms.create and fimo.forms.update validate each field definition: its type must be one of the types Fimo’s form runtime renders, and label is required. fimo.forms.update must name at least one of name, label, or fields.
  • fimo.files.write limits content to 256 KiB of UTF-8, measured in bytes, so multi-byte text counts what it actually costs.
Project MCP can change Fimo projects when you grant write access. Review the requested access before approving it.
Coding agents working beside a checkout should use the Fimo CLI and installed skills instead.

What’s next

Connections

Add and manage project connections in Studio.

Agent bundles

Give reusable agents access to connected tools.

Automate your project

Choose how work starts and runs.