Skip to content

Atribuir chave na MCP#1

Draft
claudemirmod wants to merge 6 commits intoEvolutionAPI:mainfrom
claudemirmod:claude/goofy-chaum
Draft

Atribuir chave na MCP#1
claudemirmod wants to merge 6 commits intoEvolutionAPI:mainfrom
claudemirmod:claude/goofy-chaum

Conversation

@claudemirmod
Copy link
Copy Markdown

@claudemirmod claudemirmod commented Apr 9, 2026

Summary by Sourcery

Add HTTP/SSE-based MCP server mode with optional API key authentication and update runtime configuration accordingly.

New Features:

  • Introduce an HTTP server using SSE transport for remote MCP access with dedicated /sse and /message endpoints.
  • Add optional API key-based authentication for MCP HTTP routes, configurable via the MCP_API_KEY environment variable.
  • Expose a health check endpoint for the MCP server over HTTP.

Enhancements:

  • Switch CLI and entrypoint to choose between STDIO and HTTP/SSE modes based on environment configuration.
  • Refactor Dockerfile to a multi-stage build that compiles TypeScript in a builder image and installs only production dependencies in the runtime image.

Build:

  • Update Dockerfile to use a two-stage build process and run the compiled server from the dist output.

claudemirmod and others added 4 commits April 9, 2026 08:50
- Adiciona MCP_API_KEY para proteger o servidor via Bearer token ou x-api-key header
- Implementa HTTP server com SSE transport (modo ENABLE_HTTP=true) para Dokploy
- Mantém modo STDIO para uso local com Claude Desktop
- Adiciona endpoint /health sem autenticação para health checks
- Remove WebSocket stub não funcional

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai bot commented Apr 9, 2026

Reviewer's Guide

Replaces the WebSocket MCP server with an HTTP/SSE-based server secured via optional API key, updates CLI entrypoint to choose between HTTP/SSE and STDIO modes, introduces configurable MCP API key in config, and refactors the Dockerfile into a two-stage build/runtime image aligned with the new startup mode.

Sequence diagram for HTTP/SSE MCP server with API key validation

sequenceDiagram
    actor Client
    participant HttpServer
    participant ValidateApiKey
    participant SSEServerTransport
    participant TransportsMap
    participant MCPServer

    Client->>HttpServer: GET /health
    HttpServer-->>Client: 200 { status: ok }

    Client->>HttpServer: GET /sse (with headers)
    HttpServer->>ValidateApiKey: validateApiKey(req, res)
    alt API key invalid or missing
        ValidateApiKey-->>HttpServer: false
        HttpServer-->>Client: 401 { error: Unauthorized }
    else API key valid or not configured
        ValidateApiKey-->>HttpServer: true
        HttpServer->>SSEServerTransport: new SSEServerTransport(/message, res)
        HttpServer->>TransportsMap: set(sessionId, transport)
        SSEServerTransport->>MCPServer: connect(transport)
        MCPServer-->>SSEServerTransport: session established
    end

    Client->>HttpServer: POST /message?sessionId
    HttpServer->>ValidateApiKey: validateApiKey(req, res)
    alt API key invalid
        ValidateApiKey-->>HttpServer: false
        HttpServer-->>Client: 401 { error: Unauthorized }
    else API key valid
        ValidateApiKey-->>HttpServer: true
        HttpServer->>TransportsMap: get(sessionId)
        alt transport not found
            TransportsMap-->>HttpServer: undefined
            HttpServer-->>Client: 400 { error: Sessao nao encontrada }
        else transport found
            TransportsMap-->>HttpServer: transport
            HttpServer->>SSEServerTransport: handlePostMessage(req, res)
            SSEServerTransport->>MCPServer: forward MCP request
            MCPServer-->>SSEServerTransport: MCP response
            SSEServerTransport-->>Client: SSE event with response
        end
    end

    SSEServerTransport-->>TransportsMap: onclose() delete(sessionId)
Loading

File-Level Changes

Change Details Files
Replace WebSocket transport with HTTP server exposing SSE and message endpoints, with optional API key authentication and health check route.
  • Remove WebSocket-based startWebSocketServer implementation and introduce validateApiKey helper for header-based authentication using MCP_API_KEY or no-auth if unset.
  • Implement startHttpServer that manages SSEServerTransport instances keyed by sessionId, exposes /sse for server-sent events, /message for POSTed client messages, and /health as an unauthenticated health check, handling 400/404 error responses appropriately.
  • Change process entrypoint logic to prefer HTTP/SSE mode when ENABLE_HTTP=true and otherwise run the original STDIO startServer, updating startup logging accordingly.
