Connect an AI agent
An AI agent can answer questions about your warehouse and do work for you: “which orders are stuck, and why?”, “where is order #1042?”, “start the morning’s batches”. It connects to Floormode’s MCP server, signs in as you, and can never do more than you can.
On this page
Section titled “On this page”- What you need
- Connect
- What you approve
- Taking access back
- What the agent can do
- How the agent finds its way
- Three examples
- When something goes wrong
- See also
What you need
Section titled “What you need”- The Enterprise plan.
- A Floormode person whose role includes Use the API and AI agents (REST, MCP). Administrators have it.
- An AI client that can add a remote MCP server. Claude calls it a connector, other clients a custom integration or an MCP server. Floormode speaks the current MCP version, 2026-07-28, and the earlier 2025-06-18, so newer and older clients both connect.
Connect
Section titled “Connect”-
In your AI client, add a remote MCP server with this address:
https://prod.floormode.app/mcp -
The client opens Floormode’s sign-in in your browser. Sign in with the email of your Floormode account. If you belong to more than one workspace, choose your store’s.
-
Approve the client. The next section says what the approval screen asks for.
-
Ask your question in the chat.
What you approve
Section titled “What you approve”The approval screen comes from the sign-in page of your P&H account, not from Floormode’s own pages, and its words are general. What you grant is narrower than it may sound:
- Floormode’s API for the workspace you chose: that one store’s Floormode, not your Shopify admin or any other app.
- As you, within your role. The client reads and changes what your role allows, nothing more, and every call is checked against your role as it is at that moment. A change it makes shows in the history under your name.
- For as long as you leave it connected. The screen asks to keep access: the client stays signed in without asking you each time, until you take the access back.
The screen may call the client unverified and warn about it. Most AI clients register themselves with the sign-in page when you add the server, and nobody can vouch for the publisher of a client that registered itself, so the page says so. The warning is about the client app, not about Floormode, and it changes nothing about what the client may do. Approve it only when you have just added the server yourself, in a client you trust.
Taking access back
Section titled “Taking access back”- In your AI client: remove the server (the connector). The client stops calling Floormode.
- In Floormode, at once: open the person the agent signs in as under Settings → Team and choose Deactivate, or take Use the API and AI agents (REST, MCP) out of their role. The agent’s next call is refused, whatever the client still holds.
That is why a person of its own suits an agent (see below): deactivating it takes the agent’s access back without touching yours.
What the agent can do
Section titled “What the agent can do”- It works as you. Every read and every change is checked against your role, as in the app. A change it makes shows in the history under your name.
- It can change data. Holds, stock adjustments and pick batches are writes. Ask the agent to say what it will do before it does it.
- An agent of its own. To give an agent less than your own access, invite a person for it in Settings → Team (for example
agent@yourshop.com), give that person a role with only what the agent needs plus Use the API and AI agents (REST, MCP), and sign in as that person when you connect. - Limits. Your store can make 60 calls a minute through the API, agents included. One agent request stops after 30 seconds or 200 calls.
How the agent finds its way
Section titled “How the agent finds its way”This part is for the curious and for developers; the agent does it by itself.
The server offers two tools:
describe_apianswers the index of everything the agent can call: each area (orders,inventory,picking, …) with its reads and its writes. Asked for an area,describe_api({ namespaces: ["orders"] }), it answers the area’s methods with their inputs and answers as TypeScript. Asked for words,describe_api({ search: "short stock" }), it answers the methods whose name or description holds every word.runruns the JavaScript the agent writes, in a sandbox with no network. The agent callsapp.<area>.<method>(input)and returns what it found. Several calls fit in one run.
A method’s name is the operation’s name in the API explorer with its first _ turned into a dot: orders_work_queue is app.orders.work_queue, and pick_profiles_list is app.pick.profiles_list.
Three examples
Section titled “Three examples”What the agent writes for three questions, and what the answer looks like. You never write this code yourself.
Which orders are stuck, and why?
Section titled “Which orders are stuck, and why?”const { groups } = await app.dashboard.needs_attention();const short = await app.orders.work_queue({ allocationState: "short", limit: 5 });const missing = await Promise.all( short.rows.map(async (order) => { const { gaps } = await app.orders.allocation_gaps({ shopifyOrderId: order.shopifyOrderId }); return { order: order.name, missing: gaps.map((gap) => `${gap.missingQty} × ${gap.sku ?? gap.title}`), }; }),);return { attention: groups.map(({ kind, reason, count }) => ({ kind, reason, count })), missing,};{ "attention": [ { "kind": "on_hold", "reason": "address_issue", "count": 2 }, { "kind": "short_allocation", "reason": null, "count": 3 } ], "missing": [ { "order": "#1038", "missing": ["2 × MUG-BLUE"] }, { "order": "#1041", "missing": ["1 × TEE-M-BLACK", "1 × TOTE-NAT"] } ]}Where is order #1042?
Section titled “Where is order #1042?”const { hits } = await app.search.global({ query: "#1042" });const order = hits.find((hit) => hit.type === "order" && hit.label === "#1042");if (!order) return "No order #1042.";const { entries } = await app.orders.journey({ shopifyOrderId: order.id });return entries.slice(-4).map(({ atMs, kind, subject, detail }) => ({ at: new Date(atMs).toISOString(), kind, subject, detail,}));The journey lists every step oldest first: reserved, picked, packed, label bought, shipped in Shopify, the carrier’s tracking. The last steps say where the order stands.
[ { "at": "2026-10-21T09:12:40.000Z", "kind": "packed", "subject": "PACK-1", "detail": null }, { "at": "2026-10-21T09:13:05.000Z", "kind": "label_bought", "subject": null, "detail": "00340434161094042557" }, { "at": "2026-10-21T09:13:09.000Z", "kind": "shipped_in_shopify", "subject": "DHL", "detail": null }, { "at": "2026-10-21T16:40:00.000Z", "kind": "tracking", "subject": "in_transit", "detail": "Hamburg" }]What’s short?
Section titled “What’s short?”const { rows, totalShortfallUnits } = await app.inventory.backlog_shortfall({ limit: 10 });return { totalShortfallUnits, items: rows.map(({ sku, title, demand, available, shortfall, incoming, suggestedOrderQty }) => ({ sku, title, demand, available, shortfall, incoming, suggestedOrderQty, })),};demand is what open orders owe and available what the bins hold; shortfall is the difference. incoming is already on its way, so suggestedOrderQty is what is left to order.
{ "totalShortfallUnits": 9, "items": [ { "sku": "MUG-BLUE", "title": "Mug, blue", "demand": 12, "available": 6, "shortfall": 6, "incoming": 2, "suggestedOrderQty": 4 }, { "sku": "TOTE-NAT", "title": "Tote bag, natural", "demand": 5, "available": 2, "shortfall": 3, "incoming": 0, "suggestedOrderQty": 3 } ]}When something goes wrong
Section titled “When something goes wrong”| The agent says | Means | Do |
|---|---|---|
| It has to sign in again and again | The sign-in did not reach your store’s workspace | Sign in with the email of your Floormode account, and choose your store’s workspace if asked |
| The approval screen calls it unverified | The client registered itself when you added the server | Approve it if you added the server yourself just now; see What you approve |
plan_required | Your plan does not include the API | Choose the Enterprise plan in Settings → Billing |
permission_required | Your role does not include the API | Ask an administrator to add Use the API and AI agents (REST, MCP) to your role |
RATE_LIMITED | The store’s 60 calls for this minute are used up | Wait a minute. The refused call did not run, but the calls before it in the same request did: check what was already done before asking again |
INVALID_INPUT or CONFLICT | Floormode refused the call and said why | The agent reads the reason and can correct the call |
... is not a function | The agent guessed a method name | Ask it to look the name up with describe_api |
See also
Section titled “See also”- REST quickstart: the same API for your own code
- REST API: authentication, errors and limits in full
- API explorer: every operation with its inputs
- Standalone access & your team: inviting people and their roles