Nimbu Developer Docs

MCP Server

Connect Claude, ChatGPT and other AI assistants to a Nimbu site through the remote MCP server: setup, permissions, access tokens, the tool reference and limits.

Nimbu runs a remote Model Context Protocol (MCP) server. Connect an AI assistant to it and the assistant can work on one of your Nimbu sites: look up products, orders and customers, read and edit pages, channel entries and translations, upload images, and read or update theme files.

The server URL is:

https://mcp.nimbu.io/mcp

Enter it exactly as shown, including the /mcp path. Some clients compare it character by character with the address the server reports during setup, and the connection fails if the two differ.

Every connection belongs to one Nimbu user and one site. The assistant acts as you, so it can never do more than your own Nimbu account can do on that site. It is limited further by the permissions (OAuth scopes) you approve when you connect.

Connect an assistant

Most assistants connect with OAuth: you paste the server URL, sign in to Nimbu, pick a site and approve the access. Clients that only accept a fixed bearer token use a dedicated MCP access token instead.

Claude

  1. In Claude, open Settings → Connectors and choose Add custom connector.
  2. Paste https://mcp.nimbu.io/mcp as the server URL and connect.
  3. Claude opens the Nimbu sign-in and consent screen. Sign in, choose the site and approve.

For Claude Code, add the server from a terminal and follow the browser prompt:

claude mcp add --transport http nimbu https://mcp.nimbu.io/mcp

ChatGPT

Custom MCP connectors in ChatGPT need developer mode, which depends on your ChatGPT plan and workspace settings.

  1. In ChatGPT settings, open the connectors section, go to the advanced settings and turn on developer mode.
  2. Create a connector with https://mcp.nimbu.io/mcp as the server URL and OAuth as the authentication method.
  3. ChatGPT sends you to the same Nimbu sign-in and consent screen.

Menu names in Claude and ChatGPT change from time to time. If a label above doesn't match what you see, look for the place to add a custom or remote MCP connector. The URL and the sign-in flow stay the same.

Other MCP clients

The server speaks Streamable HTTP on a single stateless endpoint and returns JSON (no SSE stream, no session id). For OAuth, clients discover everything from the server:

  • Protected resource metadata: https://mcp.nimbu.io/.well-known/oauth-protected-resource
  • OAuth 2.1 authorization code flow with PKCE (S256)
  • Client registration through dynamic client registration or a Client ID Metadata Document

If your client can't do OAuth, create an MCP access token and send it as a bearer token. For clients configured with an mcp.json file (Cursor, VS Code and others):

{
  "mcpServers": {
    "nimbu": {
      "url": "https://mcp.nimbu.io/mcp",
      "headers": {
        "Authorization": "Bearer <your-mcp-token>"
      }
    }
  }
}

With Claude Code:

claude mcp add --transport http nimbu https://mcp.nimbu.io/mcp \
  --header "Authorization: Bearer <your-mcp-token>"

When an assistant connects through OAuth, Nimbu shows a consent screen before anything is granted. It shows:

  • The name of the app asking for access. For self-registered clients Nimbu marks that name as self-reported, because anyone can pick any name. When a client identifies itself by a domain, Nimbu shows that domain.
  • Where you will be sent after approving. Nimbu verifies this host, so check that it belongs to the assistant you are connecting (for example claude.ai or chatgpt.com). A desktop or command-line client shows an address on your own device instead.
  • The permissions requested, grouped as Read content, Manage content, Read commerce, Manage commerce and Theme & code.
  • A site picker (Grant access to) if your account has access to more than one site.

Only continue if you started this

If a consent screen appears that you didn't start yourself, or the redirect host isn't the assistant you meant to connect, click Cancel. Approving hands that app access to your site as you.

Access tokens issued through OAuth last two hours and the client refreshes them in the background. If a client later needs a permission you didn't grant, it can ask again and you'll see the consent screen for the extra access.

Permissions

A connection can use two things at once: the scopes you approved, and your own permissions on the selected site. Both have to allow an action. If an admin narrows your role later, the connection narrows with it on the next request. It stops working altogether if your account is locked, you lose access to the site, or the connection is revoked.

These are the scopes an MCP connection can request:

ScopeShown asAllows
read_contentread contentPages, menus, translations, the media library
write_contentupdate contentCreate, edit, publish and delete pages; translations; uploads
read_channelsread channelsChannels and their entries
write_channelsupdate channelsCreate, edit and delete channel entries
read_sensitive_channelsread privacy-sensitive channelsEntries in channels marked as privacy-sensitive
write_sensitive_channelsupdate privacy-sensitive channelsChanging entries in privacy-sensitive channels
read_productsread productsProducts and collections
write_productsupdate productsCreate and edit products
read_ordersread ordersOrders
read_customersread customersCustomers
read_themesread theme codeTheme layouts, templates, snippets and assets
write_themesupdate themesCreate and update theme files

