MCP servers,
gateway-proxied.
Connect GitHub, Linear, Jira, Search, Sheets — any MCP server. Route through Xcity for auth, permissioning, and per-tool cost tracking.
6-level permission cascade
Access resolution stops at the first match. From the most specific (key) to the broadest (toolset bundle).
Every auth mode covered
From public MCPs to OAuth2 + PKCE passthrough. Store credentials securely or delegate auth to the upstream.
| auth_type | Notes |
|---|---|
none | Public MCP |
api_key | Single static key |
bearer_token | Authorization: Bearer *** |
basic | HTTP basic |
oauth2 | Stored OAuth flow |
oauth2_token_exchange | RFC 8693 OBO |
delegate_auth_to_upstream | PKCE passthrough |
Three ways to invoke
Through chat completions, direct REST, or URL-namespaced endpoints.
Pass MCP tools in the tools array. The proxy intercepts tool calls, invokes the server, threads results back.
Direct REST invocation. Same auth, same tool name format {server_alias}.{tool_name}.
URL-namespaced for fixed MCP sets. Only the scoped server's tools are available.
Connect in 5 lines
import xct from "@xct/sdk"
# 1. List available MCP tools
tools = xct.mcp.list_tools() # GET /v1/mcp/tools
# 2. Use them in chat — proxy handles execution
reply = xct.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Find regressions in main"}],
tools=tools,
extra_headers={"x-mcp-servers": "github"},
) Approval workflow
Non-admin users can propose MCP servers via POST /v1/mcp/server/register. Admins review at /submissions.
Until approved, the row stays pending_review and isn't routable.