# MCP 404 Mates — publication depuis Claude / ChatGPT / Cursor

Rédiger et publier des articles sur 404 Mates depuis un assistant IA, **sans fichier local** : le serveur MCP et l’API tournent sur `https://404mates.ai`.

## Prérequis (une fois)

Sur Vercel → Environment Variables :

```
MATES_API_KEY=<openssl rand -hex 32>
NEXT_PUBLIC_SITE_URL=https://404mates.ai
```

Redeploy après ajout. **Ne commite jamais** la clé.

| Endpoint | Usage |
|----------|--------|
| `https://404mates.ai/api/mcp` | Serveur **MCP distant** (Claude, Cursor) |
| `https://404mates.ai/api/v1/mcp` | Alias versionné (même handlers) |
| `https://404mates.ai/.well-known/openapi.json` | Spec **OpenAPI** publique (ChatGPT + découverte) |
| `https://404mates.ai/api/mcp/openapi` | Même spec (alias) |
| `https://404mates.ai/api/mcp/*` | API REST (même auth) |
| `https://404mates.ai/auth.md` | Auth agent (Bearer / x-api-key) |
| `https://404mates.ai/developers` | Portail développeurs |
| `https://404mates.ai/llms.txt` | Instructions agents (when-to-use) |

Découverte machine-readable : voir [`docs/agent-discovery.md`](./agent-discovery.md) (`/.well-known/api-catalog`, MCP Server Card, ARD, skills).

Auth : `Authorization: Bearer <MATES_API_KEY>` (ou header `x-api-key: <MATES_API_KEY>`). **Pas d’OAuth.**

---

## Claude (web + mobile) — ~5 min

