Skip to content

Configuration

MCP Front uses a single JSON config file. The structure is straightforward: proxy settings at the top, MCP servers at the bottom.

{
"version": "v0.0.1-DEV_EDITION_EXPECT_CHANGES",
"proxy": {
"name": "My MCP Proxy",
"baseURL": "https://mcp.company.com",
"addr": ":8080",
"auth": {
/* auth config */
}
},
"mcpServers": {
/* server configs */
}
}

The version is currently “v0.0.1-DEV_EDITION_EXPECT_CHANGES” - this signals the config format may change. The name shows up in logs. The addr is where MCP Front listens, typically “:8080” for port 8080 on all interfaces.

For OAuth, you need baseURL (note the camelCase) set to your public URL so Google can redirect back after login. For bearer tokens, you can skip it.

The auth section defines how users authenticate. The mcpServers section lists all the MCP servers you want to proxy.

You have two options: bearer tokens or OAuth. Choose based on your security needs.

Map MCP server names to lists of valid tokens. The client’s token must be in that server’s list.

{
"auth": {
"kind": "bearerToken",
"tokens": {
"filesystem": ["dev-token-123", "prod-token-456"],
"database": [{ "$env": "DB_TOKEN" }]
}
}
}

Each key matches an MCP server name from your mcpServers section. The value is an array of valid tokens. You can mix hardcoded strings and environment variables using {"$env": "VAR_NAME"}.

For production, use OAuth with Google. Claude redirects users to Google for authentication, and MCP Front validates their domain. All sensitive fields must use environment variables for security.

{
"auth": {
"kind": "oauth",
"issuer": "https://mcp.company.com",
"allowedDomains": ["company.com"],
"allowedOrigins": ["https://claude.ai"],
"tokenTtl": "24h",
"storage": "memory",
"googleClientId": { "$env": "GOOGLE_CLIENT_ID" },
"googleClientSecret": { "$env": "GOOGLE_CLIENT_SECRET" },
"googleRedirectUri": "https://mcp.company.com/oauth/callback",
"jwtSecret": { "$env": "JWT_SECRET" },
"encryptionKey": { "$env": "ENCRYPTION_KEY" }
}
}

The issuer should match your baseURL. allowedDomains restricts access to specific email domains. allowedOrigins controls which websites can make requests.

tokenTtl controls how long JWT tokens are valid. Shorter times are more secure but require more frequent logins.

Security requirements: googleClientSecret, jwtSecret, and encryptionKey must be environment variables. The JWT secret must be at least 32 bytes. The encryption key must be exactly 32 bytes.

For production, set storage to “firestore” and add gcpProject, firestoreDatabase, and firestoreCollection fields.

Storage Architecture

MCP Front supports two storage backends:

  • Memory: Development only, data lost on restart
  • Firestore: Production, with encrypted secrets and persistent sessions

All MCP servers need a transportType field. MCP Front supports four transport types for different use cases.

For MCP servers that already expose a Server-Sent Events endpoint:

{
"mcpServers": {
"database": {
"transportType": "sse",
"url": "http://postgres-mcp:3000/sse",
"options": {
"authTokens": ["dev", "prod"]
}
}
}
}

Start MCP servers as subprocesses. Each user gets their own process. Isolation depends on your sandboxing setup:

{
"mcpServers": {
"filesystem": {
"transportType": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/data"],
"env": {
"DEBUG": "1"
}
}
}
}

MCP Front just spawns processes directly. For actual isolation, use containers, systemd sandboxing, or similar tools.

For MCP servers that use HTTP with streaming responses:

{
"mcpServers": {
"api-tools": {
"transportType": "streamable-http",
"url": "http://api-mcp:8080",
"options": {
"timeout": "30s"
}
}
}
}

For simple servers defined directly in the config (advanced use case):

{
"mcpServers": {
"simple": {
"transportType": "inline",
"options": {
"handler": "builtin-echo"
}
}
}
}

Use the options field for additional configuration:

{
"database": {
"transportType": "sse",
"url": "http://postgres-mcp:3000/sse",
"options": {
"authTokens": ["dev", "prod"],
"timeout": "30s",
"headers": {
"X-API-Key": { "$env": "DB_API_KEY" }
},
"requiresUserToken": true,
"tokenSetup": {
"displayName": "Database Token",
"instructions": "Get your token from the admin panel",
"helpUrl": "https://db.company.com/tokens"
}
}
}
}

authTokens lists bearer tokens that can access this server (bearer auth only). requiresUserToken prompts users to provide their own token via the /my/tokens web UI. This is useful for services like Notion where each user needs their own API key.

Claude can connect to specific servers using URL paths. For example, GET /database/sse connects to the “database” server, while GET /filesystem/sse connects to “filesystem”.

Any string value in the config can reference environment variables using {"$env": "VAR_NAME"}. This keeps secrets out of your config files.

{
"proxy": {
"baseUrl": { "$env": "BASE_URL" },
"auth": {
"tokens": {
"prod": { "$env": "PROD_TOKEN" }
},
"gcpProject": { "$env": "GOOGLE_CLOUD_PROJECT" }
}
},
"mcpServers": {
"database": {
"url": { "$env": "DATABASE_URL" }
}
}
}

OAuth needs these environment variables:

Terminal window
GOOGLE_CLIENT_ID=your-client-id
GOOGLE_CLIENT_SECRET=your-secret
JWT_SECRET=your-32-byte-jwt-secret-for-oauth! # Must be 32+ bytes
ENCRYPTION_KEY=your-32-byte-encryption-key-here! # Must be exactly 32 bytes

Control MCP Front behavior with these optional variables:

Terminal window
MCP_FRONT_ENV=development # Relaxes OAuth validation for local dev
LOG_LEVEL=debug # Options: debug, info, warn, error
LOG_FORMAT=json # Options: json (structured) or text (human-readable)

Set MCP_FRONT_ENV=development when testing OAuth locally. It allows http:// URLs and reduces security requirements.

{
"version": "v0.0.1-DEV_EDITION_EXPECT_CHANGES",
"proxy": {
"name": "Dev Proxy",
"addr": ":8080",
"auth": {
"kind": "bearerToken",
"tokens": {
"filesystem": ["dev-token-123"]
}
}
},
"mcpServers": {
"filesystem": {
"transportType": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
}
}
}
{
"version": "v0.0.1-DEV_EDITION_EXPECT_CHANGES",
"proxy": {
"name": "Production Proxy",
"baseURL": "https://mcp.company.com",
"addr": ":8080",
"auth": {
"kind": "oauth",
"issuer": "https://mcp.company.com",
"allowedDomains": ["company.com"],
"allowedOrigins": ["https://claude.ai"],
"tokenTtl": "4h",
"storage": "firestore",
"googleClientId": { "$env": "GOOGLE_CLIENT_ID" },
"googleClientSecret": { "$env": "GOOGLE_CLIENT_SECRET" },
"googleRedirectUri": "https://mcp.company.com/oauth/callback",
"jwtSecret": { "$env": "JWT_SECRET" },
"encryptionKey": { "$env": "ENCRYPTION_KEY" },
"gcpProject": { "$env": "GOOGLE_CLOUD_PROJECT" },
"firestoreDatabase": "(default)",
"firestoreCollection": "mcp_front_oauth_clients"
}
},
"mcpServers": {
"database": {
"transportType": "sse",
"url": { "$env": "DATABASE_MCP_URL" }
},
"analytics": {
"transportType": "sse",
"url": { "$env": "ANALYTICS_MCP_URL" }
}
}
}