# Guide de l'API de l'oracle des métiers — à l'intention d'une IA

L'API REST donne les mêmes données que le MCP, sans passer par une IA : pour
écrire du code, extraire un jeu de données ou bâtir une application.

- Base : `https://joboracle.cloud/api/v1`
- Documentation interactive : `https://joboracle.cloud/docs` ; OpenAPI : `https://joboracle.cloud/api/v1/openapi.json`
- MCP distant (mêmes outils) : `POST https://joboracle.cloud/mcp`
- Public, en lecture seule, sans clé.

## Statut : un prototype

L'oracle n'est **pas une source officielle**. Ses données « etabli » viennent de
sources gouvernementales (Québec.ca, CNP 2021, SIPeC 2025, SCT, DRHC, programmes
d'études, normes professionnelles, carnets d'apprentissage). Ses liens
« propose » (jugement d'un LLM) et « calcule » (mesure), ses fiches de
connaissances et ses situations de travail rédigées n'ont été confirmés par
aucune autorité. **Un programme qui republie ces données doit garder
l'avertissement et le statut des liens.** Chaque réponse les fournit, et chaque
réponse HTTP porte l'en-tête `X-Oracle-Statut: prototype`.

**Contact.** Pour toute information sur ce projet (le signaler, corriger une erreur, proposer une collaboration), s'adresser au Centre de formation professionnelle Val-d'Or.

## Enveloppe

Toute réponse JSON a la même forme :

```json
{
  "avertissement": "Prototype. …",
  "version": {"modele": "1.3.0", "gabarit": "2.1.0", "construction": "…", "paquet": "…", "sha256_base": "…"},
  "donnees": { … }
}
```

`donnees` est exactement ce que renvoie l'outil MCP du même nom. Une erreur
(identifiant inconnu…) donne un code 404 et `donnees.erreur`. Une requête SQL
refusée donne un code 400.

## Routes

Les identifiants contiennent `:` `/` `#` : passe-les **en paramètres de
requête, encodés** (`?id=cours%3A400916%2Fe4`). Les listes se passent séparées
par des virgules.

| Route | Paramètres | Outil MCP |
|---|---|---|
| `GET /metiers` | — | `lister_metiers` : point de départ |
| `GET /metiers/fiche` | `noeud`, `parties` (ex. `taches,formation`) | `fiche_metier` |
| `GET /recherche` | `texte`, `table`, `limite` (≤ 100) | `rechercher` |
| `GET /entite` | `id` | `entite` |
| `GET /competence` | `id` (`cours:…`, code ministériel, `norme:…/cN`, `carnet:…`) | `competence` |
| `GET /comparaison/metiers` | `a`, `b` | `comparer_metiers` |
| `GET /tronc-commun` | `noeuds` (2 ou plus), `seuil` (1–5) | `tronc_commun` |
| `GET /comparaison/programmes` | `a`, `b` (ex. `5370`) | `comparer_programmes` |
| `GET /carrefour` | `id` | `carrefour` |
| `GET /couverture` | `noeud`, `programme` (sans paramètre : les paires analysées) | `couverture` |
| `GET /ecarts` | `noeud` | `ecarts` |
| `GET /document` | `id` (`kb:63201.00` ou `kb:63201.00#sst`), `sections` | `document` |
| `GET /sections` | `cle`, `noeuds` (sans `cle` : les clés) | `section` |
| `GET /sources` | `id` | `sources` : adresse officielle de chaque source |
| `GET /contexte-pedagogique` | `noeuds` (virgules), `competence` | `contexte_pedagogique` : décor, outils, risques, situations réelles, compétence visée |
| `GET /scenarios` | `nom` et les arguments du scénario (sans `nom` : la liste) | `scenario` |
| `GET /sql` | `q` : une requête SELECT ou WITH (200 lignes, 2 s) | `sql` |
| `GET /schema` | — | schéma commenté (texte) |
| `GET /version` | — | version des données, manifeste et sommes SHA-256 |
| `GET /sante` | — | état du service |
| `GET /statistiques` | — | requêtes par jour et par route (sans IP) |

## Limites

Par adresse et par minute : 60 requêtes ; 10 pour `/sql`, `/tronc-commun`,
`/comparaison/metiers` et `/metiers/fiche` ; 120 pour `/mcp`. Au-delà : code
429 et en-tête `Retry-After: 60`. Attends puis reprends : ne martèle pas.
Pour un gros extrait, préfère les téléchargements de `https://joboracle.cloud/donnees`
(base complète et exports) à des milliers d'appels.

Les réponses `GET` réussies sont cachables une heure. La version des données
change seulement à une nouvelle publication : compare `version.sha256_base`
pour savoir si un extrait est à jour.

## Exemples

```sh
curl -s "https://joboracle.cloud/api/v1/metiers" | jq '.donnees.metiers[] | {id, titre}'
curl -s -G "https://joboracle.cloud/api/v1/carrefour" --data-urlencode "id=sct:F.04.c.01"
curl -s -G "https://joboracle.cloud/api/v1/sql" --data-urlencode "q=SELECT relation, statut, COUNT(*) n FROM lien GROUP BY 1, 2"
```

```python
import json, urllib.parse, urllib.request

BASE = "https://joboracle.cloud/api/v1"

def oracle(route, **params):
    url = f"{BASE}/{route}?{urllib.parse.urlencode(params)}"
    with urllib.request.urlopen(url) as r:
        reponse = json.load(r)
    return reponse["donnees"], reponse["avertissement"], reponse["version"]

jonctions, avertissement, version = oracle("comparaison/metiers", a="qc:63202.021", b="sipec:63201.00")
for fil in jonctions["descripteurs_sct_eleves_communs"]["lignes"][:5]:
    print(fil["sct"], fil["nom"], fil["niveaux"])
```

MCP distant, en JSON-RPC :

```sh
curl -s https://joboracle.cloud/mcp -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"carrefour","arguments":{"id":"cours:400916"}}}'
```

Dans Claude Code : `claude mcp add --transport http oracle-metiers https://joboracle.cloud/mcp`.

Le serveur parle les deux époques du protocole MCP : la poignée de main `initialize`
(versions 2024-11-05 à 2025-11-25) et le mode sans état de la version 2026-07-28
(`server/discover`, version portée dans le `_meta` de chaque requête). Pour ChatGPT :
`https://joboracle.cloud/mcp`, sans authentification ; les outils `search` et `fetch` y donnent
la recherche par mots-clés et le contenu complet d'un résultat.

## Bonnes pratiques pour le code que tu écris

1. Garde `avertissement` et `version` avec toute donnée que tu stockes ou affiches.
2. Garde le `statut` de chaque lien ; n'affiche jamais un lien `propose` comme un fait.
3. Cite les identifiants et, pour la provenance, l'`url` de la source (`/sources`).
4. Encode les paramètres ; respecte les limites ; gère 404, 400 et 429.
5. Pour comprendre un champ, lis le schéma (`/schema`) et le guide de l'oracle
   (ressource MCP `oracle://guide`).
