You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: AGENT.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -27,11 +27,11 @@ Developer reference for agents and contributors. User-facing overview: [README.m
27
27
-**Pipeline storage** (crawl, edges, nodes, report payload, Lighthouse, keywords, warnings) lives in **PostgreSQL only**. Deliverables use the Export view, `GET /api/report/export`, or MCP `export_*` tools — not files written by the main pipeline step.
28
28
-**Pool tuning:**`DB_POOL_MIN` / `DB_POOL_MAX` (Python), `PGPOOL_MAX` (Node). Bulk crawl writes via `executemany`; optional **`crawl_stream_to_db`** streams rows during fetch. Per-URL raw HTML: `crawl_page_html` table (migration `015`); API `GET/POST /api/crawl/page-html` (localhost).
29
29
-**`web/` APIs:**`/api/report/*` read routes (payload, meta, history — not localhost-guarded; protect with `AUTH_*` when exposed); `/api/run` spawns Python (localhost); `/api/jobs`, `/api/jobs/[id]`, `/api/jobs/[id]/cancel` (localhost); `/api/crawl/browser-status`, `/api/crawl/page-html` (localhost); `/api/pipeline-config` GET/PUT; `/api/llm-config` GET/PUT; `/api/chat` POST (SSE); `/api/chat/sessions` GET/POST; `/api/ollama/status` (localhost); `/api/properties/{id}/google/links/import` POST; `PipelineRunnerFab` saves pipeline + LLM state before each run. Full route list: `web/app/api/**/route.ts`.
30
-
-**MCP:**`python -m website_profiling.mcp` (stdio, **340 read-only audit tools**, domain-scoped via `WP_MCP_DOMAIN`). See `docs/MCP.md`. Requires `pip install -r requirements.txt`.
30
+
-**MCP:**`python -m website_profiling.mcp` (stdio) or `python -m website_profiling.mcp.http` (remote Streamable HTTP). Configure at **`/mcp`** in the web UI. See `docs/MCP.md`.
-**Job store:** PostgreSQL `pipeline_jobs` when `DATABASE_URL` is set (`pipelineJobsDb.ts` — status, timestamps, truncated logs). In-memory map in `pipelineJobs.ts` holds live log tail and child process handles; stale rows reconciled via `PIPELINE_JOB_STALE_HOURS`.
Copy file name to clipboardExpand all lines: README.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -93,7 +93,7 @@ Site Audit focuses on **honest, self-hosted technical SEO**. It is not a drop-in
93
93
</tr>
94
94
</table>
95
95
96
-
Also included: **AI chat** over audit data (optional), **Content studio** (write & optimize with live SEO scoring), **340 MCP tools** (domain-scoped servers), image SEO, GEO/AEO readiness, keyword explorer (GSC + on-site), backlinks (GSC Links import), compare runs, and portfolio management for agencies.
96
+
Also included: **AI chat** over audit data (optional), **Content studio** (write & optimize with live SEO scoring), **340 MCP tools** (local stdio or remote Streamable HTTP), image SEO, GEO/AEO readiness, keyword explorer (GSC + on-site), backlinks (GSC Links import), compare runs, and portfolio management for agencies.
97
97
98
98
<imgsrc="docs/assets/social-preview.png"alt="Site Audit — developer-friendly SEO audit preview"width="100%">
99
99
@@ -109,7 +109,7 @@ WebsiteProfiling/
109
109
│ ├── integrations/ # Google Search Console, GA4, Bing, CrUX
For remote access over HTTP, see [Remote Streamable HTTP](#remote-streamable-http).
42
+
40
43
---
41
44
42
45
## Domain-scoped servers
@@ -111,6 +114,80 @@ Add to `.cursor/mcp.json` or your MCP client settings:
111
114
112
115
---
113
116
117
+
## Remote Streamable HTTP
118
+
119
+
Use this when Site Audit runs on a hosted server and your MCP client (Cursor, Claude Desktop, etc.) connects over the network instead of spawning a local stdio subprocess.
120
+
121
+
### Start the HTTP server
122
+
123
+
Configure access on **MCP settings** (`/mcp`) in the web UI (recommended), or set environment variables. UI changes apply on the next MCP request without restarting the service.
Set **MCP bearer token** and **Allowed hostnames** on the Secrets page (or via `WP_MCP_TOKEN` / `WP_MCP_ALLOWED_HOSTS`). Environment variables override saved values when set.
137
+
138
+
The MCP endpoint is `http://<host>:8000/mcp` by default (`WP_MCP_HTTP_PATH=/mcp`).
139
+
140
+
### Environment variables
141
+
142
+
| Variable | Default | Purpose |
143
+
|----------|---------|---------|
144
+
|`WP_MCP_HTTP_HOST`|`127.0.0.1`| Bind address (`0.0.0.0` for Docker) |
145
+
|`WP_MCP_HTTP_PORT`|`8000`| Listen port |
146
+
|`WP_MCP_HTTP_PATH`|`/mcp`| Mount path |
147
+
|`WP_MCP_TOKEN`| unset | Bearer token (**required** when not binding localhost). Save on **Secrets → Remote MCP** or set here (env wins). |
148
+
|`WP_MCP_ALLOWED_HOSTS`| unset | Comma-separated `Host` allowlist (**required** for non-localhost bind). Save on **Secrets → Remote MCP** or set here. |
149
+
|`WP_MCP_ALLOWED_ORIGINS`| unset | Comma-separated `Origin` allowlist for browser clients |
150
+
|`WP_MCP_JSON_RESPONSE`|`false`| JSON responses instead of SSE streams |
151
+
|`WP_MCP_DOMAIN`|`core`| Tool bundle (same as stdio) |
152
+
|`WP_PROPERTY_ID`| unset | Default property (same as stdio) |
153
+
154
+
**Security:**`WP_MCP_TOKEN` is required when `WP_MCP_HTTP_HOST` is not localhost. Tools are read-only but expose audit, GSC, and GA4 data — treat the token like a database credential.
155
+
156
+
**DNS rebinding protection:** Whenever a token **and** allowed hosts are configured — via the UI **or** environment variables — the HTTP service enforces the bearer token plus the Host/Origin allowlist in its own middleware, and the MCP SDK's built-in DNS-rebinding check is turned off (the middleware supersedes it). The SDK check only applies as a fallback on a non-localhost bind that has no remote access configured (a state the startup validation otherwise refuses to boot in). Either way, set `WP_MCP_ALLOWED_HOSTS` to the public hostname clients use (e.g. `audit.example.com`).
157
+
158
+
### Cursor / Claude Desktop (remote)
159
+
160
+
```json
161
+
{
162
+
"mcpServers": {
163
+
"site-audit-remote": {
164
+
"url": "https://audit.example.com/mcp",
165
+
"headers": {
166
+
"Authorization": "Bearer your-long-random-token"
167
+
}
168
+
}
169
+
}
170
+
}
171
+
```
172
+
173
+
### Docker (production)
174
+
175
+
The `mcp` service in `docker-compose.prod.yml` includes an `mcp` service. Set `WP_MCP_TOKEN` and `WP_MCP_ALLOWED_HOSTS` in the environment **or** configure them on **Secrets → Remote MCP** after deploy.
176
+
177
+
Terminate TLS at your reverse proxy and route `/mcp` to the MCP container. Recommended proxy settings: `proxy_buffering off`, long `proxy_read_timeout`.
178
+
179
+
### Troubleshooting
180
+
181
+
| Symptom | Likely cause |
182
+
|---------|----------------|
183
+
| Server refuses to start | Missing token or allowed hosts on non-localhost bind (Secrets page or env) |
Production also requires `AUTH_SECRET` and optionally `AUTH_USER` / `AUTH_PASSWORD` (see `docker-compose.prod.yml`).
119
119
120
+
### Remote MCP (Streamable HTTP)
121
+
122
+
The `mcp` service in `docker-compose.prod.yml` exposes read-only audit tools over HTTP at `/mcp`. Configure on **Secrets → Remote MCP** (`/secrets`) or via environment variables (env overrides saved values):
123
+
124
+
| Variable | Purpose |
125
+
|----------|---------|
126
+
|`WP_MCP_TOKEN`| Bearer token for MCP clients (`Authorization: Bearer …`) |
127
+
|`WP_MCP_ALLOWED_HOSTS`| Public hostname allowlist (e.g. `audit.example.com`) |
|`WP_MCP_DOMAIN`| Tool bundle (`core` recommended for remote) |
130
+
|`MCP_PORT`| Host port mapped to container `8000` (default `8000`) |
131
+
132
+
Terminate TLS at your reverse proxy; do not expose plain HTTP publicly. Configure token and allowed hostnames on **Secrets → Remote MCP** (`/secrets`, Remote MCP section).
133
+
120
134
### Read-only client dashboards
121
135
122
136
Set `AUTH_DEFAULT_ROLE=client-readonly` so session logins cannot run audits or save settings. The API returns 403 on mutations; the UI hides **Run audit** and disables save controls. Use `viewer` instead if chat access should also be blocked.
0 commit comments