Skip to main content
Glama
jamersoncalixto

ghl-mcp-remote

ghl-mcp-remote

Remote MCP (Model Context Protocol) server for GoHighLevel — multi-tenant, accessible via URL, to be used from Claude or ChatGPT by any agency, without each one needing to run anything locally.

This is a separate project from the original ghl-mcp (stdio, personal/local use). Neither one depends on the other.

Difference from the original ghl-mcp

ghl-mcp (original)

ghl-mcp-remote (this one)

Transport

stdio (local process)

HTTP (POST /mcp), hostable

Tenants

1 agency per installation, credentials in ~/.ghl-mcp/credentials.json

Any number of agencies, isolated by companyId, credentials in Postgres

"Login"

npm run auth in the terminal

GHL's own authorization screen, triggered by Claude/ChatGPT

Use

You, locally

Any company, from Claude.ai/ChatGPT, via URL

The business code (the tools in src/tools/) is practically identical in both — only the authentication/storage layer changes.

Related MCP server: GoHighLevel MCP Server

Architecture

Claude/ChatGPT ──(1) descobre──> GET /.well-known/oauth-authorization-server
               ──(2) registra───> POST /register                      (DCR, automático)
               ──(3) pede login─> GET /authorize ──redirect──> tela da GHL (o "login")
                                                        <──redirect── GET /oauth/ghl/callback
               <──code+state───── (nosso próprio código de autorização)
               ──(4) troca──────> POST /token ──> access_token + refresh_token nossos
               ──(5) chama tool─> POST /mcp  (Authorization: Bearer <access_token>)
  • "Login" = authorize GHL. This service has no account/password of its own. When an agency admin approves access on GHL's own screen, that already creates/updates their tenant (identified by GHL's companyId) and completes the login on the MCP side.

  • A single GHL Marketplace app (same GHL_CLIENT_ID/GHL_CLIENT_SECRET) serves any agency that installs it — there's no need to create an app per client.

  • Each tool call arrives authenticated with a Bearer token issued by this server; the middleware resolves that token to the correct companyId and injects it into an AsyncLocalStorage (src/tenant-context.ts) — that's how the tools code (identical to the original project's) remains "unaware" of multi-tenancy.

  • Built on top of what @modelcontextprotocol/sdk itself already provides for OAuth servers (server/auth/router.ts, provider.ts) — see src/auth/mcp-oauth-provider.ts.