A few rules follow from how scopes are checked:

  • A write scope includes its read scope. write_content is enough to read pages.
  • Tools the connection can't use are hidden. A connection without write scopes never sees the write tools in its tool list, so the assistant can't even try to call them.
  • search, fetch, list_sites and get_site need no scope. search and fetch only return the kinds of records your scopes allow.
  • A connection with no scopes at all only sees its own connection details.

Orders and customers are read-only through MCP. There are no write scopes for them.

Revoke access

Connections and tokens are listed in the Nimbu admin under Settings → Apps:

  • Connected AI agents lists every OAuth connection to the site, with the user it acts as and when it was last used. Click Disconnect to revoke one.
  • MCP Access Tokens lists the dedicated tokens. Click Revoke and confirm to delete one.

Revoking takes effect right away. If you don't see Apps in the settings menu, ask someone who manages the site's settings to disconnect the assistant for you.

MCP access tokens

For clients that take a token in their configuration instead of doing OAuth (Cursor, VS Code, CI jobs, your own scripts), create a dedicated MCP access token:

  1. Go to Settings → Apps and click Create new MCP token in the MCP Access Tokens section.
  2. Give it a name you'll recognise later, and pick only the scopes the assistant needs.
  3. Pick an expiry: 90 days, 1 year (the default) or never.
  4. Save and copy the token into your client's configuration.

An MCP token acts as the user who created it, on the site it was created for, and it follows that user's permissions just like an OAuth connection. It only works on mcp.nimbu.io; the REST API at api.nimbu.io rejects it. The reverse is true as well: a regular Site Access Token or REST token won't work on the MCP server. Create one MCP token per assistant so you can revoke one without touching the others.

Tools

The server exposes 37 tools. Your client shows the subset your scopes allow.

ToolWhat it doesScope
searchFull-text search across pages, products, collections and channel entries; customers and orders only when asked for explicitlynone (results follow scopes)
fetchFetch the full record for a search resultnone (results follow scopes)

Customers and orders hold personal data, so search leaves them out unless the request names them and the connection has read_customers or read_orders.

TypeSearched by defaultScopefetch id
pageyesread_contentpage:<id>
productyesread_productsproduct:<id>
collectionyesread_productscollection:<id>
entryyesread_channelsentry:<channel-slug>:<id>
customerno, name it in typesread_customerscustomer:<id>
orderno, name it in typesread_ordersorder:<id>

Pass a result's id to fetch unchanged. Types the connection has no scope for are dropped, and the response's types lists what was actually searched. degraded: true means the search for one type failed and its results are missing, so retry instead of treating the answer as complete.

Pages and navigation

ToolWhat it doesScope
list_pagesList the site's pagesread_content
get_pageRead a page's content, including a content_etagread_content
create_pageCreate a page (a draft unless you ask for it to be published)write_content
update_pageChange a page's title, slug, template, parent or SEO fieldswrite_content
update_page_contentEdit a page's content with up to 10 operations per callwrite_content
publish_pagePublish a page or take it offlinewrite_content
delete_pagePermanently delete a page and its child pageswrite_content
list_menusList the site's navigation menusread_content
get_menuRead one menu and its itemsread_content

Page edits are protected against overwriting someone else's work. update_page and update_page_content need the content_etag from a recent get_page; if the page changed in the meantime, the write is refused and the assistant has to read the page again. delete_page only proceeds when the assistant passes the page's current title.

Channels and translations

ToolWhat it doesScope
list_channelsList the site's channelsread_channels
describe_channelShow a channel's fieldsread_channels
query_channel_entriesQuery entries with filters, sorting and paginationread_channels
get_channel_entryRead one entryread_channels
create_channel_entryCreate an entrywrite_channels
update_channel_entryChange only the fields you passwrite_channels
delete_channel_entryPermanently delete one entrywrite_channels
list_translationsList the site's translation stringsread_content
upsert_translationsCreate or update up to 100 translation strings in one callwrite_content

Channels marked as privacy-sensitive also need read_sensitive_channels or write_sensitive_channels. Per-entry access rules apply to MCP just as they do to the API.

On channels with publishing enabled, create_channel_entry and update_channel_entry take two arguments for the publication state:

  • status: draft, published or scheduled. A create without status is a draft; an update without it leaves the state alone.
  • publish_at: an ISO 8601 timestamp, required when status is scheduled.

An unknown status, scheduled without publish_at, or a malformed timestamp is refused before anything is written. On a channel without publishing, passing status returns a 422. To find unpublished entries, call query_channel_entries with filters: {"_status": "draft"} (or published, scheduled).

Products, orders and customers

ToolWhat it doesScope
query_productsQuery products with filters, sorting and paginationread_products
get_productRead one product by id or slugread_products
create_productCreate a productwrite_products
update_productChange only the fields you passwrite_products
list_collectionsList product collectionsread_products
get_collectionRead one collection by id or slugread_products
query_ordersQuery orders with filters, sorting and paginationread_orders
get_orderRead one order by id or order numberread_orders
query_customersQuery customers with filters, sorting and paginationread_customers
get_customerRead one customer by id or emailread_customers

Stock and inventory fields are ignored on product writes. Customer passwords and tokens are never returned, and you can't filter customers on them.

Files

ToolWhat it doesScope
list_uploadsList the files in the site's media libraryread_content
upload_fileUpload a small file to the media librarywrite_content

An upload returns a file_ref that the assistant can put in an image or file field of a channel entry or product. Channel entries, products and pages can also take a small file inline in the same write call.

Theme

ToolWhat it doesScope
list_theme_filesList a theme's layouts, templates, snippets and assetsread_themes
get_theme_fileRead one theme file's sourceread_themes
update_theme_fileCreate or update a layout, template or snippetwrite_themes

A change to a file in the active theme goes live on your storefront immediately, the same as saving it in the admin or pushing it with the CLI. Nimbu doesn't ask for a second confirmation. Grant write_themes only when you want the assistant to change theme code.

A theme file that someone last edited in the Nimbu admin is locked, and update_theme_file won't overwrite it.

Site

ToolWhat it doesScope
list_sitesReturn the site this connection is bound tonone
get_siteRead that site's details, including its languagesnone

Tools never take a site argument. To work on another site, connect again and pick that site.

Languages

Content tools for pages, menus, channel entries, products, collections, translations, search and fetch take an optional locale argument, such as "nl" or "fr". Leave it out and the tool uses the site's default language. A write with locale only changes that language and leaves the others alone. A language the site hasn't enabled is refused; get_site lists the enabled ones.

Page reads always include every language under translations, whatever locale you pass.

Writes and retries

  • create_page, create_channel_entry, create_product and upload_file require an idempotency_key (a UUID). Retrying with the same key and the same input returns the original result instead of creating a duplicate. The same key with different input is refused with idempotency_conflict. While the first attempt is still running, or when its outcome is unknown, the answer is idempotency_in_progress: check whether the record exists, and don't retry with a new key.
  • update_product and update_channel_entry are not idempotent. Repeating an update can apply an increment twice or add another file or nested record. After a timeout or a lost response, read the record again and check what changed before you retry.
  • update_page_content needs the page's current content_etag, so a retry after a write that did land is refused. Read the page again to see the result and get the new etag.
  • Tools publish destructiveHint, idempotentHint and openWorldHint annotations. They help a client explain what a tool does, but they are hints, not a permission or confirmation check.

Limits

  • Uploads are limited to 700 KB after base64 decoding, for upload_file and for inline files. Accepted types are PNG, JPEG, GIF, WebP and PDF. SVG is not accepted. Use the Nimbu admin or the CLI for larger files.
  • Each connection can make 600 read calls and 60 write calls per five minutes. search has its own budget that depends on how many record types and results it asks for. Over the limit, the server answers with 429 and a Retry-After header.
  • A single request may batch at most 20 tool calls.
  • Lists return at most 50 items per page. Responses over roughly 50 KB are cut short, so narrow a query with filters or a smaller per_page.
  • Menus are read-only. Edit them in the Nimbu admin.
  • Some things are deliberately not available through MCP: stock changes, order status changes, customer account actions, coupons, webhooks, site settings, Cloud Code, and bulk or filtered deletes.

For client developers

  • Protocol version. The server checks the MCP-Protocol-Version header. It currently accepts 2026-07-28, 2025-11-25, 2025-06-18, 2025-03-26 and 2024-11-05; without the header it assumes 2025-03-26. Any other value returns 400 unsupported_protocol_version, before authentication.
  • Tool list changes. The server doesn't advertise listChanged and never sends notifications/tools/list_changed. The tool list still depends on the granted scopes, so call tools/list again after a scope step-up or when a call returns 403 insufficient_scope.
  • Structured content. Every result has structuredContent and the same JSON in a text block. structuredContent is always an object: a list comes back as {"items": [...]}, while the text block keeps the bare array.
  • Partial bulk writes. When a bulk write such as upsert_translations doesn't fully succeed, the tool returns an error with code: "multi_status", a summary and per-item results. Check each item's applied flag: some items may have been written.
  • Client registration. Nimbu only issues public OAuth clients with PKCE and no client secret. Dynamic client registration requires token_endpoint_auth_method: "none". A Client ID Metadata Document that declares an auth method must prefer none or list it in token_endpoint_auth_methods_supported.

Security

  • Give each assistant the fewest scopes that do the job. Start with read scopes and add write scopes when you actually want changes made.
  • Watch for prompt injection. An assistant reads whatever your site contains, including text that visitors and customers typed into forms, orders or channel entries. That text can contain instructions aimed at the assistant. With write scopes granted, a client may carry out an allowed write without asking you first, so review what the assistant proposes before you let it act.
  • Records the assistant reads, including customer and order data, are sent to the AI provider behind your assistant. Check that your agreement with that provider covers this data before you grant read_customers or read_orders.
  • Disconnect assistants and revoke MCP tokens you no longer use under Settings → Apps.

On this page