Skip to content
Developers
Open app

MCP server

The Focal MCP server connects AI assistants to your Focal workspace over the Model Context Protocol. Search and browse your media library, read transcripts and on-screen text, work with boards, collections, comments and workflows, and query ad performance — directly from Claude, ChatGPT, Cursor or any MCP-compatible client.

Quick start

  • MCP endpoint: https://api.focal.inc/mcp
  • Authentication: OAuth 2.1 — you sign in to Focal and approve access in the browser. No API key needed.
  • Who can connect: any member of a Focal organization (guests can’t). Your organization admin can turn the connector off for the whole organization.
  • What the assistant can see: exactly what you can see in Focal, optionally narrowed further to specific spaces when you approve the connection.

Server details

Endpoint https://api.focal.inc/mcp
Transport Streamable HTTP (JSON-RPC over POST), stateless
Server name focal
Authorization server https://api.focal.inc (same origin)
Protected resource metadata https://api.focal.inc/.well-known/oauth-protected-resource
Authorization server metadata https://api.focal.inc/.well-known/oauth-authorization-server
MCP Apps Supported — interactive media player (ui://focal/media-player.html)

The assistant acts as you: every call runs with your own Focal permissions, so it can never read or change anything you couldn’t in the Focal app.

Authentication

Focal uses OAuth 2.1 with PKCE. Most clients handle this for you — you add the server, a browser window opens, you sign in to Focal and approve.

The approval screen

When you connect, Focal shows:

  • The app asking for access — its name and logo. Apps connecting from Claude are marked as such.
  • The permissions it gets — a summary of what the connection can do. There is nothing to untick: what the assistant is actually allowed to do comes from your own Focal permissions (see below).
  • Which spaces it can use — the whole organization, or only the spaces you pick.

The connection belongs to the organization you have selected in Focal when you approve. To connect a different organization, switch organizations in Focal first and connect again.

Permissions (scopes)

Every connection is granted all of the scopes below. They don’t decide what the assistant may do — your own Focal permissions do. The assistant acts as you, so it can only read and change what your role lets you read and change in the Focal app. For example:

  • If you can only view a board, the assistant can read it but not edit it.
  • Workflow tools work only if you are an org admin or space owner.
  • Space settings, such as media library custom fields, can only be changed by org admins and space owners.

To limit a connection, restrict it to specific spaces when you approve it. To stop it entirely, revoke it (see Managing connections).

For reference, these are the scopes a connection carries:

Scope Allows the assistant to…
spaces:read Read spaces, members and your account details
spaces:write Change space settings, such as media library custom fields
media:read Read media, folders, library views, transcripts and on-screen text
media:write Update media, folders and library views; upload media
media:delete Archive media, folders and library views
boards:read Read boards, columns, rows and views
boards:write Create and update boards, columns, rows and views
boards:delete Archive boards, columns, rows and views
collections:read Read collections
collections:write Create and update collections
collections:delete Archive collections
comments:read Read comments on media and board rows
comments:write Post, edit and react to comments as you
comments:delete Remove your own comments
workflows:read Read workflows, their runs and the step catalog
workflows:write Create, edit and publish workflows
workflows:run Start runs of published workflows, which can send Slack messages and email, upload to ad platforms and call external URLs
workflows:delete Archive workflows
metrics:read Read ad accounts and ad performance (spend, results, metrics)

Sessions and tokens

  • Access tokens last 1 hour and are refreshed automatically.
  • A connection stays signed in as long as it’s used at least once every 30 days.

Managing connections

  • Your connections: User settings → MCP lists every app you’ve connected, with a button to revoke each one. Revoking takes effect immediately.
  • Organization admins: Organization settings → Connector has the switch that enables or disables the connector for everyone in the organization. Admins can’t see or revoke other people’s individual connections — each connection is personal.

Compatible clients

Any client that supports remote MCP servers with OAuth works. Point it at https://api.focal.inc/mcp.

Claude (claude.ai, Claude Desktop, Claude mobile)

  1. Open Settings → Connectors and add Focal (or choose Add custom connector and paste https://api.focal.inc/mcp).
  2. Click Connect, sign in to Focal and approve.

On Claude Team and Enterprise plans an owner may need to add the connector for the organization first.

Claude Code

Terminal window
claude mcp add --transport http focal https://api.focal.inc/mcp

Then run /mcp inside Claude Code and choose Authenticate for focal.

ChatGPT and Codex

  • Codex CLI:

    Terminal window
    codex mcp add focal --url https://api.focal.inc/mcp
    codex mcp login focal
  • ChatGPT: add a custom connector with the URL https://api.focal.inc/mcp (requires a plan and workspace settings that allow custom connectors).

Cursor, VS Code and other clients

Add Focal as a remote (HTTP) server in the client’s MCP config, for example:

{
"mcpServers": {
"focal": { "url": "https://api.focal.inc/mcp" }
}
}

Clients that only support local (stdio) servers can use the mcp-remote bridge:

{
"mcpServers": {
"focal": { "command": "npx", "args": ["-y", "mcp-remote", "https://api.focal.inc/mcp"] }
}
}

Add Focal only once per app. Two entries for the same server in one client (for example two mcp-remote configs) share one sign-in and can keep logging each other out. Different apps — Claude and Codex, say — can be connected at the same time without any problem.

Core workflow

  1. Find your spaces — get_account shows what the connection can access; list_spaces returns the space_ids that most other tools need.
  2. Find content — search_media for natural-language search across your library (including sorting and filtering by ad performance), list_media / list_folders to browse, or list_boards → list_board_columns → list_board_tasks for boards.
  3. Go deeper — get_media for details, get_media_transcript and get_media_ocr for what’s said and shown, query_metrics for performance, open_media_player to view results.
  4. Act — update metadata, set custom field values, fill board rows, organize collections, or leave comments.

Every resource includes an html_url — a link straight to that item in the Focal web app.

Available tools

Read-only tools are marked as such to the client, so assistants can run them without asking for confirmation; write tools are annotated as writes, and archive tools as destructive.

Account, spaces and users

Tool Description
get_account The current connection: organization, granted scopes and allowed spaces
list_spaces / get_spaces Spaces this connection can access
list_users / get_users Members of a space

Media

Tool Description
search_media Natural-language and filtered search across media, including ad-metric sorting
list_media / get_media Browse media or fetch specific items
get_media_transcript Spoken-word transcript of a video or audio file
get_media_ocr Text detected on screen
get_media_download Download links for original files
update_media Update media fields such as name and description
archive_media Archive media
create_media_from_url Import media from a public URL
create_media_upload → complete_media_upload Upload a file directly: get an upload URL, upload the bytes, then complete
get_media_upload Check an upload’s status
open_media_player Open an interactive gallery and player for a set of media (in clients that support MCP Apps)

Media custom fields

Tool Description
list_media_attributes / get_media_attribute Custom fields defined on a media library
set_media_attribute_value Set a custom field’s value on media
add_media_attribute_options Add options to a tags field
create_media_attribute / update_media_attribute Create or change a custom field (org admin or space owner)
delete_media_attribute_option Permanently delete a tag option (org admin or space owner)

Folders and library views

Tool Description
list_folders / get_folders Browse folders
create_folder / update_folder / archive_folder Manage folders
list_library_views / get_library_views Saved library views
create_library_view / update_library_view / archive_library_view Manage library views

Boards

Tool Description
list_boards / get_boards Browse boards
list_board_columns / get_board_column A board’s columns and their settings
list_board_tasks / search_board_tasks Read or search rows
list_board_views A board’s views
create_board / update_board / archive_board Manage boards
create_board_column / update_board_column / archive_board_column Manage columns
create_board_task / update_board_task / archive_board_task Manage rows and their cell values
create_board_view / update_board_view / archive_board_view Manage views

Collections

Tool Description
list_collections / get_collection Browse collections
create_collection / update_collection / archive_collection Manage collections

Comments

Tool Description
list_comments / get_comments Comments on media and board rows
create_comment / update_comment / archive_comment Post, edit or remove your comments
react_to_comment Add or remove a reaction

Workflows

Tool Description
list_workflow_node_types The step types a workflow can use, with their config and outputs
list_workflows / get_workflow Browse workflows, their draft graph and validation issues
create_workflow / update_workflow / archive_workflow Manage workflows and declare their steps
publish_workflow Make a workflow’s draft the live version
start_workflow_run Start a manual run of the published version
list_workflow_runs / get_workflow_run Run history, status and per-step results

Ad performance

Tool Description
list_ad_accounts / get_ad_accounts Connected ad accounts
list_ad_campaigns / list_ad_sets Campaigns and ad sets, for filtering performance queries
list_ads / get_ads Ads, with their campaign, ad set, creatives and linked media
list_creatives / get_creatives Creatives (one piece of ad content, across every ad running it)
list_metrics Available metrics
query_metrics Query performance data such as spend and results

Feedback

Tool Description
report_feedback Tell the Focal team about a missing capability or confusing behavior

Fewer tools up front (optional)

For clients with a small tool budget, use https://api.focal.inc/mcp?tools=search. The server then lists only a few core tools (list_spaces, get_account, search_media, open_media_player, report_feedback) plus a search_tools tool the assistant uses to find the rest on demand.

Common use cases

  • “Find our top-spending TikTok videos from last month that feature a product close-up.”
  • “Summarize what’s said in these five ads and tag each with its hook type.”
  • “Fill in the Status and Concept columns on the Q4 creative board for every row that’s empty.”
  • “Make a collection of all approved UGC videos and share the link.”
  • “What did the team comment on this video, and what changed since?”
  • “Compare CTR for our static vs. video creatives across all Meta ad accounts.”

Rules for AI agents

These conventions apply across all tools and are also sent to the assistant when it connects.

  • Start with get_account or list_spaces to discover the space_ids other tools require.
  • Tools take lists. Anything acting on resources by id takes ids (or items, when each entry carries its own values). Send everything in one call rather than looping.
  • Batch results aren’t transactions. A batch returns { items, succeeded, failed } with items in request order. A failed entry carries its index and a failure in place of the resource; the successful ones stay applied. Retry only the failed entries, with a fresh idempotency_key.
  • Say what you want back. Where a tool takes fields, it’s required — there’s no “everything” default. id always comes back.
  • Board rows need columns too. Every tool returning board rows requires a columns list (ids or names from list_board_columns). Pass [] for no cell values.
  • “Not found” means “not available to you”. An id that doesn’t exist and one you can’t access return the same error.
  • Use html_url to link the user straight to what you found.
  • Report gaps with report_feedback — not for transient errors.

Limits

Limit Value
Requests per connection 600 per minute
Requests per organization 1,200 per minute (all connections combined)
Page size 1–100 items (default 25), cursor-based pagination
Items per read batch 100 (25 for transcript, OCR, download and similar per-item reads)
Items per write batch 25
Upload size Images 1 GB, video 4 GB
Upload completion window 12 hours

Errors and troubleshooting

How errors come back

Problems with a tool call (not found, missing permission, invalid arguments, conflict) come back as a normal tool result marked isError: true, so the assistant can read the message and adjust:

{ "error": { "kind": "insufficient_scope", "message": "…", "status": 403, "required_scope": "boards:write" } }
kind Meaning
not_found The item doesn’t exist or isn’t available to you
insufficient_scope The connection lacks a permission, or your Focal role doesn’t allow it
invalid_arguments The request was malformed
conflict Retry later — for example, completing an upload before the file finished uploading
internal Unexpected error; includes a request_id to share with support

Common problems

  • The client keeps asking me to sign in. Check that Focal is added only once in that client (see Compatible clients). Remove duplicates, restart the client and connect once. For mcp-remote, clearing its cached credentials (~/.mcp-auth) and reconnecting also helps.
  • “The MCP Connector is disabled for this organization.” An organization admin has turned the connector off in Organization settings → Connector.
  • I can’t approve the connection. Guests can’t connect — ask an admin for member access.
  • The assistant can’t find something I can see in Focal. The connection may be limited to certain spaces. Revoke it in User settings → MCP and reconnect with access to the space you need.
  • A write tool says insufficient_scope. Your Focal role doesn’t allow the change — for example, editing custom fields needs an org admin or space owner. Ask someone with the right role to change your access in Focal. (A connection made before all scopes were granted by default may also be missing one: revoke it in User settings → MCP and reconnect.)