Skip to main content

Permit MCP Gateway quickstart

Create a Permit MCP Gateway host, get a gateway URL for one Model Context Protocol (MCP) server, and connect your MCP client to it. This quickstart is for AI agent builders who want their agent's tool calls authenticated, authorized, and logged without changing the MCP server or the agent.

When you finish, your MCP client calls the MCP server through the gateway, and the call appears in the gateway activity log.

Prerequisites

  • A Permit.io account with permission to create an organization-scoped API key.
  • An MCP client: Cursor, VS Code, Claude Desktop, or Claude Code.
  • The URL of the MCP server you want to secure, such as https://mcp.linear.app/mcp.

1. Create an account and a host

A host is a gateway instance with its own subdomain, users, and policies. Each host is linked to one Permit environment.

  1. Sign up at app.agent.security.
  2. Connect your Permit.io organization with an organization-scoped API key.
  3. Go to Dashboard > Create Host, then pick a subdomain, a project, and an environment.

The gateway base URL for the host has this form:

https://<your-subdomain>.agent.security/mcp

The examples on this page use the host acme-brave-coral-37.agent.security. Replace it with your own host.

2. Get a gateway URL for your MCP server

Choose how the gateway finds the upstream MCP server:

OptionUse whenAdmin control
Dynamic MCPYou want to try the gateway with any MCP server right awayUsers can connect to any MCP server URL
Pre-imported MCP serverYou want admins to approve each MCP server and review its toolsUsers can connect only to servers an admin imported and granted

Option A: Dynamic MCP (quickest path)

With Dynamic MCPs enabled on the host, you point the gateway at any MCP server by adding a query parameter. You don't import the server first.

  1. In app.agent.security, open your host's Settings and turn on Allow Dynamic MCPs.
  2. Build the gateway URL by appending ?upstream_mcp= and the MCP server URL to the gateway base URL:
https://<your-subdomain>.agent.security/mcp?upstream_mcp=<url-of-target-mcp-server>

Example gateway URLs:

Target MCP serverGateway URL
Linearhttps://acme-brave-coral-37.agent.security/mcp?upstream_mcp=https://mcp.linear.app/mcp
GitHubhttps://acme-brave-coral-37.agent.security/mcp?upstream_mcp=https://api.githubcopilot.com/mcp/
A custom serverhttps://acme-brave-coral-37.agent.security/mcp?upstream_mcp=https://internal.example.com/mcp
Dynamic MCPs bypass the admin allow-list

When Allow Dynamic MCPs is on, users of the host can connect to any MCP server URL, including servers an admin never reviewed. Tool calls are still authorized and logged. Turn the setting off in the host's Settings to limit users to imported servers.

Option B: Pre-imported MCP server

Import the MCP server first when you want admins to control which servers users can reach.

  1. Go to MCP Servers > Create Server.
  2. Enter the upstream URL, such as https://mcp.linear.app/mcp, and click Connect.
  3. Review the trust level the gateway assigned to each tool, change any you need, and click Import.
  4. On the Humans page, grant yourself or your users access to the server.

Users who connect with the host base URL pick the MCP server during the consent flow:

https://acme-brave-coral-37.agent.security/mcp

To skip the server selection step, append the upstream URL as a query parameter:

https://acme-brave-coral-37.agent.security/mcp?upstream_mcp=https://mcp.linear.app/mcp

Or use a path-based URL with the server key assigned during import (linear in this example):

https://acme-brave-coral-37.agent.security/mcp/linear

3. Connect your MCP client

Add the gateway URL to your MCP client configuration. Replace the example URL with your own gateway URL.

Remove direct connections to the same MCP server

If your client also has a direct connection to the same MCP server, the agent can call the server through that connection and skip the gateway. Remove the direct entry so only the gateway URL remains.

Cursor

Add the server to .cursor/mcp.json:

{
"mcpServers": {
"linear": {
"url": "https://acme-brave-coral-37.agent.security/mcp?upstream_mcp=https://mcp.linear.app/mcp"
}
}
}

VS Code reads MCP servers from .vscode/mcp.json, which uses a top-level servers key instead of mcpServers. See the VS Code MCP server documentation for the file format.

Claude Desktop

Add the server to your Claude Desktop config file. The file is ~/Library/Application Support/Claude/claude_desktop_config.json on macOS and %APPDATA%\Claude\claude_desktop_config.json on Windows. The config uses mcp-remote, a community tool that connects Claude Desktop to the gateway's Streamable HTTP endpoint and handles the OAuth sign-in.

{
"mcpServers": {
"linear": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://acme-brave-coral-37.agent.security/mcp?upstream_mcp=https://mcp.linear.app/mcp"]
}
}
}

Claude Code

Run this command to add the gateway as an MCP server in Claude Code:

claude mcp add --transport http linear "https://acme-brave-coral-37.agent.security/mcp?upstream_mcp=https://mcp.linear.app/mcp"

4. Complete the consent flow

The first time your MCP client connects, it opens a browser window for the consent flow:

  1. Sign in: create an account or sign in to the host.
  2. Select the MCP server: pick the server to connect to. The server is pre-selected if the URL includes upstream_mcp or a server path.
  3. Set a trust level: choose what the agent can do. Low allows read tools, medium adds write tools, and high adds destructive tools.
  4. Accept: the gateway saves the permissions and the MCP client receives an access token.

For each screen of the consent flow, see Consent service.

5. Verify that tool calls go through the gateway

  1. Ask your agent to perform a read action, such as "list my Linear issues". The agent returns results from the MCP server.
  2. In app.agent.security, open the Agents page and select your MCP client. The tool call appears in the activity log as allowed.

If the agent returns a permission error, the tool's trust level is higher than the trust level you set during consent. See Troubleshooting for this and other errors.

Next steps