Serveur MCP

Support DQE
Support DQE
  • Mise à jour
Serveur MCP - DQE One Standalone

DQE One Standalone expose un endpoint Model Context Protocol (MCP) afin que des assistants IA tels que Claude puissent lister, créer et lancer vos processes, vérifier les runs et téléverser des fichiers — les mêmes opérations que l'API REST, pilotées par la conversation.

{DOMAIN} est le nom d'hôte de votre propre serveur DQE One Standalone — il est auto-hébergé, cette valeur dépend donc de votre déploiement. {EMAIL} est votre identifiant de connexion DQE One et {API_TOKEN} le token généré dans My Account > API Token.
Documentation associée : DQE One Standalone API — Introduction (l'API REST sur laquelle les outils sont construits) et Manage your profile in DQE One Standalone (API token).
En un coup d'œil : JSON-RPC 2.0 sur HTTP à l'adresse POST https://{DOMAIN}/mcp, version de protocole 2024-11-05, 18 outils, 5 prompts, aucune ressource. Réponses JSON simples (sans streaming).

Connecter un assistant IA

L'assistant agit en votre nom et ne voit que vos propres objets. En coulisses, chaque outil appelle l'API REST avec votre API token : vous devez donc avoir généré un API token (My Account > API Token), même si vous vous connectez avec OAuth.

Option A — avec un en-tête (Claude Code, fichier de configuration de Claude Desktop)

Construisez le credential Basic à partir de votre email et de votre token :

# Linux / macOS echo -n "you@example.com:your_api_token" | base64 # Windows PowerShell [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("you@example.com:your_api_token"))

Claude Code (redémarrez ensuite la session ; les serveurs MCP se chargent au démarrage) :

claude mcp add --transport http dqe-one https://{DOMAIN}/mcp \ --header "Authorization: Basic <your_base64_credential>"

Claude Desktop — modifiez claude_desktop_config.json (macOS ~/Library/Application Support/Claude/, Windows %APPDATA%\Claude\) puis redémarrez :

{ "mcpServers": { "dqe-one": { "type": "http", "url": "https://{DOMAIN}/mcp", "headers": { "Authorization": "Basic <your_base64_credential>" } } } }

Option B — OAuth (connecteurs personnalisés, par exemple dans claude.ai)

Saisissez uniquement l'URL https://{DOMAIN}/mcp. L'assistant découvre ensuite tout seul le reste :

  1. Le serveur répond 401 avec un en-tête WWW-Authenticate pointant vers /.well-known/oauth-protected-resource.
  2. Le client lit /.well-known/oauth-authorization-server et s'enregistre via /oauth/register.
  3. Il ouvre /oauth/authorize. Vous devez être connecté à DQE One dans le même navigateur ; vérifiez le nom du client et cliquez sur Authorize.
  4. Le client échange le code sur /oauth/token (PKCE S256 requis) et reçoit un token Bearer valable 1 heure ainsi qu'un refresh token.
Accessibilité : pour claude.ai, le callback et chaque appel d'outil proviennent du côté d'Anthropic : votre serveur doit donc être joignable en HTTPS depuis Internet. Un serveur uniquement accessible sur votre intranet fonctionne avec Claude Code ou Claude Desktop sur une machine qui peut l'atteindre (Option A).

Outils (18)

Les arguments marqués * sont obligatoires. Un outil qui échoue répond tout de même HTTP 200 avec isError: true et le message de l'API REST sous-jacente.

Outil Arguments Renvoie
list_processes — [{id,name,type,isDraft,lastRunId}] (vos processes)
get_process id* Détails du process : source, file, credentials, ruleSet, lastRunId, dates
list_runs processId, runId, kind Un run (avec runId) ou [{id,processId,type,startedOn,updatedOn,status,outputFile,count,error}]. processId l'emporte sur kind.
list_files — [{id,name,headers,rows,process_id}]
get_file id* Une entrée de fichier
list_rulesets — [{id,setId,label,updatedOn,source}]. Aucun statut de publication n'est renvoyé, quoi que dise la description de l'outil.
list_credentials — [{id,name}]. Le type de connecteur n'est pas renvoyé.
get_credential id* {id,login,name,type,status,process} ; jamais le mot de passe ni la clé
get_upload_status token* {status: pending|done|expired, file_id, ttl_seconds}
check_dataverse_table credential_id*, table_name* {table,exists,record_count}. Nécessite un credential Dynamics.
query_dataverse_table credential_id*, table_name*, top (100, max 5000) {table,exists,total_count,returned_count,records} — renvoie de vrais enregistrements clients à l'assistant.
start_marketing_campaign — Le texte du prompt marketing_campaign ; n'exécute rien.
create_process WRITE name*, kind*, source*, primaryKey*, fields* ; credential, ruleSet, file, object, input_file_path, output_dir_path, description optionnels {"status":"success","id":N}. Mêmes règles que Processes → createProcess.
run_process WRITE id* {"status":"success","message":"Process Enqueue","run_id":"101"} — asynchrone
upload_file WRITE — {url, token, expires_in: 3600, instructions} — un lien de téléversement via navigateur
delete_file WRITE DESTRUCTIVE id* Définitif ; refusé tant que le fichier est lié à un process
create_credential WRITE name*, type* (salesforce, sftp, bigquery) ; login, client_id, endpoint, port, password, email, id, key_id, pvt {"status":"success","id":N}
delete_credential WRITE DESTRUCTIVE id* Refusé tant qu'un process l'utilise

Ce qui diffère des descriptions des outils

  • create_process ne peut pas définir filters, sync, autoMerge, mergeThreshold, metaToReparent, allowEmpty, next ni reject_dir_path — les processes SFTP ne peuvent donc pas être créés via MCP. fields a une forme différente selon le kind (voir Processes), et pour check_duplicate il s'agit de {"<setId>": ["<matching rule label>"]}.
  • create_credential propose 3 des 6 types REST. Ses secrets transitent par le contexte de l'assistant (et sont écrits dans les logs de debug du serveur) : créez plutôt les credentials dans l'interface web.
  • run_process peut renvoyer un résultat normal contenant {"status":"error"} (process en brouillon, aucun fichier SFTP, échec de la mise en file d'attente) : lisez le corps de la réponse.
  • Aucun outil ne lit les libellés de correspondance d'un RuleSet, n'annule un run, ne télécharge de résultats, ne fusionne ni ne synchronise. Consultez les résultats dans l'interface web.

Prompts (5)

prompts/list renvoie cinq prompts sans paramètres. prompts/get renvoie {description, messages, instructions} (instructions est un ajout non standard). Il n'y a aucune ressource MCP.

Prompt Objectif
create_process_dedup Création guidée d'un process de déduplication (il demande encore les filtres, le reparenting et la synchronisation, que create_process ne peut pas définir).
marketing_campaign Workflow Dynamics en sept étapes : query_dataverse_table → create_process + run_process (check_email, check_phone, check_duplicate) → list_runs. L'envoi de SMS est “bientôt disponible”.
run_existing_process list_processes → get_process → run_process → list_runs.
check_process_status Vérifier le statut d'un process.
manage_credentials Workflow de gestion des credentials.

Téléverser un fichier via MCP

  1. L'assistant appelle upload_file et obtient https://{DOMAIN}/upload/<token>/, valable 1 heure.
  2. Vous ouvrez le lien dans un navigateur et déposez un fichier .csv, .xlsx ou .xls (en-têtes uniques, sans espaces, un fichier par lien).
  3. L'assistant interroge get_upload_status régulièrement jusqu'à done, ce qui fournit le file_id.
  4. create_process avec "source":"csv" et "file": <file_id>.
Le lien est le credential. La page de téléversement ne demande aucune connexion : toute personne détenant l'URL peut téléverser dans votre compte pendant une heure, et le lien est affiché dans le chat. La page indique “max 50 MB” mais aucune limite n'est appliquée côté serveur.

Exemple pas à pas — dédoublonner un CSV

  1. list_rulesets → choisissez-en un avec source: "csv" ; notez son id (7) et son setId (RS_ABC).
  2. upload_file, donnez l'URL à l'utilisateur, puis get_upload_status jusqu'à done (file_id 12).
  3. get_file {"id":12} → vérifiez que la clé primaire figure dans headers.
  4. Trouvez les libellés de correspondance qu'utilise le RuleSet. Aucun outil MCP ne les renvoie : demandez-les à l'utilisateur, ou lisez matching.Labels[].value avec getRuleset dans l'API REST.
  5. create_process:
{ "name": "Dedup contacts", "kind": "check_duplicate", "source": "csv", "primaryKey": "id", "file": 12, "ruleSet": 7, "fields": { "RS_ABC": ["Email + Name"] } }
  1. run_process {"id":42} → run_id "101".
  2. list_runs {"runId":101} jusqu'à ce que status soit Finished ou Failed.
  3. Passez en revue les doublons dans l'interface web DQE One.

Limitations et notes de sécurité

Ces points décrivent le comportement actuel du produit.

  • Pas de scopes, pas de mode lecture seule : un assistant connecté peut tout faire ce que votre compte peut faire. Ne connectez que des assistants de confiance.
  • L'enregistrement des clients OAuth est ouvert (sans authentification) : n'importe quel client peut s'enregistrer et choisir le nom affiché sur l'écran de consentement. Vérifiez le nom et la redirection avant de cliquer sur Authorize. Vous devez toujours être connecté et donner votre consentement.
  • Les refresh tokens n'expirent jamais et ne sont pas renouvelés ; les tokens sont stockés en clair dans la base de données ; il n'existe aucun écran de révocation. Les administrateurs peuvent révoquer un token dans la base de données.
  • Le serveur écrit les corps de requêtes et les arguments des outils — y compris les secrets des credentials — dans sa sortie de debug ; leur présence dans les logs dépend de votre déploiement.
  • Pas de limitation de débit ; CORS est ouvert à toute origine ; le transport SSE historique conserve les sessions en mémoire et ne fonctionne qu'avec un seul worker.
Endpoint JSON-RPC - DQE One Standalone MCP

Le point d'entrée unique : envoyez un message JSON-RPC, recevez un objet JSON en retour.

mcpRpc

Requête

Envoyez un corps JSON-RPC 2.0. initialize et ping ne nécessitent aucune authentification ; tout le reste nécessite Basic ou Bearer.

Appeler un outil : {"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"list_processes","arguments":{}}}. Le résultat est {"content":[{"type":"text","text":"<JSON as a string>"}]} ; en cas d'échec, isError vaut true mais le statut HTTP reste 200.
Codes d'erreur : -32700 erreur d'analyse (HTTP 400) ; -32601 méthode inconnue ou outil inconnu ; -32602 prompt inconnu. Un accès non autorisé renvoie un HTTP 401 avec un en-tête WWW-Authenticate qui lance la découverte OAuth. Il n'y a pas de traitement par lots et resources/* n'est pas implémenté.
POSThttps://{DOMAIN}/mcp

Exemples de code

Envoyer une requête JSON-RPC

curl -u "{EMAIL}:{API_TOKEN}" -X POST \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }' \ "https://{DOMAIN}/mcp"
fetch("https://{DOMAIN}/mcp", { method: "POST", headers: { "Authorization": "Basic " + btoa("{EMAIL}:{API_TOKEN}"), "Content-Type": "application/json" }, body: JSON.stringify({ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }) }) .then(r => r.text()) .then(data => console.log(data));
import requests response = requests.post( "https://{DOMAIN}/mcp", auth=("{EMAIL}", "{API_TOKEN}"), json={"jsonrpc": "2.0", "id": 2, "method": "tools/list"}, ) print(response.status_code, response.text)
<?php $ch = curl_init("https://{DOMAIN}/mcp"); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_USERPWD, "{EMAIL}:{API_TOKEN}"); $data = ['jsonrpc' => '2.0', 'id' => 2, 'method' => 'tools/list']; curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . " " . $response;
const axios = require('axios'); axios({ method: "post", url: "https://{DOMAIN}/mcp", auth: { username: "{EMAIL}", password: "{API_TOKEN}" }, data: { "jsonrpc": "2.0", "id": 2, "method": "tools/list" } }) .then(res => console.log(res.status, res.data)) .catch(err => console.log(err.response ? err.response.status : err.message, err.response && err.response.data));
import java.net.URI; import java.net.http.*; import java.util.Base64; String auth = Base64.getEncoder().encodeToString("{EMAIL}:{API_TOKEN}".getBytes()); String body = "{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/list\"}"; HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://{DOMAIN}/mcp")) .header("Authorization", "Basic " + auth) .header("Content-Type", "application/json") .method("POST", HttpRequest.BodyPublishers.ofString(body)) .build(); HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.statusCode() + " " + response.body());
using System.Net.Http; using System.Net.Http.Headers; using System.Text; using var client = new HttpClient(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue( "Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("{EMAIL}:{API_TOKEN}"))); using var request = new HttpRequestMessage(HttpMethod.Post, "https://{DOMAIN}/mcp"); request.Content = new StringContent("{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/list\"}", Encoding.UTF8, "application/json"); var response = await client.SendAsync(request); Console.WriteLine((int)response.StatusCode + " " + await response.Content.ReadAsStringAsync());
package main import ( "bytes" "fmt" "io" "net/http" ) func main() { body := []byte(`{"jsonrpc":"2.0","id":2,"method":"tools/list"}`) req, _ := http.NewRequest("POST", "https://{DOMAIN}/mcp", bytes.NewBuffer(body)) req.SetBasicAuth("{EMAIL}", "{API_TOKEN}") req.Header.Set("Content-Type", "application/json") resp, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer resp.Body.Close() out, _ := io.ReadAll(resp.Body) fmt.Println(resp.StatusCode, string(out)) }

Paramètres

Champ Description Type Obl / Opt
jsonrpc
Valeurs : 2.0
String Obligatoire
id Integer Optionnel
method initialize et ping ne nécessitent aucune authentification. Tout le reste en nécessite une. resources/* n'est pas implémenté (-32601).
Valeurs : initialize, ping, tools/list, tools/call, prompts/list, prompts/get
String Obligatoire
params Object Optionnel
Authentification : HTTP Basic (email:api_token) ou un token OAuth Bearer. La console ci-dessous utilise Basic.

Réponse

Réponse JSON-RPC. Un outil en échec renvoie tout de même HTTP 200 avec result.isError = true.. Statut HTTP 200.

Clé Description Type
jsonrpc String
id Integer
result Object
error Object

Exemple de réponse

Exemple de réponse
{ "jsonrpc": "2.0", "id": 1, "result": { "protocolVersion": "2024-11-05", "capabilities": { "tools": {}, "prompts": {} }, "serverInfo": { "name": "dqe-one", "version": "1.0.0" } } }

Erreurs

HTTP Corps / signification
400 Erreur d'analyse (-32700).
401 Non autorisé. Porte un en-tête WWW-Authenticate: Bearer resource_metadata=... qui déclenche la découverte OAuth.

Tester l'API

Cliquez sur le bouton ci-dessous pour tester cet endpoint en direct dans votre navigateur.

À savoir : cette console envoie une vraie requête à votre propre serveur depuis votre navigateur, avec votre véritable API token. tools/call peut démarrer des runs ou supprimer des données.
Ouvrir la console
Informations du serveur - DQE One Standalone MCP

Renvoie des informations de base sur le serveur sans authentification. Avec Accept: text/event-stream, il ouvre à la place le transport SSE historique (authentification Basic uniquement ; un seul worker).

mcpInfo

Requête

Envoyez une requête GET.

GEThttps://{DOMAIN}/mcp

Exemples de code

Informations du serveur, ou flux SSE historique

curl \ "https://{DOMAIN}/mcp"
fetch("https://{DOMAIN}/mcp", { method: "GET" }) .then(r => r.text()) .then(data => console.log(data));
import requests response = requests.get( "https://{DOMAIN}/mcp", ) print(response.status_code, response.text)
<?php $ch = curl_init("https://{DOMAIN}/mcp"); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . " " . $response;
const axios = require('axios'); axios({ method: "get", url: "https://{DOMAIN}/mcp" }) .then(res => console.log(res.status, res.data)) .catch(err => console.log(err.response ? err.response.status : err.message, err.response && err.response.data));
import java.net.URI; import java.net.http.*; import java.util.Base64; HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://{DOMAIN}/mcp")) .method("GET", HttpRequest.BodyPublishers.noBody()) .build(); HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.statusCode() + " " + response.body());
using System.Net.Http; using System.Net.Http.Headers; using System.Text; using var client = new HttpClient(); using var request = new HttpRequestMessage(HttpMethod.Get, "https://{DOMAIN}/mcp"); var response = await client.SendAsync(request); Console.WriteLine((int)response.StatusCode + " " + await response.Content.ReadAsStringAsync());
package main import ( "fmt" "io" "net/http" ) func main() { req, _ := http.NewRequest("GET", "https://{DOMAIN}/mcp", nil) resp, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer resp.Body.Close() out, _ := io.ReadAll(resp.Body) fmt.Println(resp.StatusCode, string(out)) }

Paramètres

Cet endpoint ne prend aucun paramètre.

Authentification : aucune — cet endpoint est public (ou sécurisé par un token dans l'URL, voir ci-dessus).

Réponse

Informations du serveur ou flux d'événements.. Statut HTTP 200.

Exemple de réponse

Exemple de réponse
{ "name": "dqe-one", "version": "1.0.0" }

Erreurs

HTTP Corps / signification
Aucune réponse d'erreur n'est documentée pour cet endpoint.

Tester l'API

Cliquez sur le bouton ci-dessous pour tester cet endpoint en direct dans votre navigateur.

À savoir : cette console envoie une vraie requête à votre propre serveur depuis votre navigateur, avec votre véritable API token.
Ouvrir la console
Métadonnées de la ressource protégée OAuth - DQE One Standalone MCP

Métadonnées RFC 9728 utilisées par les clients pour découvrir le serveur d'autorisation.

oauthProtectedResource

Requête

Envoyez une requête GET.

GEThttps://{DOMAIN}/.well-known/oauth-protected-resource

Exemples de code

Métadonnées de la ressource protégée (RFC 9728)

curl \ "https://{DOMAIN}/.well-known/oauth-protected-resource"
fetch("https://{DOMAIN}/.well-known/oauth-protected-resource", { method: "GET" }) .then(r => r.text()) .then(data => console.log(data));
import requests response = requests.get( "https://{DOMAIN}/.well-known/oauth-protected-resource", ) print(response.status_code, response.text)
<?php $ch = curl_init("https://{DOMAIN}/.well-known/oauth-protected-resource"); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . " " . $response;
const axios = require('axios'); axios({ method: "get", url: "https://{DOMAIN}/.well-known/oauth-protected-resource" }) .then(res => console.log(res.status, res.data)) .catch(err => console.log(err.response ? err.response.status : err.message, err.response && err.response.data));
import java.net.URI; import java.net.http.*; import java.util.Base64; HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://{DOMAIN}/.well-known/oauth-protected-resource")) .method("GET", HttpRequest.BodyPublishers.noBody()) .build(); HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.statusCode() + " " + response.body());
using System.Net.Http; using System.Net.Http.Headers; using System.Text; using var client = new HttpClient(); using var request = new HttpRequestMessage(HttpMethod.Get, "https://{DOMAIN}/.well-known/oauth-protected-resource"); var response = await client.SendAsync(request); Console.WriteLine((int)response.StatusCode + " " + await response.Content.ReadAsStringAsync());
package main import ( "fmt" "io" "net/http" ) func main() { req, _ := http.NewRequest("GET", "https://{DOMAIN}/.well-known/oauth-protected-resource", nil) resp, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer resp.Body.Close() out, _ := io.ReadAll(resp.Body) fmt.Println(resp.StatusCode, string(out)) }

Paramètres

Cet endpoint ne prend aucun paramètre.

Authentification : aucune — cet endpoint est public (ou sécurisé par un token dans l'URL, voir ci-dessus).

Réponse

{resource, authorization_servers, bearer_methods_supported}. Statut HTTP 200.

Exemple de réponse

Exemple de réponse
{ "resource": "https://{DOMAIN}/mcp", "authorization_servers": [ "https://{DOMAIN}" ], "bearer_methods_supported": [ "header" ] }

Erreurs

HTTP Corps / signification
Aucune réponse d'erreur n'est documentée pour cet endpoint.

Tester l'API

Cliquez sur le bouton ci-dessous pour tester cet endpoint en direct dans votre navigateur.

À savoir : cette console envoie une vraie requête à votre propre serveur depuis votre navigateur, avec votre véritable API token.
Ouvrir la console
Métadonnées du serveur OAuth - DQE One Standalone MCP

Métadonnées RFC 8414 : endpoints et flux pris en charge.

oauthServerMetadata

Requête

Envoyez une requête GET.

GEThttps://{DOMAIN}/.well-known/oauth-authorization-server

Exemples de code

Métadonnées du serveur d'autorisation (RFC 8414)

curl \ "https://{DOMAIN}/.well-known/oauth-authorization-server"
fetch("https://{DOMAIN}/.well-known/oauth-authorization-server", { method: "GET" }) .then(r => r.text()) .then(data => console.log(data));
import requests response = requests.get( "https://{DOMAIN}/.well-known/oauth-authorization-server", ) print(response.status_code, response.text)
<?php $ch = curl_init("https://{DOMAIN}/.well-known/oauth-authorization-server"); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . " " . $response;
const axios = require('axios'); axios({ method: "get", url: "https://{DOMAIN}/.well-known/oauth-authorization-server" }) .then(res => console.log(res.status, res.data)) .catch(err => console.log(err.response ? err.response.status : err.message, err.response && err.response.data));
import java.net.URI; import java.net.http.*; import java.util.Base64; HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://{DOMAIN}/.well-known/oauth-authorization-server")) .method("GET", HttpRequest.BodyPublishers.noBody()) .build(); HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.statusCode() + " " + response.body());
using System.Net.Http; using System.Net.Http.Headers; using System.Text; using var client = new HttpClient(); using var request = new HttpRequestMessage(HttpMethod.Get, "https://{DOMAIN}/.well-known/oauth-authorization-server"); var response = await client.SendAsync(request); Console.WriteLine((int)response.StatusCode + " " + await response.Content.ReadAsStringAsync());
package main import ( "fmt" "io" "net/http" ) func main() { req, _ := http.NewRequest("GET", "https://{DOMAIN}/.well-known/oauth-authorization-server", nil) resp, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer resp.Body.Close() out, _ := io.ReadAll(resp.Body) fmt.Println(resp.StatusCode, string(out)) }

Paramètres

Cet endpoint ne prend aucun paramètre.

Authentification : aucune — cet endpoint est public (ou sécurisé par un token dans l'URL, voir ci-dessus).

Réponse

Endpoints, grant types (authorization_code, refresh_token), PKCE S256, méthodes d'authentification none/client_secret_post.. Statut HTTP 200.

Exemple de réponse

Exemple de réponse
{ "authorization_endpoint": "https://{DOMAIN}/oauth/authorize", "token_endpoint": "https://{DOMAIN}/oauth/token", "registration_endpoint": "https://{DOMAIN}/oauth/register", "response_types_supported": [ "code" ], "grant_types_supported": [ "authorization_code", "refresh_token" ], "code_challenge_methods_supported": [ "S256" ], "token_endpoint_auth_methods_supported": [ "none", "client_secret_post" ] }

Erreurs

HTTP Corps / signification
Aucune réponse d'erreur n'est documentée pour cet endpoint.

Tester l'API

Cliquez sur le bouton ci-dessous pour tester cet endpoint en direct dans votre navigateur.

À savoir : cette console envoie une vraie requête à votre propre serveur depuis votre navigateur, avec votre véritable API token.
Ouvrir la console
Enregistrer un client - DQE One Standalone MCP

Enregistrement dynamique de client (RFC 7591). Ouvert : aucune authentification.

oauthRegister

Requête

Envoyez un corps JSON contenant au moins redirect_uris.

POSThttps://{DOMAIN}/oauth/register

Exemples de code

Enregistrement dynamique de client (RFC 7591)

curl -X POST \ -H "Content-Type: application/json" \ -d '{ "redirect_uris": [ "https://client.example.com/callback" ], "client_name": "My connector" }' \ "https://{DOMAIN}/oauth/register"
fetch("https://{DOMAIN}/oauth/register", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ "redirect_uris": [ "https://client.example.com/callback" ], "client_name": "My connector" }) }) .then(r => r.text()) .then(data => console.log(data));
import requests response = requests.post( "https://{DOMAIN}/oauth/register", json={"redirect_uris": ["https://client.example.com/callback"], "client_name": "My connector"}, ) print(response.status_code, response.text)
<?php $ch = curl_init("https://{DOMAIN}/oauth/register"); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); $data = ['redirect_uris' => ['https://client.example.com/callback'], 'client_name' => 'My connector']; curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . " " . $response;
const axios = require('axios'); axios({ method: "post", url: "https://{DOMAIN}/oauth/register", data: { "redirect_uris": [ "https://client.example.com/callback" ], "client_name": "My connector" } }) .then(res => console.log(res.status, res.data)) .catch(err => console.log(err.response ? err.response.status : err.message, err.response && err.response.data));
import java.net.URI; import java.net.http.*; import java.util.Base64; String body = "{\"redirect_uris\":[\"https://client.example.com/callback\"],\"client_name\":\"My connector\"}"; HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://{DOMAIN}/oauth/register")) .header("Content-Type", "application/json") .method("POST", HttpRequest.BodyPublishers.ofString(body)) .build(); HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.statusCode() + " " + response.body());
using System.Net.Http; using System.Net.Http.Headers; using System.Text; using var client = new HttpClient(); using var request = new HttpRequestMessage(HttpMethod.Post, "https://{DOMAIN}/oauth/register"); request.Content = new StringContent("{\"redirect_uris\":[\"https://client.example.com/callback\"],\"client_name\":\"My connector\"}", Encoding.UTF8, "application/json"); var response = await client.SendAsync(request); Console.WriteLine((int)response.StatusCode + " " + await response.Content.ReadAsStringAsync());
package main import ( "bytes" "fmt" "io" "net/http" ) func main() { body := []byte(`{"redirect_uris":["https://client.example.com/callback"],"client_name":"My connector"}`) req, _ := http.NewRequest("POST", "https://{DOMAIN}/oauth/register", bytes.NewBuffer(body)) req.Header.Set("Content-Type", "application/json") resp, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer resp.Body.Close() out, _ := io.ReadAll(resp.Body) fmt.Println(resp.StatusCode, string(out)) }

Paramètres

Champ Description Type Obl / Opt
redirect_uris Liste non vide d'URL de callback. Array Obligatoire
client_name Affiché à l'utilisateur sur la page de consentement. String Optionnel
token_endpoint_auth_method client_secret_post renvoie également un client_secret, une seule fois.
Valeurs : none, client_secret_post · Par défaut : "none"
String Optionnel
Authentification : aucune — cet endpoint est public (ou sécurisé par un token dans l'URL, voir ci-dessus).

Réponse

Client enregistré (client_secret renvoyé une seule fois pour client_secret_post).. Statut HTTP 201.

Exemple de réponse

Exemple de réponse
{ "client_id": "kQ3...", "client_name": "My connector", "redirect_uris": [ "https://client.example.com/callback" ], "token_endpoint_auth_method": "none" }

Erreurs

HTTP Corps / signification
400 Requête invalide.
Page de consentement - DQE One Standalone MCP

La page où vous approuvez un connecteur. Elle s'ouvre dans un navigateur et n'est pas appelée depuis du code. Vous devez être connecté à DQE One dans le même navigateur ; PKCE S256 est obligatoire ; le code est valable 5 minutes.

oauthAuthorize

Requête

Le client redirige votre navigateur vers cette URL.

GEThttps://{DOMAIN}/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type={response_type}&code_challenge={code_challenge}&code_challenge_method={code_challenge_method}&state={state}

Exemple d'URL

https://{DOMAIN}/oauth/authorize?client_id=kQ3...&redirect_uri=https%3A%2F%2Fclient.example.com%2Fcallback&response_type=code&code_challenge=E9Melhoa...&code_challenge_method=S256&state=xyz

Paramètres

Champ Description Type Obl / Opt
client_id Client id renvoyé par /oauth/register. String Obligatoire
redirect_uri Doit correspondre exactement à l'une des URI de redirection enregistrées. String Obligatoire
response_type code (par défaut). String Optionnel
code_challenge Challenge PKCE. String Obligatoire
code_challenge_method Doit être S256. String Obligatoire
state Valeur opaque renvoyée au client. String Optionnel
Authentification : aucune — cet endpoint est public (ou sécurisé par un token dans l'URL, voir ci-dessus).

Réponse

Page de consentement (Allow / Deny).. Statut HTTP 200.

Exemple de réponse

Exemple de réponse
{ "redirect": "https://client.example.com/callback?code=...&state=xyz" }

Erreurs

HTTP Corps / signification
400 Requête invalide.
Endpoint de token - DQE One Standalone MCP

Échange un code d'autorisation contre des tokens, ou renouvelle un access token. L'access token est valable 1 heure ; les refresh tokens n'expirent pas et ne sont pas renouvelés.

oauthToken

Requête

Envoyez un POST encodé en formulaire.

POSThttps://{DOMAIN}/oauth/token

Exemples de code

Échanger un code ou renouveler un token

curl -X POST \ --data-urlencode "grant_type=authorization_code" \ --data-urlencode "code=AUTH_CODE" \ --data-urlencode "redirect_uri=https://client.example.com/callback" \ --data-urlencode "code_verifier=PKCE_VERIFIER" \ --data-urlencode "client_id=CLIENT_ID" \ "https://{DOMAIN}/oauth/token"
fetch("https://{DOMAIN}/oauth/token", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: new URLSearchParams({ "grant_type": "authorization_code", "code": "AUTH_CODE", "redirect_uri": "https://client.example.com/callback", "code_verifier": "PKCE_VERIFIER", "client_id": "CLIENT_ID" }) }) .then(r => r.text()) .then(data => console.log(data));
import requests response = requests.post( "https://{DOMAIN}/oauth/token", data={"grant_type": "authorization_code", "code": "AUTH_CODE", "redirect_uri": "https://client.example.com/callback", "code_verifier": "PKCE_VERIFIER", "client_id": "CLIENT_ID"}, ) print(response.status_code, response.text)
<?php $ch = curl_init("https://{DOMAIN}/oauth/token"); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(['grant_type' => 'authorization_code', 'code' => 'AUTH_CODE', 'redirect_uri' => 'https://client.example.com/callback', 'code_verifier' => 'PKCE_VERIFIER', 'client_id' => 'CLIENT_ID'])); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . " " . $response;
const axios = require('axios'); axios({ method: "post", url: "https://{DOMAIN}/oauth/token", data: new URLSearchParams({ "grant_type": "authorization_code", "code": "AUTH_CODE", "redirect_uri": "https://client.example.com/callback", "code_verifier": "PKCE_VERIFIER", "client_id": "CLIENT_ID" }) }) .then(res => console.log(res.status, res.data)) .catch(err => console.log(err.response ? err.response.status : err.message, err.response && err.response.data));
import java.net.URI; import java.net.http.*; import java.util.Base64; String body = "grant_type=authorization_code&code=AUTH_CODE&redirect_uri=https%3A%2F%2Fclient.example.com%2Fcallback&code_verifier=PKCE_VERIFIER&client_id=CLIENT_ID"; HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://{DOMAIN}/oauth/token")) .header("Content-Type", "application/x-www-form-urlencoded") .method("POST", HttpRequest.BodyPublishers.ofString(body)) .build(); HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.statusCode() + " " + response.body());
using System.Net.Http; using System.Net.Http.Headers; using System.Text; using var client = new HttpClient(); using var request = new HttpRequestMessage(HttpMethod.Post, "https://{DOMAIN}/oauth/token"); request.Content = new FormUrlEncodedContent(new Dictionary<string, string> { { "grant_type", "authorization_code" }, { "code", "AUTH_CODE" }, { "redirect_uri", "https://client.example.com/callback" }, { "code_verifier", "PKCE_VERIFIER" }, { "client_id", "CLIENT_ID" } }); var response = await client.SendAsync(request); Console.WriteLine((int)response.StatusCode + " " + await response.Content.ReadAsStringAsync());
package main import ( "fmt" "io" "net/http" "net/url" "strings" ) func main() { form := url.Values{} form.Set("grant_type", "authorization_code") form.Set("code", "AUTH_CODE") form.Set("redirect_uri", "https://client.example.com/callback") form.Set("code_verifier", "PKCE_VERIFIER") form.Set("client_id", "CLIENT_ID") req, _ := http.NewRequest("POST", "https://{DOMAIN}/oauth/token", strings.NewReader(form.Encode())) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") resp, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer resp.Body.Close() out, _ := io.ReadAll(resp.Body) fmt.Println(resp.StatusCode, string(out)) }

Paramètres

Champ Description Type Obl / Opt
grant_type
Valeurs : authorization_code, refresh_token
String Obligatoire
code Code d'autorisation (5 minutes, usage unique). String Optionnel
redirect_uri Même valeur que dans la requête d'autorisation. String Optionnel
code_verifier Vérifieur PKCE (verifier). String Optionnel
refresh_token Pour grant_type refresh_token. String Optionnel
client_id String Optionnel
client_secret Uniquement pour les clients enregistrés avec client_secret_post. String Optionnel
Authentification : aucune — cet endpoint est public (ou sécurisé par un token dans l'URL, voir ci-dessus).

Réponse

{access_token, token_type: Bearer, expires_in: 3600, refresh_token, scope}. Statut HTTP 200.

Exemple de réponse

Exemple de réponse
{ "access_token": "...", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "...", "scope": "" }

Erreurs

HTTP Corps / signification
400 invalid_grant / invalid_client.
Page de téléversement - DQE One Standalone MCP

La page navigateur derrière le lien renvoyé par l'outil upload_file. Le token dans l'URL est le seul credential.

uploadPage

Requête

Vous ouvrez le lien dans un navigateur.

GEThttps://{DOMAIN}/upload/{token}/

Exemple d'URL

https://{DOMAIN}/upload/3f1c0a52-...-9b7e/

Paramètres

Champ Description Type Obl / Opt
token String Obligatoire
Authentification : aucune — cet endpoint est public (ou sécurisé par un token dans l'URL, voir ci-dessus).

Réponse

Page HTML.. Statut HTTP 200.

Exemple de réponse

Exemple de réponse
{ "info": "HTML page" }

Erreurs

HTTP Corps / signification
Aucune réponse d'erreur n'est documentée pour cet endpoint.
Téléverser le fichier - DQE One Standalone MCP

Ce que la page de téléversement envoie lorsque vous déposez un fichier. Vous n'avez normalement jamais à l'appeler vous-même.

uploadFile

Requête

Un POST multipart/form-data avec le champ file.

Un fichier par lien, valable 1 heure. .csv, .xlsx, .xls ; en-têtes uniques et sans espaces. Aucune limite de taille côté serveur.
POSThttps://{DOMAIN}/upload/{token}/

Exemples de code

Téléverser le fichier

curl -X POST \ -F "file=@contacts.csv" \ "https://{DOMAIN}/upload/{token}/"
const form = new FormData(); form.append("file", fileInput.files[0]); // <input type="file"> fetch("https://{DOMAIN}/upload/{token}/", { method: "POST", body: form }) .then(r => r.text()) .then(data => console.log(data));
import requests response = requests.post( "https://{DOMAIN}/upload/{token}/", files={"file": open("contacts.csv", "rb")}, ) print(response.status_code, response.text)
<?php $ch = curl_init("https://{DOMAIN}/upload/{token}/"); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_POSTFIELDS, ['file' => new CURLFile("contacts.csv")]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . " " . $response;
const axios = require('axios'); const FormData = require('form-data'); const fs = require('fs'); const form = new FormData(); form.append('file', fs.createReadStream("contacts.csv")); axios({ method: "post", url: "https://{DOMAIN}/upload/{token}/", headers: form.getHeaders(), data: form }) .then(res => console.log(res.status, res.data)) .catch(err => console.log(err.response ? err.response.status : err.message, err.response && err.response.data));
import java.net.URI; import java.net.http.*; import java.util.Base64; String boundary = "----dqe" + System.nanoTime(); byte[] content = java.nio.file.Files.readAllBytes(java.nio.file.Path.of("contacts.csv")); var out = new java.io.ByteArrayOutputStream(); out.write(("--" + boundary + "\r\nContent-Disposition: form-data; name=\"file\"; filename=\"" + "contacts.csv" + "\"\r\n\r\n").getBytes()); out.write(content); out.write(("\r\n--" + boundary + "--\r\n").getBytes()); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://{DOMAIN}/upload/{token}/")) .header("Content-Type", "multipart/form-data; boundary=" + boundary) .method("POST", HttpRequest.BodyPublishers.ofByteArray(out.toByteArray())) .build(); HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.statusCode() + " " + response.body());
using System.Net.Http; using System.Net.Http.Headers; using System.Text; using var client = new HttpClient(); using var request = new HttpRequestMessage(HttpMethod.Post, "https://{DOMAIN}/upload/{token}/"); var form = new MultipartFormDataContent(); form.Add(new ByteArrayContent(File.ReadAllBytes("contacts.csv")), "file", "contacts.csv"); request.Content = form; var response = await client.SendAsync(request); Console.WriteLine((int)response.StatusCode + " " + await response.Content.ReadAsStringAsync());
package main import ( "bytes" "fmt" "io" "mime/multipart" "net/http" "os" ) func main() { var buf bytes.Buffer w := multipart.NewWriter(&buf) part, _ := w.CreateFormFile("file", "contacts.csv") f, _ := os.Open("contacts.csv") io.Copy(part, f) w.Close() req, _ := http.NewRequest("POST", "https://{DOMAIN}/upload/{token}/", &buf) req.Header.Set("Content-Type", w.FormDataContentType()) resp, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer resp.Body.Close() out, _ := io.ReadAll(resp.Body) fmt.Println(resp.StatusCode, string(out)) }

Paramètres

Champ Description Type Obl / Opt
token String Obligatoire
file String (file) Obligatoire
Authentification : aucune — cet endpoint est public (ou sécurisé par un token dans l'URL, voir ci-dessus).

Réponse

{status: success, file_id, name}. Statut HTTP 200.

Exemple de réponse

Exemple de réponse
{ "status": "success", "file_id": 12, "name": "contacts.csv" }

Erreurs

HTTP Corps / signification
400 Mauvaise extension, en-têtes invalides, ou lien déjà utilisé.

Voir aussi

Associé à

Cet article vous a-t-il été utile ?

Utilisateurs qui ont trouvé cela utile : 0 sur 0