Docs & FAQ

Everything you need to publish, secure, and connect your MCP or agent.

How the platform works

What is mcpchannel.ai?

A marketplace and proxy gateway for MCP servers and agents. As a provider you publish your MCP listing once. Consumers subscribe and the platform gateway routes all their tool calls to your server — handling auth, metering, and billing.

What is the gateway?

Every consumer tool call goes through the mcpchannel.ai gateway before reaching your server. The gateway authenticates the consumer, injects any OAuth token or provider headers, enforces usage caps, and records metered usage. Your server only has to handle the tool call itself.

What does a request to my MCP server look like?

POST https://your-mcp-server.com/mcp
Authorization: Bearer <consumer-oauth-token>   ← injected by gateway (if OAuth enabled)
X-MCP-Market-Verification: mkt_v1_abc9f3...    ← platform-generated, always sent
X-Provider-Key: your-static-secret              ← from your Provider auth headers (if set)
Content-Type: application/json

{"jsonrpc":"2.0","method":"tools/call","params":{"name":"your_tool","arguments":{}}}

Provider auth headers

What are Provider auth headers?

Static key-value headers you configure once on your listing. The gateway sends them on every request to your MCP server — introspection, tool calls, everything. Use them so your server can verify that requests are coming from the gateway.

When should I add Provider auth headers?

Any time your MCP server requires authentication before accepting requests. If your server is open to the internet with no auth, you don't need them — but it's strongly recommended to add at least one so random internet traffic can't call your tools.

What header name should I use?

ScenarioHeader nameExample value
No OAuthAuthorizationBearer my-secret-key-123
OAuth enabledX-Provider-Keymy-secret-key-123
Multiple auth layersX-Provider-Key + X-Tenant-Idkey + tenant
Custom API keyX-Api-Keysk-abc123

If OAuth is enabled, avoid Authorization — the gateway overwrites it with the consumer's live Bearer token. Use X-Provider-Key instead.

How do I verify Provider auth headers on my server?

JavaScript
// Express / Node.js
const key = req.headers["x-provider-key"];
if (key !== process.env.PROVIDER_SECRET) {
  return res.status(401).json({ error: "Unauthorized" });
}
Python
# Flask / FastAPI
key = request.headers.get("X-Provider-Key")
if key != os.environ.get("PROVIDER_SECRET"):
    return jsonify({"error": "Unauthorized"}), 401
Go
// net/http
key := r.Header.Get("X-Provider-Key")
if key != os.Getenv("PROVIDER_SECRET") {
    http.Error(w, "Unauthorized", http.StatusUnauthorized)
    return
}

X-MCP-Market-Verification

What is X-MCP-Market-Verification?

A platform-generated secret unique to your listing. The gateway always injects it. Your server can check it to confirm that requests came through the marketplace gateway — not from someone calling your MCP directly.

How is it different from Provider auth headers?

Provider auth headersX-MCP-Market-Verification
Set byYouPlatform (auto-generated)
What it provesRequests use your secret keyRequests came through the gateway
RequiredNo (recommended)No (optional check)
ChangesOnly when you update itNever (stable per listing)

How do I check X-MCP-Market-Verification on my server?

JavaScript
const verify = req.headers["x-mcp-market-verification"];
if (verify !== process.env.MCP_MARKET_VERIFICATION_TOKEN) {
  return res.status(401).json({ error: "Not from marketplace" });
}
Python
import os
verify = request.headers.get("X-MCP-Market-Verification")
if verify != os.environ.get("MCP_MARKET_VERIFICATION_TOKEN"):
    return jsonify({"error": "Not from marketplace"}), 401
Go
import "os"
verify := r.Header.Get("X-MCP-Market-Verification")
if verify != os.Getenv("MCP_MARKET_VERIFICATION_TOKEN") {
    http.Error(w, "Not from marketplace", http.StatusUnauthorized)
    return
}

Copy the verification secret from the Market verification section on your listing's edit page after saving.

Consumer OAuth

What is Consumer OAuth?

An optional flow where each consumer authenticates with their own identity before calling tools. The gateway fetches a fresh Bearer token per consumer and injects it as Authorization: Bearer <token> on every request to your server. Your server validates the token to know which user is calling.

When should I enable Consumer OAuth?

Use caseEnable OAuth?
MCP with a static API key (same for all users)No — use Provider auth headers
MCP where each user has their own account (GitHub, Google, Slack…)Yes — authorization_code
System-to-system, no per-user dataNo
Internal tool, consumers have their own OAuth credentialsYes — client_credentials

What is the difference between client_credentials and authorization_code?

Grant typeWhen to useWho owns the OAuth app?User interaction
client_credentialsSystem-to-system. Consumer has their own OAuth app credentials.ConsumerNone — fully automated
authorization_codeEach consumer logs in with their own account (GitHub, Google, Slack…)You (the provider)Consumer clicks Authorize once

How does authorization_code work with GitHub? (provider sets up once)

For GitHub OAuth, you create one OAuth App as the provider. Consumers just click Authorize — they never handle credentials.

  1. 1Go to GitHub → Settings → Developer settings → OAuth Apps → New OAuth App
  2. 2Set Authorization callback URL to: https://mcpchannel.ai/oauth/callback
  3. 3Copy your Client ID and Client Secret from GitHub
  4. 4In your listing: Authorize URL = https://github.com/login/oauth/authorize
  5. 5In your listing: Token URL = https://github.com/login/oauth/access_token
  6. 6Store your GitHub app Client ID + Secret in the Provider OAuth credentials section (coming soon)
  7. 7Consumers click 'Connect GitHub' → authorize once → gateway handles their token forever

Provider OAuth credentials storage is coming soon. Currently the platform uses client_credentials flow where each consumer provides their own credentials.

How does client_credentials work? (consumer brings their own credentials)

For system-to-system flows, each consumer has their own client_id and client_secret issued by your OAuth server.

  1. 1Enable Consumer OAuth on your listing
  2. 2Leave Authorize URL empty (no consent screen needed)
  3. 3Set Token URL to your OAuth server's token endpoint
  4. 4Consumer enters their client_id and client_secret in Dashboard → Subscriptions
  5. 5Gateway calls client_credentials grant automatically on each tool call
  6. 6Your server receives Authorization: Bearer <token> and validates it

What is the platform's OAuth callback URL?

https://mcpchannel.ai/oauth/callback

// This is the redirect_uri the platform uses during authorization_code flows.
// Register this exact URL in your OAuth provider's app settings
// (GitHub, Google, Slack, etc.) as the allowed redirect URI.

How does the gateway inject the OAuth token?

The gateway calls your Token URL server-to-server, gets a fresh access_token, and injects it as Authorization: Bearer <token> on the request to your MCP. Your server then validates the token against your OAuth provider's /userinfo or introspection endpoint to identify the consumer.

Why can't I use Authorization in Provider auth headers when OAuth is on?

The gateway sets Authorization: Bearer <consumer-token> on every request. If you also put Authorization in your Provider auth headers, the gateway overwrites it — your static key is lost. Use X-Provider-Key instead so both values reach your server without conflict.

How do I validate the OAuth token on my server?

JavaScript
// Call your OAuth provider's userinfo endpoint
const res = await fetch("https://api.github.com/user", {
  headers: { Authorization: req.headers["authorization"] },
});
if (!res.ok) return reply.status(401).send({ error: "Invalid token" });
const user = await res.json();
// user.login = GitHub username, user.id = GitHub user ID
Python
import httpx
token = request.headers.get("Authorization")
r = httpx.get("https://api.github.com/user",
               headers={"Authorization": token})
if r.status_code != 200:
    return jsonify({"error": "Invalid token"}), 401
user = r.json()  # user["login"] = GitHub username
Go
token := r.Header.Get("Authorization")
req, _ := http.NewRequest("GET", "https://api.github.com/user", nil)
req.Header.Set("Authorization", token)
resp, err := http.DefaultClient.Do(req)
if err != nil || resp.StatusCode != 200 {
    http.Error(w, "Invalid token", http.StatusUnauthorized)
    return
}

Validating your MCP

What does the Validate button do?

It calls your MCP's introspection endpoint (tools/list, prompts/list, resources/list) using the URL and headers you've configured, and reports back how many tools, prompts, and resources were found. This confirms the gateway can reach your server before you publish.

My MCP requires OAuth — how do I validate it?

Expand the Consumer OAuth section, enter your Token URL, Client ID, and Client Secret, then click Fetch token. The token fills in automatically. Then click Validate — the gateway calls your server with that token in the Authorization header.

Validation fails with 'Could not reach Token URL'

The token fetch goes server-to-server (Next.js → your OAuth server), so CORS is not an issue. Check that: (1) your OAuth server is running, (2) the Token URL is correct and publicly reachable, (3) your Client ID and Secret are valid.

Validation fails with 401 Unauthorized

Your MCP server rejected the request. Check that the Provider auth headers match what your server expects, and if OAuth is on, that the fetched token is valid and your server's token validation logic is correct.

Use cases

Static API key only (no OAuth)

Your MCP server has one shared API key. All consumers use the same key — the gateway holds it.

  1. 1Leave Consumer OAuth unchecked
  2. 2Add Provider auth header: Authorization → Bearer your-api-key
  3. 3Your server checks req.headers["authorization"]

Per-user OAuth with GitHub

Your MCP reads the consumer's GitHub repos. Each consumer authenticates with their own GitHub account.

  1. 1Enable Consumer OAuth
  2. 2Authorize URL: https://github.com/login/oauth/authorize
  3. 3Token URL: https://github.com/login/oauth/access_token
  4. 4Add Provider auth header: X-Provider-Key → your-gateway-secret (to verify requests are from the gateway)
  5. 5Consumer connects once in their dashboard
  6. 6Gateway injects their GitHub token on every tool call

System-to-system with client_credentials (no user login)

Your MCP server is an internal tool. Consumers provide their own client_id and client_secret — no consent screen.

  1. 1Enable Consumer OAuth
  2. 2Leave Authorize URL empty
  3. 3Token URL: https://your-auth-server.com/oauth/token
  4. 4Consumer enters their client_id and client_secret in their dashboard
  5. 5Gateway calls client_credentials grant automatically

Maximum security — both Provider key and Market verification

Block both unauthorized callers and direct calls that bypass the marketplace.

  1. 1Add Provider auth header: X-Provider-Key → your-secret
  2. 2On your server: check x-provider-key matches your secret
  3. 3On your server: also check x-mcp-market-verification matches the value from your listing edit page
  4. 4Any request missing either header is rejected

Still have questions?

Open an issue or reach out — we're happy to help.

Publish your MCP