Announcing CIMD support for MCP Client registration
Learn more

Read AI MCP vs Read AI API for AI Agents (2026)

Kuntal Banerjee
Founding Engineer

TL;DR

  • Read AI's remote MCP server has four tools, including two writes: dispatch a meeting agent and share a report. The REST API documents three read-only endpoints, including a live-meeting endpoint MCP lacks.
  • Both are open beta with one auth model: OAuth 2.1 with DCR, browser consent, 10-minute access tokens, and single-use rotating refresh tokens. No API keys or client credentials yet.
  • "Use the API for headless agents" fails here. Neither path has a machine credential, so background agents depend on each user's refresh chain.
  • Neither path pushes events. Read AI webhooks are a separate, app-configured surface on paid plans.
  • Scalekit's Read AI connector runs DCR, vaults each user's tokens, and refreshes the rotating chain, so MCP vs API stops being an auth decision.

The choice your Read AI agent is waiting on

Your agent needs Read AI. It has to pull yesterday's customer calls, extract decisions and action items, and maybe send a notetaker into a call that was never on the calendar. Read AI ships a remote MCP server and a REST API for exactly this; both launched in February 2026 and both are still in open beta. They read the same meeting data, but they do not expose the same actions, and the token lifecycle underneath them is stricter than most tools your agent already talks to. Here is how to pick the path, and what you still own either way.

What Read AI MCP and Read AI API actually are

Both surfaces sit on the same Read AI account data and the same OAuth authorization server. The difference is the interface, and what each one is allowed to do.

Read AI MCP: four tools on a remote server

Read AI runs the Model Context Protocol (MCP) server itself. It is a remote server on the Streamable HTTP transport, served from the /mcp path on Read AI's API host, and users authenticate with OAuth 2.1 against their own Read AI account. Read AI documents first-party setup for Claude, ChatGPT and Codex, and Microsoft Copilot Studio.

The server exposes four tools. Two read: get a meeting by its ULID, and list meetings with date filters and cursor pagination. Two act: send a Read AI meeting agent into a Zoom, Google Meet, or Microsoft Teams call, and share a meeting report with an email address. The canonical reference is the "MCP Server" article in the API and MCP section of the Read Help Center.

Read AI API: three read endpoints under /v1

The REST API serves the same data over plain HTTP. Read AI's "API Reference" article documents three endpoints: GET /v1/meetings for a paginated list, GET /v1/meetings/{id} for one meeting, and GET /v1/meetings/{id}/live for the real-time transcript and chapter summaries of an in-progress meeting.

Rich content such as summary, action_items, transcript, and recording_download comes back only when you request it through the expand[] parameter. Every endpoint takes a bearer token issued through the same OAuth 2.1 flow the MCP server uses. No other credential type is accepted today.

Both are open beta

Read AI labels both surfaces open beta in its "Read AI API and MCP Overview" article, and makes them available to all users regardless of plan. The same article lists the GA roadmap: static API keys or personal access tokens, more token lifetime options, additional endpoints and tools, and webhook or event support. Treat every detail in this post as a snapshot of beta behavior, and re-check the tool list before you pin a production agent to it.

Comparing them where it matters for agents

Read AI inverts the usual pattern. For most tools the API is the superset and MCP is a curated subset. Here each surface has something the other lacks, so the comparison starts with capability.

What your agent can actually read

Tool names below are the names Scalekit's connector exposes for Read AI's MCP tools. On reads, the two surfaces overlap almost completely.

Capability
Read AI MCP
Read AI API
List meetings with start-time filters
Yes, readaimcp_list_meetings (ISO 8601 bounds)
Yes, GET /v1/meetings (epoch-millisecond bounds)
Retrieve one meeting by ULID
Yes, readaimcp_get_meeting_by_id
Yes, GET /v1/meetings/{id}
Summary, chapters, action items, key questions, topics
Yes, via expand
Yes, via expand[]
Full transcript with speaker attribution
Yes, via expand
Yes, via expand[]
Recording download link (MP4)
Yes
Yes, recording_download
Real-time transcript of an in-progress meeting
No
Yes, /v1/meetings/{id}/live (live-enabled meetings only)