1. Ouvre [claude.ai](https://claude.ai) → **Settings → Connectors** (ou Admin → Connectors sur Team/Enterprise).
2. **Add custom connector**.
3. URL du serveur MCP : `https://404mates.ai/api/mcp`
4. **Request headers** (si proposé — beta Anthropic) :
   - Header : `Authorization`
   - Valeur : `Bearer <ta_MATES_API_KEY>` (le mot `Bearer` + espace + la clé)
5. Enregistre, puis dans un chat : **+ → Connectors** → active **404mates**.

L’app **Claude mobile** utilise les mêmes connecteurs que le web.

> Si les *request headers* ne sont pas encore dispo sur ton compte, utilise ChatGPT Actions ou Cursor (ci-dessous) en attendant le rollout Anthropic.

---

## ChatGPT (web + mobile) — ~5 min

1. [ChatGPT](https://chatgpt.com) → **Créer un GPT** (ou éditer un GPT existant).
2. Onglet **Configure → Actions → Create new action**.
3. **Import from URL** : `https://404mates.ai/.well-known/openapi.json`  
   (alias : `/api/mcp/openapi` — un seul `securityScheme` Bearer est supporté par ChatGPT).
4. Authentication :
   - Type : **Clé API** / **API Key**
   - Auth Type : **Bearer**
   - Valeur : coller **uniquement** `MATES_API_KEY` (sans préfixe `Bearer ` — ChatGPT l’ajoute)
5. Instructions du GPT (exemple) :

```
Tu publies sur 404 Mates (rédaction alternative via MCP, sans QC).
1. Appelle getSchema (ou listAuthors + listCategories) avant create/publish.
2. Pour mettre à jour : updateArticle avec un body PARTIEL. Ignore qc_report / qc_stale.
3. Pour publier : publishArticle (sans QC) OU status=published sur create/update. author_slug + category_slug obligatoires.
4. Ne bloque JAMAIS sur qc_report.verdict — le QC n’est pas requis sur ce chemin.
Respecte les limites SEO (title ≤70, description ≤160).
```

Le GPT fonctionne aussi dans l’**app ChatGPT mobile**.

---

## Cursor

Fichier MCP (remote HTTP), pas de chemin local :

```json
{
  "mcpServers": {
    "404mates": {
      "url": "https://404mates.ai/api/mcp",
      "headers": {
        "Authorization": "Bearer VOTRE_CLE"
      }
    }
  }
}
```

---

## Outils disponibles

| Outil / opération | Description |
|-------------------|-------------|
| `get_schema` | Contraintes create/update + catégories + **auteurs** |
| `list_categories` | Catégories éditoriales |
| `list_authors` | Personas (`author_slug`) |
| `list_articles` | Liste (filtre `status`) |
| `get_article` | Article par ID |
| `create_article` | Créer (draft ou publié) |
| `update_article` | Mise à jour **partielle** |
| `publish_article` | Mettre en ligne (+ `author_slug` / `category_slug` optionnels) |

## Contraintes des champs

| Champ | Règle |
|-------|--------|
| `title` | Requis à la création, max 200 car. |
| `slug` | Requis à la création, `[a-z0-9-]+`, max 80 |
| `body_markdown` | Requis à la création — markdown (H2, H3, listes, liens, **images**) |
| `excerpt` | Chapô, max 500 car. |
| `brief_markdown` | Bloc « En bref » |
| `analyse_404mates_markdown` | Lecture 404 Mates (opt-out possible) |
| `seo_title` | Max **70** car. (clamp auto) |
| `seo_description` | Max **160** car., idéal 120–155 |
| `category_slug` | Obligatoire pour **publier** ; optionnel en PATCH (conserve l’existant) |
| `author_slug` | Obligatoire pour **publier** ; optionnel en PATCH (conserve l’existant) — `list_authors` |
| `sources_json` | `[{ "title", "url" }]` sources tierces |
| `status` | `review` (défaut), `drafting`, `published` — **MCP applique le status tel quel** (pas de forçage en review) |

### Images dans le corps

Syntaxe markdown standard :

```markdown
![Légende optionnelle](https://….supabase.co/storage/v1/object/public/article-media/articles/…/….jpg)
```

- **Upload / habillage / Flux** : dans le cockpit admin (coller, glisser-déposer, boutons Image / Habiller / Illustrer).
- Toute image acceptée (screenshot, photo, schéma, PNG/JPG/WebP) — pas seulement les captures.
- Soft limit ≈ 12 images / article ; JPEG optimisé (max ~1400px).
- MCP / ChatGPT : coller une URL déjà hébergée ; pas d’upload multipart via Actions en v1.

**Deux chemins de publication :**

1. **MCP (rédaction alternative)** — create/update avec `status: "published"` : mise en ligne **sans QC**, sans passage forcé en review. Un PATCH partiel sur un article déjà publié **conserve** `published` et **n’invalide pas** le `qc_report`.
2. **Pipeline cockpit** — gate QC **uniquement** dans l’admin si `EDITORIAL_QC_ENABLED=1`. Le chemin MCP (`publish_article` / `status=published`) **n’a jamais** de gate QC.

**Workflow MCP recommandé :**

1. `get_schema` ou `list_authors` — contraintes, catégories, auteurs.
2. `create_article` ou `update_article` avec le contenu + `author_slug` / `category_slug`.
3. Pour publier : `status: "published"` sur create/update (pas besoin de `publish_article`).

---

## API HTTP (sans MCP)

```bash
curl -s -H "Authorization: Bearer $MATES_API_KEY" \
  https://404mates.ai/api/mcp/schema | jq .
```

| Méthode | Route |
|---------|--------|
| GET | `/api/mcp/schema` |
| GET | `/api/mcp/categories` |
| GET | `/api/mcp/authors` |
| GET | `/api/mcp/articles?status=review` |
| POST | `/api/mcp/articles` |
| GET | `/api/mcp/articles/{id}` |
| PATCH | `/api/mcp/articles/{id}` (body partiel) |
| POST | `/api/mcp/articles/{id}/publish` (body optionnel `author_slug`) |
| GET | `/api/mcp/openapi` |

## Sécurité

- Ne commite **jamais** `MATES_API_KEY`.
- Révoque / rotate la clé si exposée.
- L’API contourne le login cockpit mais ne remplace pas Supabase Auth pour l’UI admin.

## Legacy : serveur stdio local

Uniquement si un client ne gère que le stdio (pas d’URL HTTP) :

```bash
cd mcp-server && npm install
# ou pont : npx -y mcp-remote https://404mates.ai/api/mcp --header Authorization:"Bearer $MATES_API_KEY"
```

Ce n’est **pas** nécessaire pour Claude, ChatGPT mobile, ni Cursor en mode remote.
