Announcing CIMD support for MCP Client registration
Learn more

Should you use Box MCP or Box API for building AI Agents?

Kuntal Banerjee
Founding Engineer

TL;DR

  • Box's tools reference currently documents 54 tools on the remote MCP server, and 16 of them are off until a Box admin turns them on. Shared links, collaborations, file moves, metadata writes, and binary uploads are all in that off-by-default set. An agent built against MCP defaults fails those actions silently.
  • Box Sign, webhooks, the events stream, retention policies, legal holds, Shield barriers, and enterprise user and group management are not exposed as MCP tools at all. They are REST-only.
  • The remote MCP server is OAuth-only and user-delegated. The REST API additionally supports JWT and Client Credentials Grant, which are the only paths that work for a background agent with no user session. JWT and CCG apps require Box admin authorization on enterprise accounts.
  • Box access tokens expire after 60 minutes and refresh tokens are single-use, valid 60 days or one refresh. Every user connection is a rotating credential you have to persist correctly or the user gets logged out of your agent.
  • Scalekit ships both a Box connector and a Box MCP connector against the same SDK, so the MCP versus API decision changes one string in your code and nothing in your credential infrastructure.

Your agent needs to read, write, and reason over content in Box. Box ships a hosted MCP server at mcp.box.com and a REST API that has been production-grade for years. They are not two views of the same surface: the capability gap is wide, the auth models diverge at exactly the point where background agents live, and the MCP tool list is not the same in every tenant you deploy into. Here is how to pick.

What Box MCP and the Box API actually are

Both paths terminate at the same Box authorization server and both spend the same API quota. What differs is the shape of what your agent sees and who has to approve it.

The remote Box MCP server

The remote Box MCP server is Box-hosted at the endpoint mcp.box.com. It exposes existing Box API functionality as a defined tool set rather than adding new capability. Connecting requires an endpoint URL, a client ID and secret, an MCP name of box-remote-mcp, and a bearer authorization token.

Auth runs against Box's own OAuth endpoints: /api/oauth2/authorize on account.box.com and /oauth2/token on api.box.com. The scopes Box documents for the server are root_readwrite, ai.readwrite, and docgen.readwrite, with docgen.readwrite requiring an Enterprise Advanced license.

One prerequisite repeats on every client integration guide Box publishes: a Box enterprise account with the MCP server enabled by an admin. The server is available on all Box plans; the gate is the admin toggle, not the plan tier. Full details are in Box's remote MCP server documentation.

The Box REST API

The Box REST API is versioned by year through the box-version header, with 2024.0, 2025.0, and 2026.0 in circulation. Requests without the header default to 2024.0. Some newer resources reject calls that omit it: Hubs endpoints return a 400 unless you send box-version: 2025.0.

The resource surface spans files, folders, search, metadata templates and taxonomies, collaborations, shared links, comments, tasks, Box AI, Box Sign, Doc Gen, Hubs, webhooks, events, retention policies, legal holds, Shield information barriers, storage policies, users, groups, and trash. Auth supports OAuth 2.0, JWT, Client Credentials Grant, and App Token. The reference lives in Box's API documentation.

Comparing them where it matters for agents

Run a single agent through both paths and the differences stop being abstract. Take a contract operations agent: find this quarter's signed agreements, pull the counterparty and renewal date out of each one, tag the files, share a summary folder with legal, and route the unsigned ones for signature.

What your agent can actually do

"Off by default" below means the tool exists on Box's server but is unavailable to agents until a Box admin turns it on for the enterprise. "Not exposed" means there is no MCP tool at all.