What your agent can do and react to

Actions and events are where the surfaces split.

Capability
Read AI MCP
Read AI API
Send a meeting agent into a Zoom, Meet, or Teams call
Yes, readaimcp_create_meeting_agent
Not documented
Share a report at a chosen access level
Yes, readaimcp_share_meeting_report
Not documented
Push events on meeting start or end
No
No (webhooks live in the Read AI app)
Ask Read, Coaching, or media upload
No
No

Where the gap bites: actions live only on MCP

If your agent needs to do anything in Read AI, the MCP server is the only documented path. readaimcp_create_meeting_agent takes a meeting URL, or a platform plus meeting ID, and an optional ISO 8601 start_time to schedule the bot. Read AI deduplicates dispatches: sending an agent twice to the same meeting returns the existing record.

readaimcp_share_meeting_report grants viewer_recap_only, viewer_full, or editor access, and can notify the recipient by email or grant access silently. It fails unless the authorizing user is an editor or owner of the report, and it cannot transfer ownership. Both tools create side effects in a real account. Gate them behind explicit user intent, not model inference.

Where the gap bites: live data and precise windows live on the API

The live endpoint is the API's one exclusive. It returns transcript turns and chapter summaries while a meeting runs, filterable by start_time_ms.gte, which is how an in-call copilot polls for new speech. The catch is documented: live data exists only if someone opened Read AI's live dashboard during the meeting. Read AI plans an account-wide setting for GA.

Time filters also differ. The API filters on integer epoch milliseconds; the MCP tools exposed through Scalekit take ISO 8601 strings. A deterministic job that already tracks a high-water mark in milliseconds maps directly onto the API. A model filling tool arguments from "last Tuesday" works with the human-readable format on the MCP side.

Neither path pushes events

An agent that should react when a meeting ends cannot subscribe through either surface. Read AI webhooks exist, but they are a separate product: configured in the Read AI app, available on Pro, Enterprise, and Enterprise+ plans, and signed with an HMAC SHA-256 signature in the X-Read-Signature header. Webhooks created before March 17, 2026 carry no signature.

User webhooks fire on meeting_end for the creator's own reports. Workspace webhooks, created by admins or owners, can also fire on meeting_start and push every member's reports to one endpoint. The workable pattern for event-driven agents is a webhook as the trigger and MCP or the API as the fetch.

The auth path each one puts you on

This section decides whether a Read AI agent survives production. The two paths share one auth model, and that model is tighter than it first looks.

One OAuth 2.1 flow, two audiences

The Read AI API uses OAuth 2.1 with Dynamic Client Registration and the Authorization Code grant with refresh tokens. The documented token exchange carries a code_verifier, so PKCE is part of the flow. A registered client requests meeting:read and mcp:execute alongside openid, profile, email, and offline_access, and the registration response lists both the /v1/meetings API and the /mcp server as audiences.

So the MCP vs API choice is not a credential choice. Both paths need browser-based consent from a real Read AI user, and both issue the same kind of token. Read AI's documented walkthrough also routes consent through its own hosted OAuth page, which suits one developer testing, not a product onboarding thousands of users.

The token lifecycle that breaks headless agents

Read AI access tokens expire after 10 minutes. Refresh tokens are single-use and rotate on every exchange, with a short grace period for concurrency. Read AI's own known-issues list warns that this can require manual intervention when a token chain breaks, and confirms that static API keys and client credentials are not supported yet.

For an agent, this is the whole problem. A background job that runs for 40 minutes needs at least three refreshes. Two workers refreshing the same user's token outside the grace window race each other; one wins, the other holds a dead refresh token, and that user stays disconnected until they consent again. Headless works on both paths. It depends entirely on keeping one refresh chain per user intact. For a deep dive on this problem, see how to handle token refresh for AI agents.

What per-user isolation looks like on Read AI

