2026-04-13 13:57:31 +02:00
2026-04-13 13:45:38 +02:00
2026-04-13 13:45:38 +02:00
2026-04-13 13:45:38 +02:00

Running OverLeaf_MCP in Docker with Authentik Authentication

Run the OverLeaf_MCP server in Docker, secured with OAuth 2.1 via your existing Authentik instance, using mcp-auth-proxy. Only authenticated Qumo users can access your Overleaf account.

What this sets up

A single Docker container running:

  • OverLeaf_MCP — the MCP server (stdio)
  • mcp-auth-proxy — wraps it with OAuth 2.1 + automatic HTTPS (Let's Encrypt)

mcp-auth-proxy acts as the OAuth 2.1 authorization server toward Claude.ai (handling Dynamic Client Registration, PKCE, token issuance). It delegates user authentication to Authentik via standard OIDC. Authentik never touches the MCP protocol — it only answers "who is this person?".

Claude.ai  ──OAuth 2.1──►  mcp-auth-proxy  ──stdio──►  OverLeaf_MCP
                                │
                          (OIDC client)
                                │
                                ▼
                           Authentik
                         (identity only)

Prerequisites

  • A server with a public IP and ports 80 + 443 open
  • A domain pointed at that IP (e.g. overleaf-mcp.qumo.io)
  • Docker and Docker Compose
  • Your existing Authentik instance (e.g. auth.qumo.io)
  • A free Overleaf account
  • Claude Pro/Team/Enterprise subscription

Step 1: Create the Authentik provider and application

In the Authentik admin UI at https://auth.qumo.io:

Create the provider

  1. Go to Applications → Providers → Create
  2. Select OAuth2/OpenID Provider (not Proxy Provider)
  3. Configure:
    • Name: Overleaf MCP Provider
    • Authentication flow: default
    • Authorization flow: default-provider-authorization-implicit-consent
    • Redirect URI (strict): https://overleaf-mcp.qumo.io/oauth/callback
    • Signing key: select any available key
    • Scopes: make sure email, profile, and openid are included
  4. Click Finish
  5. Copy the Client ID and Client Secret

Create the application

  1. Go to Applications → Applications → Create
  2. Configure:
    • Name: Overleaf MCP
    • Slug: overleaf-mcp
    • Provider: select the provider you just created
  3. Click Create

Find the issuer URL

The OIDC issuer URL for Authentik follows this pattern:

https://auth.qumo.io/application/o/overleaf-mcp/

Where overleaf-mcp is the application slug. You can verify it works by visiting:

https://auth.qumo.io/application/o/overleaf-mcp/.well-known/openid-configuration

This should return a JSON document with authorization_endpoint, token_endpoint, etc.

Step 2: DNS

Create an A record for the MCP server subdomain:

overleaf-mcp.qumo.io  →  A  →  <your-server-ip>

If you're running this on the same VPS as Caddy, see the note at the bottom about using Caddy instead of Let's Encrypt.

Step 3: Configure the project

mkdir ~/apps/overleaf-mcp && cd ~/apps/overleaf-mcp

Place the Dockerfile, docker-compose.yml, and .env.example in this directory, then:

cp .env.example .env
nano .env

Fill in all values:

OVERLEAF_EMAIL=your@email.com
OVERLEAF_PASSWORD=your-overleaf-password
MCP_DOMAIN=overleaf-mcp.qumo.io
AUTHENTIK_ISSUER_URL=https://auth.qumo.io/application/o/overleaf-mcp/
AUTHENTIK_CLIENT_ID=<from step 1>
AUTHENTIK_CLIENT_SECRET=<from step 1>
ALLOWED_USER=you@qumo.io

The ALLOWED_USER field matches against the OIDC claims returned by Authentik. This is typically the email address. You can also use glob patterns like *@qumo.io to allow all users in your Authentik instance with a Qumo email.

Step 4: Build and start

docker compose up -d --build

Check logs:

docker compose logs -f

You should see mcp-auth-proxy provision a Let's Encrypt certificate and start listening on port 443.

Step 5: Connect Claude.ai

  1. Open claude.aiSettingsIntegrations
  2. Add a new MCP integration:
    https://overleaf-mcp.qumo.io/mcp
    
  3. Claude initiates the OAuth flow → you're redirected to Authentik to log in
  4. After authenticating, Claude is connected

Test it:

Call the ping tool

Step 6: First-time Overleaf login

If Overleaf shows a CAPTCHA during headless login:

  1. Install OverLeaf_MCP locally and log in once (outside Docker)
  2. Copy the session data into the Docker volume:
docker volume inspect overleaf-mcp_browser-data
sudo cp -r ~/.overleaf-mcp/browser-data/* \
  /var/lib/docker/volumes/overleaf-mcp_browser-data/_data/
docker compose restart

Running on the same VPS as Caddy

If this runs on the same VPS where Caddy already occupies ports 80/443, you have two options:

Option A: Let mcp-auth-proxy handle its own TLS on different ports

Not ideal — Claude.ai expects standard HTTPS on 443.

Remove the port bindings and Let's Encrypt from the container, and let Caddy handle TLS and proxying:

  1. In docker-compose.yml, remove the ports: section entirely and add the shared network:
services:
  overleaf-mcp:
    # ... everything else stays the same ...
    # Remove ports: section
    networks:
      - qumo_services_proxy_network
    command:
      - --external-url
      - https://${MCP_DOMAIN}
      - --no-tls
      - --port
      - "8080"
      - --oidc-issuer
      - ${AUTHENTIK_ISSUER_URL}
      - --oidc-client-id
      - ${AUTHENTIK_CLIENT_ID}
      - --oidc-client-secret
      - ${AUTHENTIK_CLIENT_SECRET}
      - --allowed-user
      - ${ALLOWED_USER}
      - --
      - node
      - /app/dist/index.js

networks:
  qumo_services_proxy_network:
    external: true
  1. Add to your Caddyfile (no import authentik — mcp-auth-proxy handles auth):
overleaf-mcp.qumo.io {
    reverse_proxy overleaf-mcp:8080
}
  1. Reload Caddy:
cd ~/networking/caddy
docker compose exec caddy caddy reload --config /etc/caddy/Caddyfile

Note: Check whether mcp-auth-proxy supports --no-tls and --port flags. If not, you can bind it to a high port with TLS disabled by using --tls-cert-file and --tls-key-file with self-signed certs, and let Caddy terminate real TLS in front. Consult the mcp-auth-proxy docs for current flags.

Fallback: password-only auth

If the OIDC flow doesn't work cleanly with Claude.ai's Dynamic Client Registration, you can fall back to password auth (confirmed working with Claude.ai):

    command:
      - --external-url
      - https://${MCP_DOMAIN}
      - --tls-accept-tos
      - --password
      - ${MCP_PASSWORD}
      - --
      - node
      - /app/dist/index.js

Add MCP_PASSWORD=a-strong-random-password to .env. Claude.ai will prompt for this password when connecting.

Useful commands

# Logs
docker compose logs -f

# Restart
docker compose restart

# Full rebuild
docker compose down && docker compose build --no-cache && docker compose up -d

# Shell into the container
docker compose exec overleaf-mcp bash

# Extract PDFs
docker compose cp overleaf-mcp:/data/resumes/. ./my-resumes/

Troubleshooting

Let's Encrypt certificate fails — Ports 80 and 443 must be open and DNS must resolve. If Caddy already holds these ports, use the "behind Caddy" setup above.

OAuth callback error — Verify the redirect URI in Authentik matches exactly: https://overleaf-mcp.qumo.io/oauth/callback

"User not allowed" — Check that ALLOWED_USER matches what Authentik returns in its OIDC claims. Try *@qumo.io as a glob pattern, or check the claims by decoding the JWT token.

"Browser closed unexpectedly" — The compose file sets shm_size: "2gb" for Chromium. Make sure it's there.

Overleaf login times out — CAPTCHA issue. Use the session-copying approach from Step 6.

Claude.ai can't connect — Visit https://overleaf-mcp.qumo.io/.well-known/oauth-authorization-server in your browser. You should see a JSON metadata document. If not, the container isn't running or TLS isn't working.

Description
No description provided
Readme 36 KiB
Languages
Dockerfile 100%