Capability
Box MCP (remote)
Box REST API
Keyword and metadata search
Yes
Yes
Read file content, details, previews
Yes
Yes
Box AI question answering and extraction
Yes, needs Box AI enabled
Yes, needs Box AI enabled
Create folders, copy files and folders
Yes
Yes
Move, rename, or retag files
Off by default
Yes
Write metadata to files and folders
Off by default
Yes
Upload text files
Yes
Yes
Upload binary files
Off by default, plus a direct call to the upload host
Yes
Create shared links
Off by default
Yes
Create or update collaborations
Off by default
Yes
Box Hubs
Yes
Yes, requires box-version: 2025.0
Doc Gen batch generation
Off by default, Enterprise Advanced
Yes
Box Sign requests
Not exposed
Yes
Create and assign tasks
Not exposed, list only
Yes
Webhooks and the events stream
Not exposed
Yes
Governance: retention, legal holds, users, groups
Not exposed
Yes

Where the contract agent stops

On the MCP path, finding and extracting work on defaults. Search is on, get_file_content is on, and the Box AI extraction tools are on. Then the agent reaches tagging, which needs metadata writes, and those are off. Sharing the folder needs shared links, also off. Routing for signature needs Box Sign, which does not exist as a tool.

The agent gets most of the way through the job and stalls on every step that changes something. That is the shape of the MCP gap for Box: reading and reasoning are well covered, and mutation is either gated or absent.

The tool surface is not a stable contract

Sixteen of the documented tools ship off and need an admin to enable them. Box AI tools depend on the tenant having Box AI turned on. Doc Gen depends on an Enterprise Advanced license. Box also states that new tools appear automatically for enterprises with the MCP server enabled.

Put those together and tools/list returns a different answer in tenant A than in tenant B, and a different answer in tenant A next month. For a single-tenant internal agent that is a configuration step. For a multi-tenant product it is a per-customer onboarding dependency you cannot resolve from your own dashboard.

The binary upload problem

Text uploads work on the MCP path through upload_file. Binaries do not. Box routes them through get_upload_url and get_download_url, both off by default, and both of which hand your agent a temporary URL it must call itself.

Box is explicit that this only works in code-executing environments, because declarative agents cannot make the outbound request. Several Box hosts also need upload.box.com and dl.boxcloud.com allowlisted before the transfer succeeds. If your agent moves PDFs rather than notes, this is a real integration task, not a checkbox.

The auth path each one puts you on

The MCP server is OAuth-only and always acts as the user who authorized it. There is no service-account variant. Box documents two ways to supply client credentials for it: Integration Credentials generated inside each enterprise's Admin Console, or your own OAuth application from the Developer Console. Scalekit's Box MCP connector uses the second.

The REST API supports four auth types. OAuth 2.0 for user-delegated access, JWT and Client Credentials Grant for server-to-server with no user in the loop, and App Token for Limited Access Apps. JWT and CCG both authenticate as a Service Account by default and can act as a managed user when configured with enterprise access.

Why that gap decides background agents

A nightly job that reclassifies last week's contracts has no browser and no user session. On the REST API path, JWT or CCG gives you a token without an interactive redirect. On the MCP path, there is no equivalent; every credential originates from a user consenting in a browser.

Neither path is admin-free. JWT and CCG apps must be authorized by a Box admin on enterprise accounts. OAuth 2.0 user-auth apps do not need enablement by default, but do if the enterprise has turned on app enablement controls. The difference is that the MCP path adds an admin gate on top of whichever one you already had.

What you own in production

Box owns the MCP server: hosting, tool schemas, and updates. That is a genuine reduction in surface area, and for an interactive assistant it is the right trade. What you still own is token storage per user, refresh handling, revocation, and the per-tenant configuration drift described above.

On the REST path you own request construction, pagination, error handling, retries, and the full token lifecycle. In exchange you get a version pin. You send box-version: 2026.0 and the contract holds; Box supports each stable version for at least 12 months and declares end of life 24 months ahead. The MCP tool surface has no equivalent handshake.

Rate limits apply identically, and search is the tight one

Box publishes 1,000 API requests per minute per user and 240 upload requests per minute per user. Search is the constraint a content agent actually hits: 6 searches per second per user, 60 searches per minute per user, and 12 searches per second per enterprise.

That enterprise-wide search ceiling is shared across every application in the tenant, not just yours. Box also meters API calls against a per-enterprise monthly allocation tied to the customer's plan. MCP tool calls are Box API calls; they count. Both paths return 429 with a retry-after header, and both need exponential backoff.

