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.
Prerequisites
Before configuring your client:
- Create an OAuth application in the Finqu merchant admin or partner portal, or obtain a valid merchant OAuth access token. See Authentication and OAuth 2.0 Guide.
- Ensure your token carries the required scopes for the tools your agent intends to use (for example,
catalog_read,sales_read,themes_write). - Note the server endpoint:
https://mcp.finqu.com/mcp.
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",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN"
}
}
}
}Restart Claude Desktop after saving the file. 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.
Project configuration (.cursor/mcp.json)
Create .cursor/mcp.json in your repository root:
{
"mcpServers": {
"finqu-admin": {
"url": "https://mcp.finqu.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN"
}
}
}
}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 can connect to the same Admin MCP endpoint. Authorize access to the merchant account using Admin MCP authentication. If your client requires an explicit OAuth client or bearer token, configure it using that guide before calling store tools.
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, 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 .
Cline
Open Cline’s MCP Servers panel and its cline_mcp_settings.json configuration. Add this server, replacing
YOUR_ACCESS_TOKEN with an authorized merchant access token from the authentication guide:
{
"mcpServers": {
"finqu": {
"type": "streamableHttp",
"url": "https://mcp.finqu.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN"
}
}
}
}Set the transport explicitly to streamableHttp. Keep access tokens in your local client configuration.
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/sdkThe following example shows how to:
- Discover OAuth metadata dynamically via RFC 9728 and RFC 8414 if needed.
- Initialize the
StreamableHttpClientTransport. - Connect the MCP
Client. - 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 httpxThe 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
- Best Practices — Operating rules, confirmation gates, and error recovery
- Admin MCP Overview — Transport, channel requirements, and responses
- Authentication — OAuth discovery, token scopes, and permissions
- Tools Catalog — Complete reference of available Admin MCP tools