Read AI enforces permissions per user: the agent sees only the reports that user can open in the web app. Workspace-wide reach requires an admin to enable global report access. If the user belongs to a workspace, that workspace must also have the Downloads option enabled before the API or MCP server returns anything.

Two onboarding failures are documented. Users signing in through SAML SSO are sometimes not redirected back into the OAuth flow and have to restart it. Some external MCP clients, including VS Code and Notion, have reported problems with Read AI's authentication. Build the connect flow to detect a stalled authorization and reissue the link, rather than assuming consent always completes.

What you own in production

Read AI hosts the server either way. What changes is how much of the request, schema, and failure surface your team writes and maintains.

On the MCP path

Read AI maintains the four tool schemas and ships changes without a client redeploy; its documentation notes that compatible assistants pick up new tools as they appear. That helps while the surface is still growing toward GA. It is also a risk for a production agent, because a schema change reaches your agent the moment Read AI deploys it.

You still own token storage, the rotating refresh chain, revocation when a user disconnects, and tenant isolation. You also own write safety, since two of the four tools change state in a real account.

On the API path

You own everything the MCP server would have done: request construction, expand[] selection, cursor pagination, 4xx and 5xx handling, and the tool schema you hand the model. Read AI warns that expanding several fields, or expanding on large list requests, noticeably slows responses, so an agent expanding transcript across a full page pays for it in latency.

In exchange you get the live endpoint and a /v1 path that makes contract changes more visible than an evolving tool list. You also inherit the schema work. Writing the schema is the hard part. Not the API call.

Rate limits and pagination

The API enforces 100 requests per minute per user and returns HTTP 429 past that. Pages cap at 10 meetings on both surfaces, and the cursor is the ULID of the last meeting on the previous page. An agent summarizing a month of a busy user's calls can issue dozens of list and get calls in one task, so budget the limit per user, not per agent. Read AI publishes no separate MCP limit; plan as if the same ceiling applies.

When to use MCP, when to use the API

The decision follows the agent's job, not a protocol preference. Both lists reflect what Read AI exposes today.

Use Read AI MCP when

  • The agent is interactive and user-present: a meeting assistant in Claude, ChatGPT, or your own chat UI that answers "what did we decide with Acme yesterday" from real transcripts.
  • The agent must act in Read AI, such as sending a notetaker into an ad hoc Zoom, Meet, or Teams call, or sharing a report with a colleague at a chosen access level.
  • The agent orchestrates across tools, for example pulling action items and filing them in a CRM or tracker, and you want Read AI tools exposed the same way as every other MCP tool.
  • You are prototyping a Read AI agent and want four working tools without writing an HTTP client.

Use the Read AI API when

  • The agent works during the meeting: an in-call copilot that polls /v1/meetings/{id}/live for new transcript turns and chapter summaries.
  • The agent is a deterministic pipeline, such as a nightly export of meetings into a warehouse, where your code computes epoch-millisecond windows and walks cursors.
  • You need a request contract you control, with explicit expand[] choices per call, rather than tool schemas that change when Read AI redeploys.
  • The integration must be strictly read-only, with no write-capable tool anywhere in the agent's reach.

The credential problem that exists on both paths

Set the capability table aside. Both paths hand your agent the same problem, and it scales with your user count, not with your choice of protocol.

N users, N rotating refresh chains

Both paths require per-user credential isolation in a multi-tenant B2B agent. MCP's OAuth flow gives you a token per user. The API's OAuth flow gives you a credential per user. In neither case does the path itself solve storage, rotation, or revocation.

Read AI makes rotation unusually strict. Serve 300 users across 25 customer orgs and you hold 300 refresh chains, each access token expiring every 10 minutes, each chain broken by any refresh that lands out of order. Tokens must be encrypted at rest, isolated per tenant, and never logged. When a chain breaks, the agent must pause that user's work and resurface an authorization link, not retry into a wall. For the multi-tenant pattern, see how tool calling auth changes from single-tenant to multi-tenant.

Where Scalekit fits