When Box MCP is the right path

  • You are building an interactive content assistant where users ask questions across their own Box files and Hubs, and Box AI question answering plus citations is the core value
  • Your agent is read-heavy: search, retrieve, extract, summarize, with few or no write actions
  • You are deploying into one enterprise, or into customers whose Box admins will reliably enable the server and the non-default tools you need
  • You want Box to own tool schemas and server maintenance and can absorb the surface changing under you

When the Box REST API is the right path

  • Your agent runs headless on a schedule and needs JWT or Client Credentials Grant, which the MCP server does not support
  • The workflow touches Box Sign, webhooks, the events stream, retention policies, legal holds, or user and group provisioning, none of which exist as MCP tools
  • You are shipping to many customer tenants and cannot make per-tenant admin enablement a prerequisite for your product working
  • You need a pinned API version because an unannounced schema change in your pipeline is an incident, not an inconvenience

The credential problem that exists on both paths

Pick either path and Box hands you the same object: an OAuth credential belonging to one user. What it does not hand you is anywhere to put it.

Box's refresh model punishes naive storage

Box access tokens expire after 60 minutes. Refresh tokens are valid for 60 days or one use, whichever comes first, and every refresh returns a new pair that you must persist immediately. Authorization codes expire after 30 seconds.

Miss a write and the user is disconnected until they reauthorize. Two agent threads refreshing the same connection at the same time is exactly the race condition this model produces. Box handles some concurrent-refresh cases, but the burden of persisting the rotated pair is yours. The mechanics of getting this right are covered in how to handle token refresh for AI agents.

N users means N credential lifecycles

In a multi-tenant B2B agent, every user who connects Box is a separate rotating credential with its own expiry, its own revocation event, and its own tenant boundary. The path you chose changes the token profile. It does not change the count.

Tokens have to be encrypted at rest, isolated per tenant, never logged, and never placed in LLM context. When a customer churns or an employee leaves, you need to find and invalidate every credential tied to that identity. Neither Box MCP nor the Box REST API does any of this for you. The broader challenge of secure token management for AI agents at scale applies equally to both paths.

Where Scalekit fits

Scalekit's Box connector and Box MCP connector handle the OAuth flow, vaulted token storage, and automatic refresh for both paths. Credentials resolve server-side at call time and never touch the agent runtime. The MCP versus API decision stops being an auth architecture decision.

Connecting a Box agent through Scalekit

Both connectors sit behind the same SDK and the same three calls: authorize the user, retrieve the tools that user is authorized to call, execute. The connector name is the only thing that differs.

Set up the connection

Register a Box OAuth application once, add the Scalekit redirect URI to it, and store the client credentials in the dashboard. Enable at least root_readonly and root_readwrite in Box; add manage_webhook, manage_groups, or manage_enterprise_properties only for the tools you actually call.

pip install scalekit-sdk-python langchain-openai SCALEKIT_ENV_URL=<your-environment-url> SCALEKIT_CLIENT_ID=<your-client-id> SCALEKIT_CLIENT_SECRET=<your-client-secret>

Authorize the user

Each user who connects Box becomes a connected account keyed by an identifier you control. The connection_name string must match the connection name configured in your Scalekit dashboard exactly; this is the most common integration error.

import os import scalekit.client scalekit_client = scalekit.client.ScalekitClient( client_id=os.getenv("SCALEKIT_CLIENT_ID"), client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), env_url=os.getenv("SCALEKIT_ENV_URL"), ) actions = scalekit_client.actions # "box" must match the connection name in AgentKit > Connections response = actions.get_or_create_connected_account( connection_name="box", identifier="user_123", ) if response.connected_account.status != "ACTIVE": link = actions.get_authorization_link( connection_name="box", identifier="user_123", ) print("Authorize Box:", link.link) input("Press Enter after authorizing...")

Load only the tools this user is authorized to call