Prerequisites to run anywhere

  1. OAuth app in GHL Marketplace (Developer > your app), "Agency" or "Agency & Sub-Account" distribution:

    • Registered redirect URI: <PUBLIC_URL>/oauth/ghl/callback (must be the final public URL of this service — HTTPS).

    • Scopes: the same ones listed in src/services/scopes.ts.

  2. Postgres (any one — Supabase, Neon, RDS, the hosting platform's own managed Postgres, etc.). Run db/schema.sql on it once.

  3. Node.js 20+ (or this project's Docker image, which already includes it).

Environment variables

See .env.example. Summary:

Variable

Description

GHL_CLIENT_ID / GHL_CLIENT_SECRET

From the GHL Marketplace OAuth app

PUBLIC_URL

Final public URL of this service, no trailing slash

PORT

Port the process listens on (many platforms override it themselves)

DATABASE_URL

Postgres connection string

TOKEN_ENCRYPTION_KEY

32 bytes in base64 — openssl rand -base64 32

Run locally (dev)

npm install
npm run build
npm start

Checks possible without any public domain:

curl localhost:8080/healthz
curl localhost:8080/.well-known/oauth-authorization-server

The full OAuth flow (actually authorizing in GHL, getting a token, calling a tool) only works with a real PUBLIC_URL (HTTPS) up, because GHL needs to be able to redirect the agency admin's browser back here — and that same URL needs to be registered as a redirect URI in the GHL app.

Deploy

This project doesn't assume any specific hosting platform — it just includes a generic Dockerfile. Any platform that runs a Docker image (or node dist/index.js directly) works, as long as:

  1. It exposes a stable public HTTPS URL → that becomes PUBLIC_URL.

  2. It injects the environment variables from the table above.

  3. The Postgres pointed to by DATABASE_URL has already run db/schema.sql.

  4. The GHL Marketplace app's redirect URI is updated to <PUBLIC_URL>/oauth/ghl/callback as soon as the final URL is known.

Connect in Claude / ChatGPT

Once hosted:

  • Claude.ai / Claude Desktop: Settings → Connectors → Add custom connector → URL: https://<seu-dominio>/mcp. Claude will take you through the authorization flow automatically.

  • ChatGPT: in workspaces with support for remote Connectors/MCP (varies by plan — Team, Enterprise, or "Developer mode"), add a connector pointing to https://<seu-dominio>/mcp.

Caveat about ChatGPT: support for remote MCP connectors with OAuth in ChatGPT varies by plan/workspace, and some surfaces (e.g. Deep Research) restrict which tool formats they accept (sometimes only tools in the "search"/"fetch" format). This server follows the MCP authorization spec to the letter (the same one Claude uses), which maximizes compatibility — but it's worth actually testing once it's hosted, since behavior on the ChatGPT side is beyond our control.

Structure

src/
  index.ts                 App Express: monta o router de OAuth, POST/GET/DELETE /mcp,
                            GET /oauth/ghl/callback, GET /healthz, CORS.
  server.ts                 createMcpServer() — registra as tools (idêntico ao projeto original).
  tenant-context.ts          AsyncLocalStorage que carrega o companyId durante cada request.
  db/
    pool.ts                  Pool do `pg` a partir de DATABASE_URL.
    crypto.ts                 AES-256-GCM (tokens da GHL em repouso) + SHA-256 (hash dos nossos tokens).
    agencies.ts                Tokens de agência da GHL por companyId (substitui o antigo token-store.ts).
    oauth-store.ts              Clients MCP, pending auth, authorization codes, access/refresh tokens.
  auth/
    ghl-oauth.ts               Troca/refresh de tokens com a GHL — equivalente ao oauth-flow.ts original,
                               mas web-based e por tenant em vez de CLI + arquivo único.
    location-tokens.ts          Cache de location tokens, agora chaveado por companyId.
    mcp-oauth-provider.ts        Implementa OAuthServerProvider do SDK — o núcleo do "login = autorizar a GHL".
    ghl-callback.ts               Handler de GET /oauth/ghl/callback.
  services/
    constants.ts, scopes.ts, ghl-client.ts   Idênticos ao projeto original (só o import de token mudou).
  tools/
    *.ts                       Idênticos ao projeto original, exceto locations.ts (cache agora por tenant).
db/
  schema.sql                  DDL do Postgres — rodar uma vez antes do primeiro start.

Security

  • GHL refresh tokens: encrypted at rest (AES-256-GCM).

  • Access/refresh tokens that this server issues to Claude/ChatGPT: stored only as SHA-256 hashes — never in plain text, like passwords.

  • PKCE (S256) required throughout the MCP-side flow, validated locally (not delegated to GHL).

  • No agency's credentials are accessible from another agency's token — all Postgres access is filtered by companyId, and that value only comes into play after the Bearer token is validated.

F
license - not found
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    MCP server for GoHighLevel API v2 that provides 50+ tools for CRM, billing, marketing, and operations workflows, enabling natural language interaction with contacts, opportunities, conversations, and more.
    50
    1
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    MCP server for GoHighLevel sub-accounts, enabling management of CRM contacts, pipelines, calendars, invoices, and more via natural language.

View all related MCP servers

Related MCP Connectors

  • Hosted Amazon Seller Central and Amazon Ads MCP server for Claude, ChatGPT, Cursor, and agents.

  • Hosted Amazon Seller and Vendor MCP server for Claude, ChatGPT, Cursor, Codex, Gemini, Copilot.

  • MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jamersoncalixto/ghl-mcp-remote'

If you have feedback or need assistance with the MCP directory API, please join our Discord server