# Admin MCP Best Practices Building production-grade AI agents that operate a Finqu merchant store requires careful channel context management, safety gates, robust error recovery, and clear prompt instructions. This guide outlines standard practices for building resilient agent workflows on Admin MCP. ## Channel Resolution Finqu stores operate across multiple sales channels (online webstores, point-of-sale registers, feeds, and partner marketplaces). Because products, themes, and navigation can vary by channel, many admin tools require a `channel_id` parameter. ### Discovery and session caching At the start of every agent session: 1. Call `list_channels` to discover all available channels. 2. Filter channels by `type` and identify the primary channel for the user's intent. 3. Cache the selected `channel_id` in the agent's context window or session state. ```json { "merchant_id": 42, "channels": [ { "id": 101, "name": "Flagship Webstore", "type": "webstore", "store": { "url": "https://example.com" } }, { "id": 102, "name": "Downtown POS", "type": "pos", "store": {} } ] } ``` ### Channel type compatibility Different tool groups enforce channel type constraints: | Tool Group | Supported Channel Types | Notes | | ---------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------- | | Theme & Template tools | `webstore` | Liquid templates, section groups, and theme settings only apply to online storefronts | | Navigation & Pages | `webstore` | Menu links, CMS pages, and blog articles belong to a webstore | | Marketing & Social | `webstore`, `pos` | Marketing messages and social media posts support both web and physical channels | | Catalog & Inventory | Any channel | Products, variants, and stock levels are merchant-wide but can have channel-specific pricing/visibility | Passing a non-webstore `channel_id` to a theme tool produces an error: ``` Validation Error: The specified channel (ID: 102) is of type 'pos'. Theme tools require a 'webstore' channel. ``` If the merchant has multiple webstore channels and the user's intent does not specify one, your agent should list the matching channels and ask the user to clarify before proceeding. ## Safety and Confirmation Gates Admin agents hold write access to real commerce operations. Unchecked automation can lead to lost revenue, broken storefront layouts, or deleted customer data. ### Categorize operations by risk Separate tools into read, low-risk mutation, and high-risk destructive operations: ``` Low Risk (Autonomous Execution Allowed) ├── Read tools: search_products, get_order, list_channels, get_theme_file └── Low-impact mutations: add_order_note, tag_customer, create_draft_product High Risk (Require Human Confirmation) ├── Catalog: delete_product, delete_variant, bulk_update_prices, unpublish_product ├── Orders & Finances: cancel_order, issue_refund, create_manual_charge ├── Storefront & Brand: update_theme_file, delete_theme_section, modify_store_settings └── Inventory: adjust_inventory_level, finalize_stock_transfer ``` ### Implement confirmation prompts For any high-risk action, prompt the user with a structured change summary before executing the tool: ```typescript interface ActionProposal { tool: string; resourceId: string | number; action: "delete" | "update" | "refund" | "unpublish"; summary: string; changes: Record; } function formatConfirmationPrompt(proposal: ActionProposal): string { return [ `Action proposal: ${proposal.action} ${proposal.tool}:`, `- Target: ${proposal.resourceId}`, `- Summary: ${proposal.summary}`, "- Changes:", ...Object.entries(proposal.changes).map( ([field, { current, proposed }]) => ` * ${field}: ${JSON.stringify(current)} -> ${JSON.stringify(proposed)}` ), "", "Proceed with this update? (yes/no)", ].join("\n"); } ``` Do not execute the mutation tool until the user sends an explicit affirmative response. ## Error Recovery and Suggestions Admin MCP tool errors provide structured JSON payloads designed for autonomous agent self-correction. ### Structure of an error response When a tool fails, Admin MCP sets `isError: true` on the tool result content. The text payload contains: ```json { "status": "error", "response": { "message": "Resource revision mismatch. The resource has been modified since it was loaded.", "code": "revision_mismatch", "suggestions": { "current_revision": "a8f9c1b2", "action": "reload_resource" } } } ``` ### Handling common error codes | Code | Cause | Agent Recovery Strategy | | -------------------- | ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | | `release_missing` | The specified theme release ID is inactive or deleted | Call `list_theme_releases` to fetch the current active release ID, update parameters, and retry | | `revision_mismatch` | Concurrent edit occurred; resource revision token is stale | Re-fetch the target resource with `get_*` to retrieve the latest state and revision hash, reapply modifications, and retry | | `write_failed` | Validation failure on one or more payload fields | Inspect `suggestions` for field-level error messages. Adjust parameter types or formats and retry | | `insufficient_scope` | The OAuth token lacks permission for this tool | Stop execution and inform the merchant which OAuth scope is missing (e.g. `themes_write`) | ### Automated retry handler example ```typescript interface ToolErrorPayload { status: "error"; response: { message: string; code?: string; suggestions?: Record; }; } async function handleToolExecution(client: any, toolName: string, args: Record) { const result = await client.callTool({ name: toolName, arguments: args }); if (result.isError) { const rawText = result.content[0]?.text || "{}"; let errorData: ToolErrorPayload; try { errorData = JSON.parse(rawText); } catch { throw new Error(`Tool execution failed: ${rawText}`); } const { code, message, suggestions } = errorData.response; // Handle stale revision concurrency if (code === "revision_mismatch") { console.warn("Revision mismatch detected. Refreshing resource..."); // Re-fetch resource, update args with latest revision, and retry if (args.product_id) { const fresh = await client.callTool({ name: "get_product", arguments: { product_id: args.product_id }, }); const freshData = JSON.parse(fresh.content[0].text); return await client.callTool({ name: toolName, arguments: { ...args, revision: freshData.revision }, }); } } // Handle missing theme release if (code === "release_missing" && args.channel_id) { console.warn("Release missing. Looking up current active release..."); const releases = await client.callTool({ name: "list_theme_releases", arguments: { channel_id: args.channel_id }, }); const releaseList = JSON.parse(releases.content[0].text); const activeRelease = releaseList.find((r: any) => r.is_active); if (activeRelease) { return await client.callTool({ name: toolName, arguments: { ...args, release_id: activeRelease.id }, }); } } throw new Error(`Unrecoverable tool error [${code}]: ${message}`); } return JSON.parse(result.content[0].text); } ``` ## Prompt Engineering for Admin Agents Equip your agent harness with clear system instructions and tool usage constraints. ### Recommended system prompt ```markdown You are an authorized Finqu Commerce Admin Assistant. You operate the merchant's store using the Finqu Admin MCP toolset. Core Operational Rules: 1. Discovery First: - Call get_profile at the start of a conversation to identify the merchant and confirmed scopes. - Call list_channels before calling any tool that accepts channel_id. Store the webstore channel ID in context. 2. Precision & Verification: - Never guess resource IDs, SKUs, or variant IDs. Always use search_* or list_* tools first to locate the exact entity. - When updating prices, verify the currency from get_profile and specify exact decimal amounts. 3. Safety & Human Confirmation: - Always ask for merchant confirmation before making destructive or high-impact changes (e.g., deleting products, unpublishing items, modifying Liquid theme templates, altering order records). - Display the current value alongside the proposed new value when requesting confirmation. 4. Error Self-Correction: - If a tool returns an error payload with status="error", inspect the response.code and suggestions object. - If the code is revision_mismatch, re-fetch the item to obtain the new revision and re-apply changes. - If the code is release_missing, query list_theme_releases to find the current active theme release. ``` ## Next steps - [Connecting Agents](./connecting-agents) — Setup recipes for Claude Desktop, Cursor, and SDKs - [Admin MCP Overview](./admin) — Transports, endpoints, and response envelopes - [Authentication](./authentication) — OAuth discovery, token scopes, and permissions - [Tools Catalog](./tools) — Grouped catalog of available Admin MCP tools