src/index.ts
Update CLI startup to align with new HTTP/SSE vs STDIO modes.
  • Replace ENABLE_WEBSOCKET-based branching with ENABLE_HTTP, computing PORT once and passing it to startHttpServer when HTTP mode is enabled.
  • Ensure CLI runs HTTP/SSE mode for remote URL access (e.g., Dokploy) and defaults to STDIO mode for local Claude Desktop usage, with simplified error logging message.
src/cli.ts
Introduce configurable MCP API key into configuration.
  • Extend MCP config with apiKey property sourced from process.env.MCP_API_KEY and defaulting to empty string, effectively disabling auth when not set.
  • Document that setting MCP_API_KEY enables HTTP authentication for MCP access.
src/config.ts
Refactor Dockerfile into multi-stage build and runtime images compatible with TypeScript build and runtime-only dependencies.
  • Add a builder stage that installs all dependencies, copies TypeScript sources and tsconfig, and runs npm run build to produce dist artifacts.
  • Add a runtime stage that installs only production dependencies via npm install --omit=dev, copies the built dist from the builder stage, sets WORKDIR, exposes port 3000, and keeps the node dist/index.js start command (implicitly via existing configuration or default).
Dockerfile

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • The updated Dockerfile no longer defines a CMD/ENTRYPOINT, so containers built from this image won’t start the MCP server by default; consider adding back something like CMD ["node", "dist/index.js"] (or the appropriate entrypoint for the new HTTP mode).
  • In startHttpServer, the base URL for parsing (new URL(req.url || '/', 'http://localhost')) and the logged SSE endpoint both hardcode localhost, which may be confusing or incorrect when running behind a reverse proxy or in containerized environments; consider deriving the host/port from configuration or the incoming request instead.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The updated Dockerfile no longer defines a CMD/ENTRYPOINT, so containers built from this image won’t start the MCP server by default; consider adding back something like `CMD ["node", "dist/index.js"]` (or the appropriate entrypoint for the new HTTP mode).
- In `startHttpServer`, the base URL for parsing (`new URL(req.url || '/', 'http://localhost')`) and the logged SSE endpoint both hardcode `localhost`, which may be confusing or incorrect when running behind a reverse proxy or in containerized environments; consider deriving the host/port from configuration or the incoming request instead.

## Individual Comments

### Comment 1
<location path="src/index.ts" line_range="762-771" />
<code_context>
+  const httpServer = http.createServer(async (req, res) => {
</code_context>
<issue_to_address>
**issue (bug_risk):** Unhandled errors inside the async HTTP request handler can cause unhandled rejections and inconsistent responses.

Since the `http.createServer` callback is `async`, any thrown error or rejected promise in this handler will surface as an unhandled rejection rather than a proper HTTP response. Consider wrapping the handler body in a `try/catch`, returning a 5xx response and logging the error to avoid hanging requests or abrupt socket closures.
</issue_to_address>

### Comment 2
<location path="Dockerfile" line_range="2-11" />
<code_context>
-FROM node:18-alpine
+# ---- Stage 1: Build ----
+FROM node:18-alpine AS builder

 WORKDIR /app

-# Copiar arquivos de dependências
 COPY package*.json ./
-RUN npm ci --only=production
+RUN npm install
+
+COPY tsconfig.json ./
+COPY src ./src
+RUN npm run build
+
+# ---- Stage 2: Runtime ----
+FROM node:18-alpine

-# Copiar arquivos de código compilado
-COPY dist ./dist
-COPY .env.example ./.env.example
+WORKDIR /app
+
+COPY package*.json ./
+RUN npm install --omit=dev

-# Definir variáveis de ambiente padrão
</code_context>
<issue_to_address>
**suggestion (performance):** The multi-stage Docker build installs dependencies twice and could be optimized for size and speed.

The builder stage runs `npm install`, and the runtime stage runs `npm install --omit=dev`, duplicating the install work. Instead, install production deps once in the builder (e.g., `npm ci --omit=dev`) and copy `node_modules` into the runtime image to skip the second install. In the runtime stage, also set `NODE_ENV=production` so dependencies run in production mode and can apply their own optimizations.

Suggested implementation:

```
COPY package*.json ./
RUN npm ci --omit=dev

```

```
WORKDIR /app

ENV NODE_ENV=production

COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist

```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@claudemirmod
Copy link
Copy Markdown
Author

Revisado

@claudemirmod claudemirmod marked this pull request as draft April 9, 2026 12:32
claudemirmod and others added 2 commits April 9, 2026 10:18
Permite autenticação via URL para clientes que não suportam headers
customizados, como o Claude Desktop.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Adiciona fluxo OAuth 2.0 completo (authorize, token, register)
- Página HTML de autorização solicita a MCP_API_KEY ao usuário
- Suporte a PKCE (S256 e plain)
- CORS habilitado para requisições do Claude.ai
- Adiciona BASE_URL no config para discovery OAuth
- Mantém compatibilidade com Bearer token e x-api-key header

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant