Skip to Content
APIs & ToolsMCPConnecting Agents

Connecting Agents to Admin MCP

Connect external AI agents, IDE assistants, and custom applications to Finqu’s Admin Model Context Protocol (MCP) server at https://mcp.finqu.com/mcp. Once connected, your agent can discover available tools and perform merchant admin operations such as managing catalog items, reviewing orders, modifying themes, and configuring store settings.

How connection works

Finqu Admin MCP supports Dynamic Client Registration (RFC 7591) and standard OAuth 2.0 discovery (RFC 8414 and RFC 9728).

You do not need a bearer token or a pre-registered OAuth application to set up your agent or IDE. You only need to add the MCP server URL:

https://mcp.finqu.com/mcp

When your client connects for the first time, it dynamically registers as a public client and initiates the standard OAuth 2.0 flow with PKCE, prompting you to log in to your Finqu merchant account and authorize access to your store in your browser.

For headless scripts, background workers, or custom client applications without interactive OAuth discovery, you can also pass a static Bearer token using the Authorization: Bearer <token> header. See Authentication and Custom Agent Clients.

Claude Desktop

Claude Desktop supports Streamable HTTP MCP servers directly. Add the Finqu Admin MCP server to your configuration file.

Configuration path

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Configuration

Add finqu-admin to the mcpServers object in claude_desktop_config.json:

{ "mcpServers": { "finqu-admin": { "url": "https://mcp.finqu.com/mcp" } } }

Restart Claude Desktop after saving the file. Claude initiates OAuth authorization in your browser on first connection. Once authorized, Claude displays the Finqu tools in its tool catalog (hammer icon).

When asking Claude to perform tasks, instruct it to call list_channels before using channel-specific tools such as theme or navigation tools.

Cursor and Codex

Configure Cursor or Codex at the project level to give coding agents access to Finqu admin operations during development.

Cursor (.cursor/mcp.json)

Create .cursor/mcp.json in your repository root:

{ "mcpServers": { "finqu-admin": { "url": "https://mcp.finqu.com/mcp" } } }

After saving the file, open Cursor’s MCP settings or panel. Connect to the Finqu MCP server and authorize access to your store when prompted in your browser.

Codex

Add Finqu Admin MCP directly using the Codex CLI:

codex mcp add finqu --url https://mcp.finqu.com/mcp codex mcp login finqu

Sign in to complete authorization, then start a new Codex session to use your store tools.

Agent operating rules (.cursor/rules/finqu-admin.mdc)

Create an agent rule file in .cursor/rules/finqu-admin.mdc to guide the model on safe tool usage:

--- description: Rules for using Finqu Admin MCP tools globs: * alwaysApply: true --- # Finqu Admin MCP Rules When interacting with the Finqu Admin MCP server: 1. **Session initialization**: - Call `get_profile` to verify merchant context and granted scopes. - Call `list_channels` before issuing any channel-scoped tool. Store `channel_id` for subsequent calls. 2. **Channel requirements**: - Theme tools, navigation tools, and page tools require a `webstore` channel type. - Do not pass non-webstore channel IDs to theme or storefront tools. 3. **Safety and confirmation**: - Always confirm destructive operations with the user before calling write tools (e.g., deleting product variants, changing prices, unpublishing items, modifying theme files). - Display a preview of proposed changes and wait for user confirmation. 4. **Error handling**: - Inspect error responses with `{ "status": "error", "response": { "code", "message", "suggestions" } }`. - If a tool reports `revision_mismatch` or `release_missing`, refresh the state before retrying.

More editors and agents

These clients also connect directly to the Admin MCP endpoint without needing pre-configured bearer tokens.

VS Code

Add this to .vscode/mcp.json in your project:

{ "servers": { "finqu": { "type": "http", "url": "https://mcp.finqu.com/mcp" } } }

Use Start in the MCP configuration editor, complete authorization in your browser, and use the tools in Copilot’s agent mode. VS Code uses a top-level servers object. See VS Code’s MCP setup guide .

Gemini CLI

Add this to .gemini/settings.json in your project:

{ "mcpServers": { "finqu": { "httpUrl": "https://mcp.finqu.com/mcp" } } }

Run /mcp auth finqu inside Gemini CLI to authorize the connection. The httpUrl field selects Streamable HTTP; url selects the older SSE transport. See Gemini CLI’s MCP setup guide .

Claude Code

Add this to .mcp.json in your project root:

{ "mcpServers": { "finqu": { "type": "http", "url": "https://mcp.finqu.com/mcp" } } }

Alternatively, add it via CLI:

claude mcp add --transport http finqu https://mcp.finqu.com/mcp

Open /mcp in Claude Code to sign in and authorize your store tools.

Cline

Open Cline’s MCP Servers panel and its cline_mcp_settings.json configuration. Add this server:

{ "mcpServers": { "finqu": { "type": "streamableHttp", "url": "https://mcp.finqu.com/mcp" } } }

Set the transport explicitly to streamableHttp. If your client version does not support interactive OAuth discovery, you can optionally supply an authorized merchant access token in an Authorization header ("headers": { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }). See Authentication. See Cline’s MCP setup guide .

Custom Agent Clients

Build custom agent harnesses using the official Model Context Protocol SDKs in TypeScript or Python.

Session startup sequence

Every agent session must follow a standard initialization lifecycle:

TypeScript SDK (@modelcontextprotocol/sdk)

Install the official client SDK:

npm install @modelcontextprotocol/sdk

The following example shows how to:

  1. Discover OAuth metadata dynamically via RFC 9728 and RFC 8414 if needed.
  2. Initialize the StreamableHttpClientTransport.
  3. Connect the MCP Client.
  4. Execute the startup sequence (tools/list -> get_profile -> list_channels).
import { Client } from "@modelcontextprotocol/sdk/client/index.js"; import { StreamableHttpClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; interface FinquChannel { id: number; name: string; type: string; store: Record<string, unknown>; } interface FinquProfile { user: { id: number; name: string; email: string }; merchant: { id: number; name: string; hostname: string; currency_id: number }; scopes: string[]; } /** * Discover OAuth authorization server endpoints using RFC 9728 and RFC 8414. */ async function discoverOAuthMetadata(mcpUrl: string): Promise<{ authorizationEndpoint: string; tokenEndpoint: string; }> { // Step 1: Probe MCP endpoint for RFC 9728 resource metadata const probeResponse = await fetch(mcpUrl, { method: "GET" }); const authHeader = probeResponse.headers.get("www-authenticate") || ""; const match = authHeader.match(/resource_metadata="([^"]+)"/); const resourceMetadataUrl = match ? match[1] : "https://mcp.finqu.com/.well-known/oauth-protected-resource/mcp"; // Step 2: Fetch protected resource metadata const resourceRes = await fetch(resourceMetadataUrl); const resourceData = await resourceRes.json(); const authServerBase = resourceData.authorization_servers?.[0] || "https://account.finqu.com"; // Step 3: Fetch RFC 8414 authorization server metadata const serverMetaRes = await fetch(`${authServerBase}/.well-known/oauth-authorization-server`); const serverMeta = await serverMetaRes.json(); return { authorizationEndpoint: serverMeta.authorization_endpoint, tokenEndpoint: serverMeta.token_endpoint, }; } /** * Initialize and run a Finqu Admin MCP agent session. */ async function runAdminAgent(accessToken: string) { const mcpUrl = new URL("https://mcp.finqu.com/mcp"); // Initialize Streamable HTTP transport with Bearer token const transport = new StreamableHttpClientTransport(mcpUrl, { requestInit: { headers: { Authorization: `Bearer ${accessToken}`, }, }, }); const client = new Client({ name: "finqu-custom-agent", version: "1.0.0" }, { capabilities: {} }); await client.connect(transport); console.log("Connected to Finqu Admin MCP"); // Step 1: Discover available tools const toolsResult = await client.listTools(); console.log(`Discovered ${toolsResult.tools.length} admin tools`); // Step 2: Get merchant profile and active scopes const profileResult = await client.callTool({ name: "get_profile", arguments: {}, }); const profile = profileResult.content[0].text ? (JSON.parse(profileResult.content[0].text) as FinquProfile) : null; console.log(`Authenticated as merchant: ${profile?.merchant.name} (ID: ${profile?.merchant.id})`); console.log(`Granted scopes: ${profile?.scopes.join(", ")}`); // Step 3: Discover sales channels const channelsResult = await client.callTool({ name: "list_channels", arguments: {}, }); const channelsPayload = channelsResult.content[0].text ? (JSON.parse(channelsResult.content[0].text) as { merchant_id: number; channels: FinquChannel[] }) : { merchant_id: 0, channels: [] }; const webstoreChannel = channelsPayload.channels.find((c) => c.type === "webstore"); const defaultChannelId = webstoreChannel?.id || channelsPayload.channels[0]?.id; console.log(`Selected default channel ID: ${defaultChannelId} (${webstoreChannel?.name})`); // Example tool call requiring channel_id if (defaultChannelId) { const categoriesResult = await client.callTool({ name: "list_categories", arguments: { channel_id: defaultChannelId, limit: 10, }, }); console.log("Categories response:", categoriesResult.content[0].text); } await client.close(); } // Example invocation const token = process.env.FINQU_ACCESS_TOKEN || "YOUR_ACCESS_TOKEN"; runAdminAgent(token).catch(console.error);

Python SDK (mcp)

Install the official Python MCP SDK:

pip install mcp httpx

The following example establishes a session using httpx and mcp.client.session.ClientSession:

import asyncio import os import re import httpx from mcp import ClientSession from mcp.client.streamable_http import streamable_http_client MCP_URL = "https://mcp.finqu.com/mcp" async def discover_oauth_endpoints(mcp_url: str): """Discover OAuth 2.0 endpoints using RFC 9728 and RFC 8414.""" async with httpx.AsyncClient() as http: # Step 1: Probe unauthenticated endpoint probe = await http.get(mcp_url) auth_header = probe.headers.get("www-authenticate", "") match = re.search(r'resource_metadata="([^"]+)"', auth_header) meta_url = ( match.group(1) if match else "https://mcp.finqu.com/.well-known/oauth-protected-resource/mcp" ) # Step 2: Fetch protected resource metadata resource_res = await http.get(meta_url) resource_data = resource_res.json() auth_server = resource_data.get("authorization_servers", ["https://account.finqu.com"])[0] # Step 3: Fetch authorization server metadata server_meta_res = await http.get(f"{auth_server}/.well-known/oauth-authorization-server") server_meta = server_meta_res.json() return { "authorization_endpoint": server_meta.get("authorization_endpoint"), "token_endpoint": server_meta.get("token_endpoint"), } async def run_admin_session(access_token: str): """Connect to Finqu Admin MCP, run startup sequence, and invoke tools.""" headers = { "Authorization": f"Bearer {access_token}" } async with streamable_http_client(MCP_URL, headers=headers) as (read_stream, write_stream): async with ClientSession(read_stream, write_stream) as session: await session.initialize() print("Connected to Finqu Admin MCP") # 1. Discover tools tools_response = await session.list_tools() print(f"Discovered {len(tools_response.tools)} admin tools") # 2. Get profile profile_res = await session.call_tool("get_profile", arguments={}) print("Profile output:", profile_res.content[0].text) # 3. List channels channels_res = await session.call_tool("list_channels", arguments={}) print("Channels output:", channels_res.content[0].text) # Store channel_id for subsequent calls import json channel_data = json.loads(channels_res.content[0].text) channels = channel_data.get("channels", []) webstore = next((c for c in channels if c.get("type") == "webstore"), None) channel_id = webstore["id"] if webstore else (channels[0]["id"] if channels else None) if channel_id: print(f"Using channel_id: {channel_id}") products_res = await session.call_tool( "search_products", arguments={"channel_id": channel_id, "limit": 5} ) print("Products search result:", products_res.content[0].text) if __name__ == "__main__": token = os.environ.get("FINQU_ACCESS_TOKEN", "YOUR_ACCESS_TOKEN") asyncio.run(run_admin_session(token))

Next steps