MCP limits & security

Updated May 30, 20264 min read

MCP runs on the same security and isolation guarantees as the Carriyo Dashboard — multi-tenant boundaries, per-user permissions, full audit trail. This page captures the specifics agents and their operators need to know.

Auth model

The Carriyo MCP server uses OAuth 2.1 Authorization Code with PKCE (Cognito-backed). When an agent connects:

  1. The agent opens Carriyo's authorization URL in your browser.
  2. You log into Carriyo (if you're not already signed in) and approve the agent's access.
  3. Carriyo issues the agent a token; the agent uses it on every MCP call thereafter.

There is no client_credentials flow and no service-account tokens — every MCP session is bound to a real Dashboard user. The agent inherits that user's permissions, tenant scope, and merchant scope.

Whatever you can do, the agent can do

If your Dashboard role is read-only, the agent is read-only. If you can confirm and cancel shipments, so can the agent. To restrict the agent further than your role allows, use the tool-catalog restriction below.

Tool-catalog restriction

Most MCP-aware agent clients (Claude Desktop, Cursor, custom agents) let users disable individual tools per server. This is the strongest guardrail you have for production agents.

Patterns:

  • Read-only copilot — disable every write tool (create_*, confirm_*, cancel_*, update_*, schedule_*, mark_*, refresh_*, reprocess_*, reassign_*). Leave get_*, report_*, list_* enabled.
  • Diagnostic-only — leave get_*, list_*, list_shipment_system_logs, get_shipment_system_log enabled. Disable everything else.
  • Quoter — leave only get_shipping_rates (and the lookup tools it needs) enabled.

Refer to your client's documentation for the exact UI. In Claude Desktop: Settings → MCP servers → Carriyo → Tools.

Server-published agent guardrails

The Carriyo MCP server publishes operating guidance at https://mcp.carriyo.com/mcp/docs that agent clients should pick up automatically. Two rules every agent must follow:

  1. Tenant safety. Call get_accessible_tenants first. Validate any user-requested tenant against the result before invoking shipment tools. If the requested tenant isn't accessible, do not call shipment tools.
  2. Date range required for get_shipment_list. creation_date_from and creation_date_to are mandatory. Default to the last 30 days when the user doesn't specify a range. Maximum range is 90 days. Requests without a range must fail.

If you're authoring custom agent prompts, restate these rules in your system prompt — they aren't optional.

Data scope

The agent sees exactly what the authorizing user sees — no more, no less:

  • Shipments, orders, returns: scoped to the user's tenant + merchant scope (as set in the user's Dashboard role).
  • Reports: scoped the same way; e.g. report_carrier_performance only covers carriers the merchant has accounts with.
  • Configuration data (carrier accounts, rules, locations): scoped to the tenant.

There is no shared / global data exposed via MCP.

Rate limits

MCP shares the REST API rate-limit pool. Today's per-tenant limits:

FamilyLimit
Read tools (get_*, report_*, list_*)600 calls / minute
Write tools (create_*, confirm_*, cancel_*, update_*, schedule_*, mark_*, refresh_*, reprocess_*, reassign_*)120 calls / minute
Burst window5× steady-state for 10 seconds

When an agent loops over many shipments, prefer get_shipment_list (one call) over get_shipment per row. Many tools also accept select (json-mask syntax) to trim the response — useful when the agent only needs a few fields.

Audit trail

Every MCP call is logged identically to a Dashboard action:

  • Visible in Integration Monitor in the Dashboard (a future guide will cover this).
  • Tagged with the authorizing user's identity so you can filter agent-vs-human traffic.
  • Retained for the same window as REST audit logs.

If you're running an agent in production — especially one driven by human chat — these are worth setting up before traffic flows:

  1. Use a dedicated user for the agent. Don't reuse a power-user account. If something goes wrong, you can disable the user without affecting humans.
  2. Tighten the user's role to the smallest permission set the agent needs.
  3. Restrict the tool catalog in the agent client (see above).
  4. Re-state the server guardrails in your system prompt (get_accessible_tenants first; get_shipment_list date range).
  5. Review the audit trail weekly at first. Look for tools the agent is calling that you didn't anticipate.
  6. For customer-facing agents, add an application-layer confirmation step before any write tool fires (cancel, reassign, reprocess). Don't rely on the LLM to decide.
LLMs are not deterministic

Even with a tight system prompt, an LLM will occasionally pick the wrong tool. The audit trail and tool-catalog restriction turn that risk from "production incident" into "easy to spot and roll back." Set them up before going live.