- mcp/http.js: MCP por HTTP (sin estado). Cada petición lleva la contraseña de aplicación del propio usuario (Basic o Bearer); se valida contra WordPress (caché 5 min), exige permiso de edición y no se guarda. Límite por IP, /healthz, IP real reenviada a WordPress. - Herramientas comunes en mcp/src/tools.js (local y remoto); en remoto las fotos van por URL o base64 (sin acceso a archivos del servidor). - Dockerfile del MCP y servicio «mcp» en docker-compose.yml. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
98 lines
3.8 KiB
Markdown
98 lines
3.8 KiB
Markdown
# Bilagun MCP server
|
|
|
|
Lets an AI assistant (Claude Desktop, Claude Code…) manage the Bilagun website in plain language,
|
|
through the website's REST API. Examples:
|
|
|
|
- "Crea la ficha de Kira, perra de unos 2 años, tamaño mediano, muy cariñosa. Déjala en borrador."
|
|
- "Marca a Txuri como adoptada."
|
|
- "Sube esta foto como principal de Hartz."
|
|
- "Añade 'arena para gatos' a lo que necesitamos, en castellano y en euskera."
|
|
|
|
## Tools
|
|
|
|
| Tool | What it does |
|
|
|---|---|
|
|
| `list_animals` | List animals (filter by language, status, species, text) |
|
|
| `get_animal` | Full record: story, profile, translation |
|
|
| `create_animal` | New animal (draft by default). With `language: "eu"` + `translationOf` it creates the Basque version and links it |
|
|
| `update_animal` | Change name, story, texts or profile fields |
|
|
| `set_status` | available / pending / adopted (both languages) |
|
|
| `upload_photo` | Upload a JPG/PNG/WebP (local file or URL) as main photo or to the gallery |
|
|
| `get_needs` / `set_needs` | Material needs list shown on the website (es / eu) |
|
|
|
|
It can't read the contact messages, delete content or change settings: that stays in the dashboard.
|
|
|
|
## Two ways to run it
|
|
|
|
| | Remote (recommended) | Local |
|
|
|---|---|---|
|
|
| Where it runs | On the server, next to WordPress (service `mcp` in `docker-compose.yml`) | On each person's computer |
|
|
| What each person needs | A URL and their own application password | Node 20+, this folder, `npm install` |
|
|
| Photos | By URL or dragged into the chat (base64) | Also local file paths |
|
|
|
|
In both cases every person uses **their own WordPress user and application password**. The remote
|
|
server stores no credentials: it checks them against WordPress on each request and forwards them,
|
|
so each person acts with their own permissions and access can be revoked from the dashboard.
|
|
|
|
## 1. Create the access (per person)
|
|
|
|
1. In WordPress create a user for the person (role **Editor** is enough).
|
|
2. *Users → Profile → Application passwords* → name it "Asistente" → **Add**. Copy it (shown only once).
|
|
3. Build the credential: base64 of `user:application-password`:
|
|
|
|
```bash
|
|
printf 'asistente:xxxx xxxx xxxx xxxx xxxx xxxx' | base64
|
|
```
|
|
|
|
## 2a. Remote server (Dokploy)
|
|
|
|
After deploying, in Dokploy add a **domain** to the service `mcp`, port **3000** (e.g. `mcp.gureametsabilagun.pireon.dev`, HTTPS on).
|
|
Check it: `https://mcp.gureametsabilagun.pireon.dev/healthz` → `{"ok":true}`.
|
|
|
|
**Claude Code**
|
|
|
|
```bash
|
|
claude mcp add --transport http bilagun https://mcp.gureametsabilagun.pireon.dev/mcp \
|
|
--header "Authorization: Basic <base64 from step 1>"
|
|
```
|
|
|
|
**Other clients** (Cursor, VS Code, Claude Desktop via `mcp-remote`…): use the same URL and header.
|
|
Clients that only allow a *Bearer token* can use `Authorization: Bearer <same base64>`.
|
|
|
|
> claude.ai web/mobile "custom connectors" require OAuth login, which this server does not implement yet.
|
|
|
|
Server settings (environment): `BILAGUN_URL` (internal WordPress URL, default `http://wordpress`),
|
|
`BILAGUN_PUBLIC_URL`, `RATE_LIMIT` (requests per minute and IP, default 120).
|
|
It exposes `POST /mcp` (Streamable HTTP, stateless) and `GET /healthz`.
|
|
|
|
## 2b. Local server (stdio)
|
|
|
|
```bash
|
|
cd mcp && npm install
|
|
claude mcp add bilagun \
|
|
--env BILAGUN_URL=https://gureametsabilagun.pireon.dev \
|
|
--env BILAGUN_USER=asistente \
|
|
--env "BILAGUN_APP_PASSWORD=xxxx xxxx xxxx xxxx xxxx xxxx" \
|
|
-- node /absolute/path/to/mcp/index.js
|
|
```
|
|
|
|
Claude Desktop (`claude_desktop_config.json`):
|
|
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"bilagun": {
|
|
"command": "node",
|
|
"args": ["/absolute/path/to/mcp/index.js"],
|
|
"env": {
|
|
"BILAGUN_URL": "https://gureametsabilagun.pireon.dev",
|
|
"BILAGUN_USER": "asistente",
|
|
"BILAGUN_APP_PASSWORD": "xxxx xxxx xxxx xxxx xxxx xxxx"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
Application passwords only work over HTTPS (the production site already is).
|