Run a company MCP gateway
Run a company MCP gateway
Set up a company MCP gateway on Speechify: create a hosted API for members of my workspace with mcp\_enabled on, in the project of my MCP and OpenAPI tools; for each tool, preview a mount with dry\_run, then apply it with the preview’s plan\_digest; tell me which tools were skipped and why; then attach the gateway’s mcp\_url to this coding agent with my Speechify API key and list its tools.
Follow [https://docs.speechify.ai/build/guides/hosted-apis/run-a-company-mcp-gateway.md](https://docs.speechify.ai/build/guides/hosted-apis/run-a-company-mcp-gateway.md).Hosted APIs are in beta and enabled per workspace.
Without the grant every /v1/apis endpoint here answers 402 hosted_apis_not_in_plan, and the console does not show them.
Every engineer attaching Linear, Sentry and your own tools to their MCP client one by one ends with a personal token per vendor, no shared limits and no record of who called what. A gateway turns that into one address: you connect each vendor once with a credential from your vault, mount its tools on a hosted API, and your people attach that API with one command. Every call runs through the hosted API’s audience check, limits and request log before it reaches a vendor, and the vendor sees your credential and the name of the person calling.
What you end up with
- A hosted API,
company-tools.apis.speechify.ai, that answers only members of your workspace. - Linear’s MCP server and your REST vendors mounted on it, each tool a route named
<connector>__<tool>so two servers never collide. - A command your people paste once into Claude Code, Cursor or any other MCP client.
In the console, Build > APIs filtered to Serves MCP lists every API that serves MCP, and a new hire opens one, creates a key and copies the command from its Connect section.
This page assumes you manage content in the workspace. Serve tools over MCP covers the route and face mechanics this guide builds on.
1. Connect each server once
A gateway fronts tool definitions, so each vendor is connected once, in the same project as the gateway.
- An MCP server is an
mcptool: its endpoint, a vault credential, andaction_classessaying which of its tools only read. See Add tools. The server must speak streamable HTTP. An SSE-only server cannot be mounted, and a server that runs only over stdio (annpxpackage) has no address to mount until its owner exposes one. - A REST vendor is an
openapitool compiled from the vendor’s OpenAPI document. See Connect a REST API. - Set
max_requests_per_minuteon each tool when your team shares the vendor’s allowance. Every gateway call, run and agent draws from that one budget.
In the console, connectors live under Build > APIs > Connectors. From a gateway’s Routes, Mount a connector offers New connector, which creates it in the gateway’s project and brings you back to the mount review.
The gateway uses the tool’s credential for everyone. A server that insists on each person’s own OAuth grant, and acts as that person, cannot be mounted with a shared credential; keep attaching that one directly in the client.
2. Create the gateway
In the console, open Build > APIs, filter to Serves MCP and choose New API: the dialog starts with Serve over MCP on and Members of this workspace as the audience. Or create it with the API:
auth_mode: workspaceadmits any member of the workspace with their own Speechify API key or console session, and checks membership again at most a minute old, so a person you remove loses the gateway within a minute.owneradmits only you, which suits a trial;consumer_keysuits a partner, but it never serves a write.- Create it in the tools’ project. A route refuses a tool from another project with
409 cross_project_reference. - Write the
descriptionfor a model. On the MCP face it is the instruction a client’s model reads before it picks a tool.
3. Mount each connector
Mounting writes one route per tool of a connector in one call.
In the console, open the gateway’s Routes and choose Mount a connector: every tool is listed with what it does and whether it runs without asking, reads are ticked, and a tool that cannot be mounted says why.
Preview first:
- Each entry in
operationscarries itsaction(create,update,unchanged,skiporstale) and, for askiporstale, thereason. - Apply by sending the same body without
dry_run, naming what to create inoperations, with the preview’splan_digest. Every create lands in one transaction. - The apply writes only the plan its preview showed. If the server changed a tool or someone edited the gateway’s routes since, it writes nothing and answers
409 mount_plan_changedwith the current plan inerror.details.plan: review that, then apply again with itsplan_digest, under a newIdempotency-Keyif you sent one, because a key replays its first answer. One digest covers the whole plan, so a preview of every tool and an apply of the few you picked share it. - The route names clients list are
<name_prefix>__<tool>, at<path_prefix>/<tool>. Both prefixes default to the connector’s name; set them when two connectors share one. - A tool whose approval is
require_approvalordisabledis skipped: nobody is on a route to approve a call. Set the tool’s approval toautoif it should run through the gateway.
4. Decide which tools may write
A mount creates reads only, unless you ask for writes.
On an API whose audience names a person (owner, workspace or user_token), send "include_writes": true and name the write tools in operations.
In the console’s mount review, a write tool stays unticked until you tick it, and says who it lets through.
- A write runs with the connector’s credential for whoever calls it, so the tool’s class and approval are the only gate. Switch on only what you would let any member do.
- Your server receives the member’s id in
Speechify-User-Identity, and the request log names them. - Each write counts against the API’s
daily_write_cap, and a client that retries with the sameIdempotency-Keygets the first answer back rather than a second issue. - A service account key cannot write through a route, and while a route serves writes the API cannot be switched to
consumer_keyorpublic.
5. Attach your people
Each person attaches with their own Speechify API key of the workspace, and the gateway’s address is the API’s mcp_url (GET /v1/apis/{api_id}).
Send your people the link from Copy link for your team on the API’s Connect section.
A member who opens it, or opens the API from Build > APIs, lands on Connect: the MCP address, Create my API key, which mints the caller’s own key, shows it once and fills it into the commands, and a command per client.
The key it creates carries the narrowest scope a key can have: a workspace gateway admits it by membership, so it needs nothing more, and a copy left in a shell profile can do little else.
--scope user attaches the gateway in every project on that machine, rather than only in the directory the command ran in.
Signing in instead of pasting a key is not available on a hosted API yet, so a client that cannot send the header, such as a claude.ai or ChatGPT connector, cannot attach to the gateway.
Any other client needs the same three things: the address from the API’s mcp_url, the streamable HTTP transport (POST only), and the Authorization header.
When someone leaves, removing them from the workspace closes the gateway to them within a minute; revoke their key as well.
6. Refresh when a server changes
Routes pin each MCP tool’s input schema when they are written, so a server’s deploy changes nothing your people’s clients see until you refresh.
Mount the connector again with dry_run: true.
In the console, each connector’s routes are grouped under it on the gateway’s Routes, with a Refresh that shows the same plan before anything is written.
- An MCP tool whose input schema changed is an
update, rewritten when you apply. - A tool the server added is a
createyou can tick; nothing is added unless you name it. - A route whose tool is gone, or can no longer be served, is
stale. It is never deleted, since a client may still call it; delete it once nobody does. - A route you renamed or moved keeps its name and path.
7. Watch each connector
A gateway’s Overview shows, per connector and for today, the calls it answered, how many failed or were throttled, and the mean time a call took, and Build > APIs shows each API’s calls today and the share of its tool calls that failed.
Per route, the API reports today’s numbers:
tool_calls, upstream_errors, upstream_throttles and upstream_latency_ms_mean cover tool routes, so a slow or failing vendor shows up as that vendor rather than as a slow gateway.
Limits that apply
What a gateway does not do: it serves tools only, not MCP resources or prompts; it holds no per-person upstream tokens; and a tool result that is not text or JSON comes back as the server’s content blocks for the client to read.
Errors
Where the rest lives
- Route and MCP face mechanics, tool routes one at a time: Serve tools over MCP.
- Connecting an MCP server: Add tools.
- Connecting a REST vendor: Connect a REST API.
- Every error code: Error handling.