MCP limits & security

Updated September 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 — enable only the read tools (get_*, list_*, report_*) and disable everything else. Allowing the read tools, rather than blocking write tools one by one, keeps the agent read-only as new write tools are added.
  • 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

An MCP agent acts as the user who authorized it, so its calls count against the same rate limits as that user's Dashboard activity. There is no separate MCP allowance. An agent that makes many calls in a short time can slow down or throttle Dashboard access for the people in your tenant, so use MCP access with care:

  • When an agent loops over many shipments, prefer get_shipment_list (one call) over get_shipment per row.
  • Many tools accept select (json-mask syntax) to trim the response to the fields the agent needs.
  • If calls start failing with status 429, back off before retrying.

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.