SEODesk MCP Server
by apurv00001
README.md
# SEODesk MCP Server
A **Remote MCP (Model Context Protocol)** server that exposes the SEODesk SEO
toolset to ChatGPT Apps and any other MCP-compatible client (Claude, Cursor,
Codex, etc.).
- Transport: **Streamable HTTP** (spec 2025-06-18) at `POST /mcp`
- Auth: **OAuth 2.1** with PKCE + Dynamic Client Registration (RFC 7591)
- SDK: `@modelcontextprotocol/sdk`
- Runtime: Node.js 20+
The Lovable frontend is untouched. ChatGPT talks to this MCP server; the
frontend keeps talking to the existing Supabase Edge Functions. This server
calls the same Edge Functions internally to fulfil tool calls.
## Tools exposed
| Tool | Purpose |
| --- | --- |
| `analyze_website` | Full on-page SEO analysis for a URL |
| `seo_audit` | Technical site audit (findings by category) |
| `page_speed_analysis` | Google PageSpeed Insights (mobile + desktop) |
| `keyword_research` | Keywords, questions, clusters from a seed |
| `generate_meta_title` | AI-generated SEO `<title>` variants |
| `generate_meta_description` | AI-generated meta descriptions |
| `generate_schema_markup` | JSON-LD schema (Article, Product, FAQPage, …) |
| `backlink_overview` | Backlink profile summary (requires provider key) |
| `content_optimizer` | Content brief vs. a target keyword |
## Endpoints
| Path | Description |
| --- | --- |
| `POST /mcp` | MCP Streamable HTTP endpoint (requires `Authorization: Bearer <token>`) |
| `GET /health` | Liveness probe |
| `GET /ready` | Readiness probe |
| `GET /.well-known/oauth-authorization-server` | OAuth 2.0 AS metadata (RFC 8414) |
| `GET /.well-known/oauth-protected-resource` | MCP resource metadata (RFC 9728) |
| `POST /oauth/register` | Dynamic Client Registration (RFC 7591) |
| `GET /oauth/authorize` | Authorization endpoint (PKCE S256 required) |
| `POST /oauth/token` | Token endpoint (auth code + refresh) |
## Local development
```bash
cd mcp-server
cp .env.example .env # fill in values
npm install
npm run dev
```
Sanity check:
```bash
curl http://localhost:3333/health
curl http://localhost:3333/.well-known/oauth-authorization-server
```
## Environment variables
See `.env.example`. Required at minimum:
- `PUBLIC_BASE_URL` — public HTTPS URL of this server (used as OAuth issuer).
- `JWT_SECRET` — long random string, signs access tokens.
- `SUPABASE_URL`, `SUPABASE_ANON_KEY`, `SUPABASE_SERVICE_ROLE_KEY` — to call
SEODesk backend Edge Functions.
- `LOVABLE_API_KEY` — for AI-powered tools (meta/schema/optimizer).
- `GOOGLE_PAGESPEED_API_KEY` — optional (Edge Function can supply its own).
## Deploy to Railway
1. Push this folder to a Git repo.
2. In Railway → **New Project → Deploy from GitHub**, pick the repo and set the
root directory to `mcp-server`.
3. Add the env vars from `.env.example` under **Variables**.
4. Railway auto-detects Node; `railway.toml` sets the healthcheck to `/health`.
5. After deploy, set `PUBLIC_BASE_URL` and `OAUTH_ISSUER` to the generated
HTTPS domain (e.g. `https://seodesk-mcp.up.railway.app`) and redeploy.
## Deploy to Cloudflare Workers
The MCP SDK targets Node's `http` module, so the simplest CF path is to deploy
this Node app to **Cloudflare Containers** (or Fly.io / Render) rather than a
plain Worker. If you want a pure Workers deployment, port the two files
`src/index.js` and `src/oauth.js` onto `itty-router` + `@modelcontextprotocol/sdk`'s
Web-Standard transport — the tool definitions in `src/tools.js` transfer
unchanged.
Minimal Docker deploy (works on Fly.io, Render, CF Containers):
```bash
docker build -t seodesk-mcp .
docker run -p 3333:3333 --env-file .env seodesk-mcp
```
## Connect from ChatGPT
1. ChatGPT → **Settings → Apps → Create App** (or **Connectors**).
2. Server URL: `https://<your-domain>/mcp`
3. ChatGPT auto-discovers `/.well-known/oauth-protected-resource`, registers
a client via `/oauth/register`, and walks the user through OAuth.
4. Once approved, all nine tools appear in ChatGPT and can be invoked in chat.
## Connect from Claude / Cursor / Codex
Any MCP client that supports Streamable HTTP + OAuth 2.1 works. Point it at
`https://<your-domain>/mcp` and it will complete DCR + PKCE the same way.
## Production hardening checklist
- [ ] Replace in-memory `clients` / `authCodes` / `refreshTokens` stores in
`src/oauth.js` with Redis or Postgres.
- [ ] Replace the auto-approve `/oauth/authorize` handler with a real consent
page that authenticates the end user against SEODesk (Supabase Auth).
- [ ] Rotate `JWT_SECRET` and pin `ALLOWED_REDIRECT_HOSTS`.
- [ ] Put the server behind HTTPS (Railway / Fly / CF terminate TLS for you).
- [ ] Add rate limiting (e.g. `express-rate-limit`) on `/mcp` and `/oauth/*`.
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues