marcos2872/mcp-redirect-server
If you are the rightful owner of mcp-redirect-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
The MCP Redirect Server is a NestJS-based server with integrated OAuth authentication, designed to facilitate real-time communication and secure access to resources.
MCP Transparent Proxy Server
Servidor MCP (Model Context Protocol) que atua como um proxy transparente entre sistemas OAuth e servidores MCP com autenticação simples. O proxy é invisível para a IA - tools, resources e prompts do servidor externo aparecem como se fossem nativos.
🎯 Objetivo
Este servidor atua como um bridge duplo de autenticação, resolvendo dois problemas de incompatibilidade:
- Cliente → Este Servidor: Autenticação OAuth 2.1 com GitHub
- Este Servidor → MCP Externo: Autenticação via API (email/senha → Bearer token)
Fluxo Completo:
┌─────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Cliente │ │ MCP Proxy │ │ Servidor MCP │
│ MCP │◄───────►│ (Este projeto) │◄───────►│ Externo │
│ │ OAuth │ │ Bearer │ (API Login) │
│ GitHub │ 2.1 │ OAuth + API │ Token │ Email/Pass │
└─────────────┘ └──────────────────┘ └─────────────────┘
🚀 Características
Autenticação Dupla:
- 🔐 OAuth 2.1 com GitHub - Cliente autentica via OAuth no frontend
- 🔑 API Login Automático - Servidor faz login automático na API externa (email/senha)
- 🎫 Bearer Token Management - Gerencia tokens automaticamente para o servidor MCP externo
- 🔄 Auto Refresh Token - Renova tokens expirados automaticamente
- ⏱️ Token Caching - Cache inteligente de tokens com validação de expiração
Proxy Features:
- 🌉 Bridge Transparente - Conecta diferentes tipos de autenticação
- 🛠️ Proxy Tools - 6 ferramentas para acessar servidor MCP externo
- 📡 SSE Transport - Server-Sent Events para comunicação em tempo real
- 🔄 Auto-Reconnect - Reconexão automática em caso de falha de autenticação
- 🔒 JWT Security - Proteção de rotas com JWT
- 💉 Dependency Injection - Sistema DI completo do NestJS
- 📝 Logs Detalhados - Monitoramento completo de autenticação e proxy
- 🛡️ Error Recovery - Recuperação automática de erros de token expirado
📦 Instalação
pnpm install
⚙️ Configuração
1. Criar GitHub OAuth App
- Acesse: https://github.com/settings/developers
- Clique em "New OAuth App"
- Preencha:
- Application name:
mcp-redirect-server - Homepage URL:
http://localhost:3000 - Authorization callback URL:
http://localhost:3000/auth/callback
- Application name:
- Copie o Client ID e Client Secret
2. Configurar variáveis de ambiente
Crie um arquivo .env baseado no .env.example:
cp .env.example .env
Edite o .env e adicione suas credenciais:
# OAuth Provider (GitHub) - Para autenticação do cliente
GITHUB_CLIENT_ID=seu_client_id_aqui
GITHUB_CLIENT_SECRET=seu_client_secret_aqui
# JWT Configuration (mínimo 32 caracteres)
JWT_SECRET=my-super-secure-jwt-secret-key-with-at-least-32-characters
# Server Configuration
SERVER_URL=http://localhost:3000
RESOURCE_URL=http://localhost:3000/sse
# Port
PORT=3000
# External API Authentication - Para autenticação no servidor MCP externo
EXTERNAL_API_LOGIN_URL=https://api-externa.com/auth/login
EXTERNAL_API_USER=seu_email@example.com
EXTERNAL_API_PASSWORD=sua_senha_segura
# External MCP Server - URL SSE do servidor MCP externo
EXTERNAL_MCP_URL=https://api-externa.com/sse
3. Descrição das Variáveis
Autenticação do Cliente (OAuth GitHub):
GITHUB_CLIENT_ID- Client ID do OAuth App do GitHubGITHUB_CLIENT_SECRET- Client Secret do OAuth App do GitHubJWT_SECRET- Chave secreta para JWT (mínimo 32 caracteres)
Autenticação no Servidor Externo (API Login):
EXTERNAL_API_LOGIN_URL- URL da API de login do servidor externo- Exemplo:
https://meuservidor.com/auth/login - O servidor fará POST com
{ email, password }nesta URL
- Exemplo:
EXTERNAL_API_USER- Email/usuário para autenticação na API externaEXTERNAL_API_PASSWORD- Senha para autenticação na API externa
Configuração do Proxy MCP:
EXTERNAL_MCP_URL- URL SSE do servidor MCP externo- Exemplo:
https://meuservidor.com/sse - Deve ser o endpoint SSE que implementa o protocolo MCP
- Exemplo:
Importante:
- O servidor faz login automático na
EXTERNAL_API_LOGIN_URLusando email/senha - A resposta deve conter um campo
tokenouaccess_token - Opcionalmente, pode conter
expires_in(tempo de expiração em segundos) - Se
expires_innão for fornecido, assume-se 1 hora de validade - Este token é usado como Bearer token nas requisições para
EXTERNAL_MCP_URL - O token é automaticamente renovado quando próximo da expiração (5 minutos antes)
🏃 Executar o projeto
# desenvolvimento
pnpm run start:dev
# produção
pnpm run start:prod
O servidor estará disponível em: http://localhost:3000
🔌 Endpoints
Endpoints OAuth (Cliente):
GET /.well-known/oauth-authorization-server- Metadata do servidor OAuth (RFC 8414)GET /.well-known/oauth-protected-resource- Metadata MCP (RFC 9728)POST /auth/register- Registro dinâmico de cliente (RFC 7591)GET /auth/authorize- Endpoint de autorização OAuthGET /auth/callback- Callback OAuth do GitHubPOST /auth/token- Endpoint de token OAuthPOST /auth/revoke- Revogação de token OAuth
Endpoint MCP:
GET /sse- Endpoint SSE para conexão MCP (requer autenticação OAuth)
🧪 Testar com MCP Inspector
- Abra o navegador em:
http://localhost:3000/mcp - Configure o Inspector:
- Transport Type: SSE
- URL:
http://localhost:3000/sse - Connection Type: Via Proxy
- Clique em Authentication para configurar OAuth
- Clique em Connect
A Client não sabe que existe um proxy! 🎭
� Como Funciona
Fluxo de Autenticação Dupla:
1. Cliente se autentica no Proxy (OAuth GitHub):
Cliente → GET /auth/authorize
→ Redireciona para GitHub
→ Usuário autoriza
→ GET /auth/callback
→ Recebe JWT token
2. Proxy se autentica no Servidor Externo (API Login):
Proxy → POST EXTERNAL_API_LOGIN_URL
→ Body: { email: USER, password: PASS }
→ Recebe: { token: "Bearer..." }
→ Armazena token
3. Cliente usa o Proxy com proxy tools:
Cliente → callTool('proxy_list_tools') com JWT
Proxy → Valida JWT do cliente
Proxy → Conecta ao servidor externo com Bearer token
Proxy → client.listTools() via SSE
Servidor Externo → Retorna lista de tools
Proxy → Retorna resposta ao cliente
Fluxo Completo de uma Chamada:
┌─────────┐ 1. OAuth JWT ┌───────────┐ 2. Bearer Token ┌──────────┐
│ Cliente │ ───────────────→ │ Proxy │ ─────────────────→│ Servidor │
│ MCP │ │ Server │ │ Externo │
│ │ ←─────────────── │ │ ←──────────────── │ MCP │
└─────────┘ 4. Resposta └───────────┘ 3. Resposta └──────────┘
Inicialização Automática:
Quando o servidor inicia:
- ✅ Configura OAuth com GitHub para clientes
- ✅ Faz login automático na API externa
- ✅ Armazena o token com informações de expiração
- ✅ Conecta ao servidor MCP externo via SSE com Bearer token
- ✅ Registra as proxy tools
- ✅ Fica pronto para aceitar conexões de clientes
Sistema de Refresh Token:
O servidor implementa um sistema inteligente de gerenciamento de tokens:
Cache de Token:
┌──────────────────────────────────────────────────────┐
│ Token armazenado em memória com timestamp │
│ Validade: expires_in - 5 minutos (margem segurança) │
│ Reutilizado enquanto válido (evita logins extras) │
└──────────────────────────────────────────────────────┘
Renovação Automática:
1️⃣ Antes de cada operação MCP
→ Verifica se token está próximo de expirar
→ Se sim, renova automaticamente
2️⃣ Em caso de erro de autenticação (401/403)
→ Detecta erro de autenticação
→ Força refresh do token
→ Reconecta com novo token
→ Retenta operação automaticamente
Fluxo de Refresh:
Operação MCP solicitada
↓
Verifica expiração do token
↓
Token válido? ─── NÃO ──→ POST /auth/login
│ ↓
SIM Novo token + expires_in
↓ ↓
Usa token em cache Atualiza cache
↓ ↓
└──────────→ Executa operação MCP
↓
Erro 401/403? ─── SIM ──→ Força refresh
│ ↓
NÃO Reconecta cliente
↓ ↓
Retorna resultado Retenta operação
Benefícios do Sistema:
- ✅ Zero Downtime: Tokens renovados antes de expirar
- ✅ Recuperação Automática: Erros de autenticação tratados automaticamente
- ✅ Performance: Cache evita logins desnecessários
- ✅ Transparente: Cliente não percebe renovações
- ✅ Resiliente: Reconexão automática em falhas
📚 Documentação
Conceitos principais:
- Double Authentication Bridge: Ponte entre OAuth (cliente) e API Login (servidor externo)
- Proxy Tools: ferramentas para acessar servidor MCP externo de forma controlada
- Token Management: Gerenciamento automático de JWT (cliente) e Bearer tokens (servidor)
- Auto Refresh Token: Sistema inteligente que renova tokens antes de expirar
- Token Caching: Cache de tokens com validação de expiração para melhor performance
- Error Recovery: Recuperação automática de erros de autenticação com retry
- SSE Transport: Comunicação em tempo real via Server-Sent Events
Links úteis:
- MCP-Nest Documentation
- Model Context Protocol Spec
- NestJS Documentation
- OAuth 2.1 Specification
- MCP SDK Documentation
🚀 Benefícios
- ✅ Bridge Duplo: Conecta OAuth (cliente) com API Login (servidor externo)
- ✅ Sem Modificação: Usa servidores MCP existentes sem mudanças
- ✅ Segurança em Camadas: OAuth no frontend + Bearer token no backend
- ✅ Gerenciamento Automático: Tokens gerenciados e renovados automaticamente
- ✅ Zero Downtime: Renovação preventiva de tokens antes da expiração
- ✅ Resiliente: Recuperação automática de falhas de autenticação
- ✅ Performance Otimizada: Cache de tokens evita logins desnecessários
- ✅ Isolamento de Credenciais: Servidor externo nunca vê credenciais OAuth
- ✅ Logs Detalhados: Monitoramento completo de autenticação e proxy
- ✅ Produção-Ready: Implementação completa do protocolo MCP
- ✅ Flexível: Fácil configuração via variáveis de ambiente
🔒 Segurança
- ✅ OAuth 2.1: Autenticação segura de clientes via GitHub
- ✅ JWT Tokens: Tokens assinados e validados
- ✅ Credenciais Isoladas: Senhas apenas em variáveis de ambiente
- ✅ Logs Sanitizados: Senhas nunca aparecem nos logs
- ✅ Bearer Tokens: Comunicação segura com servidor externo
- ✅ Token Rotation: Renovação automática de tokens para segurança contínua
- ✅ Margem de Segurança: Tokens renovados 5 minutos antes de expirar
- ✅ HTTPS Ready: Preparado para produção com HTTPS
🎯 Formato de Resposta da API Externa
A API externa (EXTERNAL_API_LOGIN_URL) deve retornar uma resposta JSON no seguinte formato:
Resposta Mínima:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
ou
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Resposta Recomendada (com expiração):
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 3600
}
Campos suportados:
tokenouaccess_token(string, obrigatório) - Bearer token para autenticaçãoexpires_in(number, opcional) - Tempo de expiração em segundos (padrão: 3600)
Comportamento:
- Se
expires_infor fornecido, o servidor usa esse valor - Caso contrário, assume 1 hora (3600 segundos) de validade
- Token é renovado automaticamente 5 minutos antes de expirar
🛠️ Troubleshooting
Erro: "Authentication configuration is incomplete"
Verifique se todas as variáveis estão no .env:
EXTERNAL_API_LOGIN_URLEXTERNAL_API_USEREXTERNAL_API_PASSWORD
Erro: "Failed to authenticate"
- Confirme que a URL de login está correta
- Verifique se email/senha são válidos
- Confirme que a API retorna
tokenouaccess_token
Erro: "EXTERNAL_MCP_URL not configured"
Configure EXTERNAL_MCP_URL no .env com a URL SSE do servidor externo.
Cliente não consegue conectar via OAuth
- Verifique
GITHUB_CLIENT_IDeGITHUB_CLIENT_SECRET - Confirme que a callback URL no GitHub está correta:
http://localhost:3000/auth/callback - Verifique se
JWT_SECRETtem pelo menos 32 caracteres
Token expira muito rápido
- Verifique se a API externa retorna
expires_incorreto - O servidor renova tokens 5 minutos antes de expirar
- Confira os logs para ver quando tokens estão sendo renovados
- Logs de exemplo:
[McpProxyService] Refreshing authentication token... [McpProxyService] Token refreshed successfully. Expires in 3600s [McpProxyService] Using cached token
Erro: "MCP client is not connected"
- O servidor tenta reconectar automaticamente
- Verifique se
EXTERNAL_MCP_URLestá acessível - Confira logs de erro de conexão
- Sistema tentará reconectar na próxima operação
Erro 401/403 do servidor externo
- Sistema detecta automaticamente e força refresh do token
- Se persistir, verifique credenciais
EXTERNAL_API_USEReEXTERNAL_API_PASSWORD - Confirme que a API de login está funcionando corretamente