Scalekit's Read AI connector handles the OAuth flow, token storage, and rotation, so the MCP vs API decision doesn't change your auth infrastructure. The connector registers with Read AI through DCR, each user signs in once, and Scalekit stores and refreshes that user's tokens in its token vault. Refresh happens in one place instead of in every agent worker, and credentials never touch the agent runtime.

Scalekit's catalog ships Read AI as an MCP connector, readaimcp, with all four tools. There is no separate API-based Read AI connector today; for the REST-only live endpoint, the route is a custom connector, covered below.

Building a Read AI agent with Scalekit

Both examples below use Python. The first runs Claude's tool-use loop against the readaimcp connection with list_scoped_tools and execute_tool. The second exposes Read AI through a Virtual MCP server to a LangChain agent.

Before you run either one, create a Read AI MCP connection in the Scalekit dashboard under AgentKit, Connections. The connection_name in code must match that connection's name exactly. A mismatch is the most common integration error, and it surfaces as a tool-not-found rather than an auth failure.

Authorize the user once

The user completes Read AI's consent screen one time. After that, the connected account holds their token chain, and your code only ever passes an identifier. If a SAML SSO user stalls mid-flow, call get_authorization_link again and resend the link.

pip install scalekit-sdk-python anthropic python-dotenv
import os from dotenv import load_dotenv from scalekit import ScalekitClient load_dotenv() scalekit_client = ScalekitClient( env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"], client_id=os.environ["SCALEKIT_CLIENT_ID"], client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], ) actions = scalekit_client.actions # Must match the connection name in AgentKit > Connections exactly CONNECTION_NAME = "readaimcp" IDENTIFIER = "user_123" # your app's stable ID for this user response = actions.get_or_create_connected_account( connection_name=CONNECTION_NAME, identifier=IDENTIFIER ) if response.connected_account.status != "ACTIVE": link = actions.get_authorization_link( connection_name=CONNECTION_NAME, identifier=IDENTIFIER ) print("Authorize Read AI:", link.link) input("Press Enter after authorizing...") response = actions.get_or_create_connected_account( connection_name=CONNECTION_NAME, identifier=IDENTIFIER ) if response.connected_account.status != "ACTIVE": raise RuntimeError( f"Read AI is {response.connected_account.status}, not ACTIVE. Authorize and rerun." )

Retrieve the tools this user is authorized to call

The agent does not load a flat connector catalog here. list_scoped_tools returns the tools this user's connected account is authorized to call, which is the Read AI surface for this identifier and nothing else. Swap the identifier and the same code serves the next user, scoped to their Read AI permissions. What the user can't do, the agent can't do.

A digest agent also has no business holding write tools, so the allowlist below keeps readaimcp_create_meeting_agent and readaimcp_share_meeting_report out of the model's context entirely.

from google.protobuf.json_format import MessageToDict scoped_response, _ = actions.tools.list_scoped_tools( identifier=IDENTIFIER, filter={"connection_names": [CONNECTION_NAME]}, page_size=100, ) # A digest agent reads meetings; it never dispatches bots or shares reports ALLOWED_TOOLS = {"readaimcp_list_meetings", "readaimcp_get_meeting_by_id"} llm_tools = [] for scoped_tool in scoped_response.tools: definition = MessageToDict(scoped_tool.tool).get("definition", {}) if definition.get("name") in ALLOWED_TOOLS: llm_tools.append({ "name": definition["name"], "description": definition.get("description", ""), "input_schema": definition.get("input_schema", {}), })

Run the Claude tool-use loop with execute_tool

Every tool_use block routes to execute_tool, which runs the call with this user's Read AI credentials held in Scalekit. The result goes back to Claude as a tool_result. The system prompt carries today's date, because the model has to compute ISO 8601 bounds for start_datetime_gte.

import json from datetime import datetime, timezone import anthropic client = anthropic.Anthropic() system_prompt = f"Today is {datetime.now(timezone.utc).date().isoformat()} (UTC)." messages = [{ "role": "user", "content": "Summarize decisions and open action items from my meetings in the last 7 days.", }] while True: response = client.messages.create( model="claude-sonnet-4-6", max_tokens=2048, system=system_prompt, tools=llm_tools, messages=messages, ) messages.append({"role": "assistant", "content": response.content}) if response.stop_reason != "tool_use": print("".join(block.text for block in response.content if block.type == "text")) break tool_results = [] for block in response.content: if block.type == "tool_use": result = actions.execute_tool( tool_name=block.name, connection_name=CONNECTION_NAME, identifier=IDENTIFIER, tool_input=block.input, ) tool_results.append({ "type": "tool_result", "tool_use_id": block.id, "content": json.dumps(result.data), }) messages.append({"role": "user", "content": tool_results})

Call a write tool directly, on explicit intent

When a user explicitly asks for a notetaker on a call, skip the model and call the tool yourself. The join link comes from the user, never from inference; Read AI's own guidance rejects guessed or inferred meeting IDs.

result = actions.execute_tool( tool_name="readaimcp_create_meeting_agent", connection_name=CONNECTION_NAME, identifier=IDENTIFIER, tool_input={ "meeting_url": os.environ["MEETING_URL"], # the join link the user supplied "title": "Acme renewal call", }, ) print(result.execution_id, result.data)

When you need the REST-only live endpoint

For an in-call copilot, define a custom REST connector through Scalekit's add-your-own-connector path, with proxy_url set to Read AI's API base host, and call it through Tool Proxy with actions.request(). Scalekit injects the connected account's token; your code never sees it.

One caution: Read AI issues API clients only through DCR, and its public walkthrough assumes Read AI's own redirect page. Confirm your client registration against Read AI's docs before you depend on this path, or talk to us and we will help you wire it.

# Requires a custom REST connector for Read AI's API. # Must match your custom connection name in AgentKit > Connections exactly. LIVE_CONNECTION = "readai-api" meeting_id = "01HFYH0A6JM4R7MZ2E6X5T9BNP" # ULID of the in-progress meeting last_seen_ms = 1733800000000 # high-water mark from your previous poll resp = actions.request( connection_name=LIVE_CONNECTION, identifier=IDENTIFIER, path=f"/v1/meetings/{meeting_id}/live", method="GET", query_params={ "expand[]": ["transcript", "chapter_summaries"], "start_time_ms.gte": last_seen_ms, }, ) resp.raise_for_status() live = resp.json()

Why build Read AI agents the Scalekit way

Two Scalekit capabilities matter most for Read AI agents specifically: attributed logs for every downstream tool call, and Virtual MCP servers for agents that span more than one tool or more than one tenant.

Attributed logs for every downstream tool call

Read AI's write tools are exactly where you want an audit trail. When readaimcp_share_meeting_report grants someone editor access, a security reviewer will ask which user authorized it, which agent ran it, and what Read AI returned. Scalekit records every tool call with that attribution, classifies failures so you can tell a Read AI API error from a connector error, and streams events to Datadog, Splunk, or any SIEM.

Each execute_tool response also returns an execution_id you can write into your own trace. See agent tool observability and audit trails for agent auth for the full model.

Virtual MCP for multi-tool, multi-tenant meeting agents

Most Read AI agents are not Read AI-only. A follow-up agent reads the meeting and posts action items to Slack, and it serves every user in your product. A Virtual MCP server gives that agent role one scoped endpoint that declares exactly which tools it can see and whose credentials it acts with, with no MCP server to deploy, host, or maintain.

One server definition serves all users. Before each run, you mint a short-lived session token scoped to that user's connected accounts. The endpoint is static; the identity is not. The agent sees only the tools you explicitly allow, not everything each connector exposes. Surface reduction is the lever.

Define the server once per agent role

The configuration below exposes two read-only Read AI tools and one Slack tool. readaimcp_create_meeting_agent and readaimcp_share_meeting_report never reach this agent. Both connection_name values must match your dashboard connections exactly.

from datetime import timedelta from scalekit.actions.models.mcp_config import McpConfigConnectionToolMapping # Run once per agent role, not once per user vmcp_response = actions.mcp.create_config( name="meeting-followup-agent", connection_tool_mappings=[ McpConfigConnectionToolMapping( connection_name="readaimcp", tools=["readaimcp_list_meetings", "readaimcp_get_meeting_by_id"], ), McpConfigConnectionToolMapping( connection_name="slack", tools=["slack_send_message"], ), ], ) config_id = vmcp_response.config.id mcp_server_url = vmcp_response.config.mcp_server_url

Mint a session token before each run

Check every connection for this user first, because a broken Read AI refresh chain shows up here as an inactive account with a re-authorization link. The session token is Scalekit's credential, not Read AI's; Read AI's 10-minute tokens stay in the vault. Set expiry longer than the expected run.

state = actions.mcp.list_mcp_connected_accounts( config_id=config_id, identifier=IDENTIFIER, include_auth_link=True, ) inactive = [ account for account in state.connected_accounts if (account.connected_account_status or "").upper() != "ACTIVE" ] if inactive: for account in inactive: print(f"{account.connection_name} needs auth: {account.authentication_link}") raise SystemExit("Complete authorization, then rerun.") session_token = actions.mcp.create_session_token( mcp_config_id=config_id, identifier=IDENTIFIER, expiry=timedelta(minutes=30), ).token

Connect a LangChain agent to the Virtual MCP server

LangChain reaches the server through langchain-mcp-adapters over Streamable HTTP, with the session token as a bearer header. The same URL and token pattern works for any MCP host.

pip install "langchain-mcp-adapters>=0.3,<1" langchain-openai
import asyncio from datetime import datetime, timezone from langchain_mcp_adapters.client import MultiServerMCPClient from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage, SystemMessage, ToolMessage async def run(): client = MultiServerMCPClient( { "scalekit": { "transport": "streamable_http", "url": mcp_server_url, "headers": {"Authorization": f"Bearer {session_token}"}, } } ) tools = await client.get_tools() tool_map = {tool.name: tool for tool in tools} llm = ChatOpenAI(model="gpt-4o").bind_tools(tools) messages = [ SystemMessage(f"Today is {datetime.now(timezone.utc).date().isoformat()} (UTC)."), HumanMessage("Find yesterday's Acme call and post its action items to #acme-account."), ] while True: response = await llm.ainvoke(messages) messages.append(response) if not response.tool_calls: print(response.content) break for tool_call in response.tool_calls: result = await tool_map[tool_call["name"]].ainvoke(tool_call["args"]) messages.append(ToolMessage(content=str(result), tool_call_id=tool_call["id"])) asyncio.run(run())

Templates and related builds

If you are building a meeting-driven agent, start from an existing pattern rather than a blank file. For adjacent meeting tools, compare Granola MCP vs Granola API and Zoom MCP vs Zoom API, or follow the sales call prep agent build with Granola and Attio.

Which one to build against

Read AI does not offer a clean MCP-or-API split. The honest answer depends on whether your agent acts, listens live, or runs unattended.

The decision in three sentences

If your agent answers questions about meetings, or has to act in Read AI by dispatching a notetaker or sharing a report, build on MCP; it is the only documented home for those actions. If your agent works during the meeting or runs as a fixed-contract pipeline, build on the API, and accept that you own the schema. Most production Read AI agents will touch both, and neither path gives you a machine credential.

That last point is the real design constraint. With 10-minute access tokens and single-use refresh tokens on both paths, the MCP vs API choice is a capability decision. Keeping every user's refresh chain alive is an infrastructure decision, and it needs production-grade infrastructure regardless of which path you are on. Understanding who holds the token across agent tool-calling patterns is the foundational question before you ship either path.

Build with the Read AI connector

Browse the Scalekit Read AI connector, read the Read AI MCP connector docs, or scan the full connector library. Agent tool calling pricing is on the Scalekit pricing page.

Building a Read AI agent and want a second pair of eyes on the auth model, the refresh chain, or the live-endpoint connector? Use the Talk to us page for immediate help.

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.