The Box connector exposes 102 tools. Handing all of them to a model is the failure mode, not the feature: at roughly 200 tokens per definition, that is somewhere near 20,000 tokens of tool schema before the agent reads a single file, and a decision space no model selects well from.

actions.langchain.get_tools() returns the tools the current user's connected account is authorized to call, and a tool name filter narrows that further to the job at hand.

Run the agent loop with LangChain

The tools come back as native StructuredTool objects, so nothing about the loop below is Scalekit-specific. The full walkthrough lives in the LangChain code sample, and the pattern is unpacked further in LangChain tool calling.

from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage, ToolMessage tools = actions.langchain.get_tools( identifier="user_123", connection_names=["box"], page_size=100, ) # Scope to the contract workflow instead of all 102 Box tools allowed = { "box_search", "box_folder_items_list", "box_file_get", "box_ai_extract_structured", "box_file_metadata_create", } tools = [t for t in tools if t.name in allowed] tool_map = {t.name: t for t in tools} llm = ChatOpenAI(model="gpt-4o").bind_tools(tools) messages = [ HumanMessage( "Find PDFs in Box matching 'master services agreement' signed this " "quarter, extract the counterparty and renewal date from each, and " "write them back as file metadata." ) ] while True: response = llm.invoke(messages) messages.append(response) if not response.tool_calls: print(response.content) break for tc in response.tool_calls: result = tool_map[tc["name"]].invoke(tc["args"]) messages.append(ToolMessage(content=str(result), tool_call_id=tc["id"]))

Switching to the Box MCP connector

Moving the same agent onto Box's MCP server is a connection name change. The tools come back prefixed boxmcp_ instead of box_, and the surface narrows to the 44 tools Scalekit's Box MCP connector currently exposes.

# Same client, same loop, different connector scoped_response, _ = actions.tools.list_scoped_tools( identifier="user_123", filter={"connection_names": ["boxmcp"]}, page_size=100, ) result = actions.execute_tool( tool_name="boxmcp_search_files_keyword", connection_name="boxmcp", identifier="user_123", tool_input={ "query": "master services agreement", "file_extensions": ["pdf"], }, ) print(result.data)

One Virtual MCP endpoint for multi-tool Box agents

A contract agent rarely stops at Box. It reads the file, checks the CRM record, and posts to Slack. Wiring three separate MCP servers, each with its own auth and its own full tool list, is where multi-tool agents get expensive.

A Virtual MCP server is one endpoint that declares exactly which connections and which tools an agent role can see. You create it once per role, not once per user, and mint a short-lived session token bound to a specific user before each run.

from datetime import timedelta from scalekit.actions.models.mcp_config import McpConfigConnectionToolMapping vmcp = scalekit_client.actions.mcp.create_config( name="contract-ops-agent", connection_tool_mappings=[ McpConfigConnectionToolMapping( connection_name="boxmcp", tools=[ "boxmcp_search_files_keyword", "boxmcp_get_file_content", "boxmcp_ai_extract_structured_from_metadata_template", ], ), McpConfigConnectionToolMapping( connection_name="slack", tools=["slack_send_message"], ), ], ) config_id = vmcp.config.id mcp_server_url = vmcp.config.mcp_server_url # Before every run: confirm the user's connections are live accounts = scalekit_client.actions.mcp.list_mcp_connected_accounts( config_id=config_id, identifier="user_123", include_auth_link=True, ) for account in accounts.connected_accounts: if account.connected_account_status != "ACTIVE": print(f"{account.connection_name} needs auth: {account.authentication_link}") # Then mint a token scoped to that user token_response = scalekit_client.actions.mcp.create_session_token( mcp_config_id=config_id, identifier="user_123", expiry=timedelta(minutes=30), ) token = token_response.token

Consuming the endpoint from TypeScript with Mastra

The agent sees four tools instead of Box's full surface plus Slack's. The endpoint is static across every user; the identity attached to it is not.

