Skip to content

Docs

What an agent gets when it connects, the limits it runs under, and copy-paste setup for every Claude surface.

Capabilities

What it can and cannot do

10 read-only tools over one Zoho Inventory organization. The limits are enforced by the server, not by the prompt.

Can

  • Look up items by id or exact SKU, with price and stock per warehouse location.
  • Check stock for several known items in one call: up to 25 item ids or 5 SKUs, such as every line of a cart.
  • Fetch a sales order with its line items, packages, tracking numbers and invoices in one call.
  • Search customers by name, company, email or phone, and list their sales orders and invoices.
  • List invoices by status, customer or due date, with balances in minor units.
  • Trace a Razorpay reference (pay_, order_, rfnd_) to the payment, invoice and sales order it settled.
  • Report its own connection: organization, data center, plan, requested read scopes, budget left and circuit state.
  • Page through lists with an opaque cursor: limit defaults to 20, max 100.
  • Attach as_of and a zoho_url deep link to every result so a person can verify it.

Cannot

  • Create, edit, cancel or delete anything. It requests only READ scopes, its client issues GET only, and no write tool exists.
  • Search sales orders freely. Zoho documents no filters on /salesorders, so the connector uses bounded fallbacks (customer lookups, packages, at most 3 pages × 200) and says when a scan was partial.
  • Return unbounded data. Lists stop at 100 rows and every result stays under about 10K tokens.
  • Show raw customer email or phone numbers; they come back masked.
  • Take instructions from merchant data. Notes and descriptions are wrapped as untrusted_text so an agent treats them as data.
  • Use more than its share of the merchant’s Zoho quota (see rate limits below).

Never does

  • Mirror merchant data into its own database; only a short-TTL cache keyed by tenant.
  • Pass Zoho tokens to an agent, or store a refresh token unencrypted.
  • Log tokens, auth codes, client secrets or unmasked contact details.
  • Let the public demo touch a real Zoho organization.

Reference

Tools

Server name merchantbridge, so agents see mcp__merchantbridge__zoho_*. Every result uses the same envelope: data, page and meta.

Integrate

Use it from Claude

The demo server needs no key. A connected organization uses the bearer key from the connect flow.

Claude Code

Public demo server (synthetic data, no key):

Terminal
claude mcp add --transport http mb-demo https://merchantbridge-api.vercel.app/mcp/demo

Your own Zoho organization, with the key shown once after connecting:

Terminal
claude mcp add --transport http merchantbridge https://merchantbridge-api.vercel.app/mcp --header "Authorization: Bearer mb_live_YOUR_KEY"

Claude Agent SDK

agent.ts
import { query } from '@anthropic-ai/claude-agent-sdk';

for await (const message of query({
  prompt: 'Is CHAI-250 in stock in Bengaluru, and at what price?',
  options: {
    mcpServers: {
      merchantbridge: {
        type: 'http',
        url: 'https://merchantbridge-api.vercel.app/mcp',
        headers: { Authorization: `Bearer ${process.env.MERCHANTBRIDGE_KEY}` },
      },
    },
    allowedTools: ['mcp__merchantbridge__*'],
  },
})) {
  if (message.type === 'result') console.log(message);
}

Tools appear as mcp__merchantbridge__zoho_*. For the demo server, use https://merchantbridge-api.vercel.app/mcp/demo and drop the header.

Claude Messages API (MCP connector)

Shell
curl https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "anthropic-beta: mcp-client-2025-11-20" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-haiku-4-5",
    "max_tokens": 1024,
    "messages": [{"role": "user", "content": "Is CHAI-250 in stock in Bengaluru, and at what price?"}],
    "mcp_servers": [{
      "type": "url",
      "url": "https://merchantbridge-api.vercel.app/mcp",
      "name": "merchantbridge",
      "authorization_token": "mb_live_YOUR_KEY"
    }],
    "tools": [{"type": "mcp_toolset", "mcp_server_name": "merchantbridge"}]
  }'

Requires the mcp-client-2025-11-20 beta header and both halves: the mcp_servers entry and an mcp_toolset that names it. The server must be reachable from the public internet, so this does not work against localhost. Replace mb_live_YOUR_KEY with your key.

Claude.ai custom connector

  1. Open Customize → Connectors → Add custom connector.
  2. Name it MerchantBridge demo and paste the URL below.
  3. Leave the OAuth fields empty: the demo server needs no sign-in.
  4. Enable it in a chat and ask about CHAI-250.
Remote MCP server URL
https://merchantbridge-api.vercel.app/mcp/demo

Disconnect

Revokes the Zoho refresh token at Zoho, marks the connection revoked and disables the key that made the call. Local revocation happens even if Zoho is unreachable.

Shell
curl -X POST https://merchantbridge-api.vercel.app/api/connection/disconnect \
  -H "Authorization: Bearer mb_live_YOUR_KEY"

Rate governor

Sharing the merchant’s Zoho quota

Zoho limits each organization, not each app, so every agent and integration shares one budget. The governor keeps this connector well inside it. Block duration and daily reset time are undocumented by Zoho; the values below are the connector’s defaults.

Per minute
80 requests per organization, below Zoho’s 100/min hard limit.
Concurrency
Leases of 4 in-flight calls on the free plan, 8 on paid plans (Zoho allows 5 / 10).
Daily share
At most 50% of the plan’s daily quota, leaving the rest for the merchant’s other integrations.
Code 44
Zoho blocked the org for the minute: a 60 s circuit opens and calls fail fast with RATE_LIMITED and retry_after_s.
Code 45
Daily quota exhausted: DAILY_QUOTA_EXHAUSTED, never retried until the UTC-midnight reset.
Code 1070
Concurrency exceeded: requeued with jittered backoff.
5xx / timeout
Up to two retries, 10 s per attempt; a call queues at most 10 s before RATE_LIMITED.

Security

Security notes

  • Two separate credentials: the merchant authorizes Zoho once with OAuth; agents use a per-tenant mb_live_ key that is shown once and stored only as a SHA-256 hash.
  • Zoho refresh tokens are encrypted with AES-256-GCM; access tokens refresh single-flight, so twenty parallel calls cause one token request.
  • Every tool call writes exactly one usage event (tool, status, error code, latency, masked arguments), success or failure.
  • Tenant id is part of every database row, cache key and governor key.
  • Errors are tool results with isError: true and a code, message, retryable flag and hint, so an agent can recover instead of crashing.

Source: github.com/jayasinghthakur/merchantbridge