Skip to content
← All work
Case 08Production

Universal API MCP Server

One MCP server that lets an agent call any HTTPS API — GitHub, Vercel, Notion, Linear, AWS — with credentials it never sees. No custom MCP server per service: if a token exists, the agent can use it, only on the hosts that token is approved for.

Fig. 1 — System architectureUniversal API MCP Server
UNIVERSAL MCP SERVERAny agentClaude Code, any clientapi_requestsecret name + URLSecret vaultInfisical · names onlyHost allowlistper secretApproval gatedestructive callsAny HTTPS APIGitHub · Vercel · Notion…I approveone-time linkresponse · token redacted

← Swipe to follow the flow →

  • Trigger
  • Agent
  • Tool / data
  • Guardrail
  • Human

⊘ The agent holds names, not keys.

The problem

What this replaced

  1. 01Every new service an agent should reach means another MCP server to find, write or host.
  2. 02Or the API key goes into the agent's environment — where the model can read it, print it or send it anywhere.
  3. 03Nothing stops a key meant for one API being sent to a different host.
  4. 04Nothing stops an agent issuing a DELETE because a prompt told it to.

Who has this problem

Anyone giving agents real access to real systems — which is the whole point of an agent harness.

What it costs

Integration work scales with the number of services, and every shortcut around it widens the blast radius: a leaked key, a prompt-injected request to the wrong host, an irreversible call nobody approved.

The build

What I built

The agent gets one tool, api_request. It passes the name of a secret plus the URL, method and body; the server fetches the secret from Infisical, adds the auth itself — bearer, custom header, basic, query parameter or AWS SigV4 — makes the call and returns the response with the token redacted. Each secret carries the hosts it may be sent to, fixed when it is stored. Destructive requests — DELETE, delete-style GraphQL mutations, bodies that archive or trash — return an approval link instead of executing; a person approves that exact action once, for fifteen minutes. CLIs like aws or terraform get short-lived tokens through the same approval.

Make any API reachable by any agent without a new server per service — and without the agent ever holding a key.

Capabilities

  • 01One tool for any HTTPS API: api_request
  • 02Auth injected server-side — bearer, header, basic, query, AWS SigV4
  • 03Tokens redacted from every response
  • 04Per-secret host allowlist, fixed at storage time
  • 05Human approval for destructive calls, single-use and time-boxed
  • 06Short-lived tokens for CLIs, behind the same approval

How it runs

The workflow

  1. in

    Trigger

    An agent needs to call an API — open a PR, trigger a deploy, update a Notion page.

  2. 01

    The agent lists which secrets exist — names and approved hosts, never values

  3. 02

    It calls api_request with the secret name, URL, method and body

  4. 03

    The server checks the URL's host against that secret's allowlist

  5. 04

    Destructive request? It returns an approval link and waits for a person

  6. 05

    Otherwise it injects the credential, calls the API and redacts the token from the response

  7. out

    Output

    The API's response, with no credential anywhere in the agent's context.

Components

  • MCP server exposing api_request, list_secrets and add_secret
  • Infisical — secret storage, one folder per service
  • Per-secret host allowlist
  • Approval flow for destructive actions
  • Temporary-token issuance for CLIs

The guardrail

What it is not allowed to do

⊘ Boundary

The agent holds names, not keys.

The model never sees a credential, so it cannot leak one. A token can only travel to the hosts it was stored for, so a prompt-injected agent cannot send a GitHub token to an attacker's server. And anything irreversible — a DELETE, an archive, a destructive mutation — stops and waits for a person to approve that one action. The server gives the agent reach; the boundaries decide what that reach is allowed to touch.

Stack

What it is built on

Protocol
Model Context Protocol
Secrets
Infisical
Auth
BearerHeaderBasicQueryAWS SigV4
Clients
Claude CodeAny MCP client

Hard parts

What made it difficult

  • 01

    Deciding what counts as destructive across REST verbs, GraphQL mutation names and request bodies that soft-delete.

  • 02

    Pinning each token to its hosts so the allowlist holds even when the agent is being manipulated.

  • 03

    Redacting tokens that an API echoes back in its own response or error.

Outcome

What changed

1 server

instead of one MCP server per API

  • New integrations are a stored token with an approved host, not a new MCP server.

  • This site's own production deploy was triggered through it — a Vercel token the agent never saw.

  • Holds the tokens for GitHub, Vercel, Notion, Linear and search APIs behind one interface.

Get in touch

Building an agent that has to survive production?

I write about MCP design, evals and guardrails on LinkedIn most days. If you're working on something similar, I'm happy to talk shop.