npm install @scalekit-sdk/node @mastra/core @mastra/mcp @ai-sdk/openai
import { Agent } from '@mastra/core/agent'; import { MCPClient } from '@mastra/mcp'; import { openai } from '@ai-sdk/openai'; // Fetch the current user's MCP URL from your backend. // Never share one URL across users: each is pre-authenticated for one identity. const mcpUrl = await getMcpUrlForUser(currentUserId); const mcp = new MCPClient({ servers: { scalekit: { url: new URL(mcpUrl) }, }, }); const tools = await mcp.getTools(); const agent = new Agent({ name: 'contract_ops_agent', instructions: 'You review contracts in Box and report renewals to the deal channel in Slack.', model: openai('gpt-4o'), tools, }); const result = await agent.generate( 'Which master services agreements renew in the next 60 days? Post the list to #revops.' ); console.log(result.text); await mcp.disconnect();

What Scalekit adds to a Box agent

The connector solves the credential problem. Three things after that are what make a Box agent survive an enterprise security review.

Every downstream tool call is attributable

A shared Box service account is the default shortcut, and it destroys attribution. Every file read and every folder search shows up in Box's own audit trail as the bot, with admin-level reach that ignores collaboration scope and folder permissions. That failure is the subject of agent tool observability and the broader discussion in audit trails for agent auth.

Scalekit resolves the authorizing user's token at call time, so Box enforces that user's real permissions and Scalekit records who triggered the call, which tool ran, and what came back. The Box connector page documents 90 days of tool-call history, exportable to a SIEM. That is the difference between answering an auditor and guessing.

Least privilege is enforced before the API call

Storing a token is table stakes. The production question is whether this agent, calling this tool, for this tenant, in this scope, is permitted. Scalekit checks that before the request reaches Box rather than trusting a prompt to hold the line.

For Box specifically that matters because a root_readwrite token is broad by design. Tool-level scoping is how you narrow a delete-capable credential down to a read-and-tag agent. The reasoning is spelled out in access control for multi-tenant AI agents.

Multi-tenancy stays architectural

Each customer's Box credentials live in a per-tenant namespace. One Virtual MCP definition serves every user, and the session token minted before each run is what binds the endpoint to an identity. There is no per-user server to configure and no cross-tenant reachability to reason about.

The same pattern carries across connectors, so adding Salesforce or Slack to a Box agent does not mean a second auth implementation. Working examples are in the deal room sync agent and offer letter routing agent templates, and the broader argument in how tool calling auth changes when you move from single-tenant to multi-tenant.

Which one to build against

If your Box agent is interactive and read-heavy, users asking questions across their own files and Hubs with Box AI doing the retrieval, the remote MCP server is a legitimate choice. Box maintains it, OAuth handles consent, and the default tool set covers that workload well.

If your agent writes, signs, provisions, or runs on a schedule, build against the REST API. The absence of JWT and Client Credentials Grant on the MCP path is not a gap waiting to be filled; it is what the server is for. So is the absence of Box Sign, webhooks, and governance endpoints.

The question that decides it

Does your agent need to act without a user in the browser, or take an action Box has not exposed as a tool? If yes, the REST API is the only production-viable path. If no, MCP is on the table, and the per-tenant admin dependency becomes the thing to plan around rather than the thing that blocks you.

Either way, you end up holding one rotating Box credential per user, and that is infrastructure neither path builds for you.

The same analysis for the content platforms Box usually sits next to: Google Drive MCP vs API, SharePoint MCP vs API, and Dropbox MCP vs API.

Build your Box agent

Start with the Box connector docs for the REST path or the Box MCP connector docs for the MCP path. The Box connector page has the full tool list, framework snippets, and starter prompts, and the Box MCP connector page covers the MCP variant.

Browse the full connector catalog to add Salesforce, Slack, or Google Drive to the same agent, check the agent templates for working multi-tool patterns, and see AgentKit pricing for volume.

Building on Box and hitting something this article did not cover? Join the Scalekit Slack community or talk to an engineer for help on your specific setup.

No items found.
Agent
Auth Quickstart
On this page
Share this article
Agent
Auth Quickstart

Acquire enterprise customers with
‍zero upfront cost.

Every feature unlocked. No hidden fees.