MCP-Server

Support DQE
Support DQE
  • Aktualisiert
MCP-Server - DQE One Standalone

DQE One Standalone stellt einen Model-Context-Protocol-(MCP)-Endpoint bereit, über den KI-Assistenten wie Claude Ihre Processes auflisten, erstellen und ausführen, Runs prüfen und Dateien hochladen können — dieselben Operationen wie die REST API, gesteuert per Dialog.

{DOMAIN} ist der Hostname Ihres eigenen DQE One Standalone Servers — er wird selbst gehostet, daher hängt dieser Wert von Ihrer Bereitstellung ab. {EMAIL} ist Ihr DQE One Login und {API_TOKEN} der Token, der unter My Account > API Token generiert wird.
Zugehörige Dokumentation: DQE One Standalone API — Introduction (die REST API, auf der die Tools aufbauen) und Manage your profile in DQE One Standalone (API token).
Auf einen Blick: JSON-RPC 2.0 über HTTP unter POST https://{DOMAIN}/mcp, Protokollversion 2024-11-05, 18 Tools, 5 Prompts, keine Ressourcen. Einfache JSON-Antworten (kein Streaming).

Einen KI-Assistenten verbinden

Der Assistent handelt als Sie und sieht nur Ihre eigenen Objekte. Im Hintergrund ruft jedes Tool die REST API mit Ihrem API token auf, daher müssen Sie einen API token generiert haben (My Account > API Token), auch wenn Sie sich per OAuth verbinden.

Option A — mit einem Header (Claude Code, Konfigurationsdatei von Claude Desktop)

Erstellen Sie die Basic-Zugangsdaten aus Ihrer E-Mail-Adresse und Ihrem 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 (starten Sie die Sitzung anschließend neu; MCP-Server werden beim Start geladen):

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

Claude Desktop — bearbeiten Sie claude_desktop_config.json (macOS ~/Library/Application Support/Claude/, Windows %APPDATA%\Claude\) und starten Sie neu:

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

Option B — OAuth (benutzerdefinierte Connectors, zum Beispiel in claude.ai)

Geben Sie nur die URL https://{DOMAIN}/mcp ein. Der Assistent ermittelt dann alles Weitere selbst:

  1. Der Server antwortet mit 401 und einem WWW-Authenticate-Header, der auf /.well-known/oauth-protected-resource verweist.
  2. Der Client liest /.well-known/oauth-authorization-server und registriert sich über /oauth/register.
  3. Er öffnet /oauth/authorize. Sie müssen im selben Browser bei DQE One angemeldet sein; prüfen Sie den Client-Namen und klicken Sie auf Authorize.
  4. Der Client tauscht den Code bei /oauth/token ein (PKCE S256 erforderlich) und erhält ein Bearer-Token mit einer Gültigkeit von 1 Stunde sowie ein Refresh-Token.
Erreichbarkeit: Bei claude.ai kommen der Callback und jeder Tool-Aufruf von Anthropic-Seite, daher muss Ihr Server über HTTPS aus dem Internet erreichbar sein. Ein Server, der nur in Ihrem Intranet erreichbar ist, funktioniert mit Claude Code oder Claude Desktop auf einem Rechner, der ihn erreichen kann (Option A).

Tools (18)

Mit * markierte Argumente sind erforderlich. Ein Tool, das fehlschlägt, antwortet dennoch mit HTTP 200 und isError: true sowie der Meldung der zugrunde liegenden REST API.

Tool Argumente Rückgabe
list_processes — [{id,name,type,isDraft,lastRunId}] (Ihre Processes)
get_process id* Process-Details: Quelle, Datei, Credentials, ruleSet, lastRunId, Datumsangaben
list_runs processId, runId, kind Ein Run (mit runId) oder [{id,processId,type,startedOn,updatedOn,status,outputFile,count,error}]. processId hat Vorrang vor kind.
list_files — [{id,name,headers,rows,process_id}]
get_file id* Ein Dateieintrag
list_rulesets — [{id,setId,label,updatedOn,source}]. Es wird kein Veröffentlichungsstatus zurückgegeben, ungeachtet der Tool-Beschreibung.
list_credentials — [{id,name}]. Der Connector-Typ wird nicht zurückgegeben.
get_credential id* {id,login,name,type,status,process}; niemals das Passwort oder der Schlüssel
get_upload_status token* {status: pending|done|expired, file_id, ttl_seconds}
check_dataverse_table credential_id*, table_name* {table,exists,record_count}. Erfordert ein Dynamics-Credential.
query_dataverse_table credential_id*, table_name*, top (100, max. 5000) {table,exists,total_count,returned_count,records} — gibt echte Kundendatensätze an den Assistenten zurück.
start_marketing_campaign — Der Text des Prompts marketing_campaign; führt nichts aus.
create_process WRITE name*, kind*, source*, primaryKey*, fields*; optional credential, ruleSet, file, object, input_file_path, output_dir_path, description {"status":"success","id":N}. Es gelten dieselben Regeln wie bei Processes → createProcess.
run_process WRITE id* {"status":"success","message":"Process Enqueue","run_id":"101"} — asynchron
upload_file WRITE — {url, token, expires_in: 3600, instructions} — ein Upload-Link für den Browser
delete_file WRITE DESTRUCTIVE id* Endgültig; wird abgelehnt, solange die Datei mit einem Process verknüpft ist
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* Wird abgelehnt, solange ein Process es verwendet

Was von den Tool-Beschreibungen abweicht

  • create_process kann filters, sync, autoMerge, mergeThreshold, metaToReparent, allowEmpty, next oder reject_dir_path nicht setzen — daher lassen sich SFTP-Processes nicht über MCP erstellen. fields hat je nach kind einen anderen Aufbau (siehe Processes), und für check_duplicate lautet er {"<setId>": ["<matching rule label>"]}.
  • create_credential bietet 3 der 6 REST-Typen an. Die Secrets laufen durch den Kontext des Assistenten (und werden in die Debug-Logs des Servers geschrieben): Erstellen Sie Credentials stattdessen in der Weboberfläche.
  • run_process kann ein normales Ergebnis zurückgeben, das {"status":"error"} enthält (Entwurfs-Process, keine SFTP-Datei, Fehler bei der Warteschlange): Lesen Sie den Body.
  • Kein Tool liest die Matching-Bezeichnungen eines RuleSets, bricht einen Run ab, lädt Ergebnisse herunter, führt zusammen oder synchronisiert. Prüfen Sie die Ergebnisse in der Weboberfläche.

Prompts (5)

prompts/list gibt fünf parameterlose Prompts zurück. prompts/get gibt {description, messages, instructions} zurück (instructions ist eine nicht standardkonforme Ergänzung). Es gibt keine MCP-Ressourcen.

Prompt Zweck
create_process_dedup Geführte Erstellung eines Deduplizierungs-Process (er fragt weiterhin nach Filtern, Reparenting und Sync, die create_process nicht setzen kann).
marketing_campaign Siebenstufiger Dynamics-Ablauf: query_dataverse_table → create_process + run_process (check_email, check_phone, check_duplicate) → list_runs. Der SMS-Versand ist “demnächst verfügbar”.
run_existing_process list_processes → get_process → run_process → list_runs.
check_process_status Den Status eines Process prüfen.
manage_credentials Ablauf der Credential-Verwaltung.

Eine Datei über MCP hochladen

  1. Der Assistent ruft upload_file auf und erhält https://{DOMAIN}/upload/<token>/, gültig für 1 Stunde.
  2. Sie öffnen den Link in einem Browser und legen eine .csv-, .xlsx- oder .xls-Datei ab (eindeutige Spaltenüberschriften, keine Leerzeichen, eine Datei pro Link).
  3. Der Assistent fragt get_upload_status regelmäßig ab, bis done erscheint; damit erhält er die file_id.
  4. create_process mit "source":"csv" und "file": <file_id>.
Der Link ist das Credential. Die Upload-Seite erfordert keine Anmeldung: Jeder, der die URL besitzt, kann eine Stunde lang in Ihr Konto hochladen, und der Link wird im Chat angezeigt. Die Seite nennt “max 50 MB”, aber auf dem Server wird kein Limit durchgesetzt.

Durchgespieltes Beispiel — eine CSV-Datei deduplizieren

  1. list_rulesets → wählen Sie eines mit source: "csv"; notieren Sie dessen id (7) und setId (RS_ABC).
  2. upload_file, die URL an den Benutzer weitergeben, dann get_upload_status bis done (file_id 12).
  3. get_file {"id":12} → prüfen, ob der Primärschlüssel in headers enthalten ist.
  4. Die Matching-Bezeichnungen des RuleSets ermitteln. Kein MCP-Tool liefert sie: Fragen Sie den Benutzer oder lesen Sie matching.Labels[].value mit getRuleset in der REST API.
  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}, bis status den Wert Finished oder Failed hat.
  3. Prüfen Sie die Duplikate in der DQE One Weboberfläche.

Einschränkungen und Sicherheitshinweise

Diese Punkte beschreiben das aktuelle Verhalten des Produkts.

  • Keine Scopes, kein schreibgeschützter Modus: Ein verbundener Assistent kann alles tun, was Ihr Konto kann. Verbinden Sie nur Assistenten, denen Sie vertrauen.
  • Die OAuth-Client-Registrierung ist offen (keine Authentifizierung): Jeder Client kann sich registrieren und den Namen wählen, der auf dem Zustimmungsbildschirm angezeigt wird. Prüfen Sie den Namen und die Weiterleitung, bevor Sie auf Authorize klicken. Sie müssen weiterhin angemeldet sein und zustimmen.
  • Refresh-Tokens laufen nie ab und werden nicht rotiert; Tokens werden im Klartext in der Datenbank gespeichert; es gibt keinen Bildschirm zum Widerrufen. Administratoren können ein Token in der Datenbank widerrufen.
  • Der Server schreibt Request-Bodys und Tool-Argumente — einschließlich der Geheimnisse von Credentials — in seine Debug-Ausgabe; ob diese in Logs landet, hängt von Ihrer Bereitstellung ab.
  • Kein Rate Limiting; CORS ist für jeden Origin offen; der veraltete SSE-Transport hält Sitzungen im Arbeitsspeicher und funktioniert nur mit einem einzigen Worker.
JSON-RPC-Endpoint - DQE One Standalone MCP

Der einzige Einstiegspunkt: Senden Sie eine JSON-RPC-Nachricht und erhalten Sie ein JSON-Objekt zurück.

mcpRpc

Anfrage

Senden Sie einen JSON-RPC-2.0-Body. initialize und ping erfordern keine Authentifizierung; alles andere erfordert Basic oder Bearer.

Ein Tool aufrufen: {"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"list_processes","arguments":{}}}. Das Ergebnis ist {"content":[{"type":"text","text":"<JSON as a string>"}]}; bei einem Fehler ist isError true, aber der HTTP-Status bleibt 200.
Fehlercodes: -32700 Parse-Fehler (HTTP 400); -32601 unbekannte Methode oder unbekanntes Tool; -32602 unbekannter Prompt. Nicht autorisiert ist ein HTTP 401 mit einem WWW-Authenticate-Header, der die OAuth-Discovery startet. Es gibt kein Batching, und resources/* ist nicht implementiert.
POSThttps://{DOMAIN}/mcp

Codebeispiele

Eine JSON-RPC-Anfrage senden

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)) }

Parameter

Feld Beschreibung Typ Pflicht / Opt.
jsonrpc
Werte: 2.0
String Pflicht
id Integer Optional
method initialize und ping erfordern keine Authentifizierung. Alle anderen Methoden erfordern sie. resources/* ist nicht implementiert (-32601).
Werte: initialize, ping, tools/list, tools/call, prompts/list, prompts/get
String Pflicht
params Object Optional
Authentifizierung: HTTP Basic (email:api_token) oder ein OAuth-Bearer-Token. Die Konsole unten verwendet Basic.

Antwort

JSON-RPC-Antwort. Ein fehlschlagendes Tool liefert dennoch HTTP 200 mit result.isError = true.. HTTP-Status 200.

Schlüssel Beschreibung Typ
jsonrpc String
id Integer
result Object
error Object

Antwortbeispiel

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

Fehler

HTTP Body / Bedeutung
400 Parse-Fehler (-32700).
401 Nicht autorisiert. Enthält einen Header WWW-Authenticate: Bearer resource_metadata=..., der die OAuth-Discovery auslöst.

API testen

Klicken Sie auf die Schaltfläche unten, um diesen Endpoint live in Ihrem Browser zu testen.

Hinweis: Diese Konsole sendet aus Ihrem Browser eine echte Anfrage an Ihren eigenen Server, mit Ihrem echten API token. tools/call kann Runs starten oder Daten löschen.
Konsole öffnen
Server-Informationen - DQE One Standalone MCP

Gibt grundlegende Server-Informationen ohne Authentifizierung zurück. Mit Accept: text/event-stream wird stattdessen der veraltete SSE-Transport geöffnet (nur Basic-Authentifizierung; einzelner Worker).

mcpInfo

Anfrage

Senden Sie eine GET-Anfrage.

GEThttps://{DOMAIN}/mcp

Codebeispiele

Server-Informationen oder veralteter SSE-Stream

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)) }

Parameter

Dieser Endpoint benötigt keine Parameter.

Authentifizierung: keine — dieser Endpoint ist öffentlich (oder durch ein Token in der URL gesichert, siehe oben).

Antwort

Server-Informationen oder Event-Stream.. HTTP-Status 200.

Antwortbeispiel

Beispielantwort
{ "name": "dqe-one", "version": "1.0.0" }

Fehler

HTTP Body / Bedeutung
Für diesen Endpoint ist keine Fehlerantwort dokumentiert.

API testen

Klicken Sie auf die Schaltfläche unten, um diesen Endpoint live in Ihrem Browser zu testen.

Hinweis: Diese Konsole sendet aus Ihrem Browser eine echte Anfrage an Ihren eigenen Server, mit Ihrem echten API token.
Konsole öffnen
Metadaten der geschützten OAuth-Ressource - DQE One Standalone MCP

RFC-9728-Metadaten, mit denen Clients den Autorisierungsserver ermitteln.

oauthProtectedResource

Anfrage

Senden Sie eine GET-Anfrage.

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

Codebeispiele

Metadaten der geschützten Ressource (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)) }

Parameter

Dieser Endpoint benötigt keine Parameter.

Authentifizierung: keine — dieser Endpoint ist öffentlich (oder durch ein Token in der URL gesichert, siehe oben).

Antwort

{resource, authorization_servers, bearer_methods_supported}. HTTP-Status 200.

Antwortbeispiel

Beispielantwort
{ "resource": "https://{DOMAIN}/mcp", "authorization_servers": [ "https://{DOMAIN}" ], "bearer_methods_supported": [ "header" ] }

Fehler

HTTP Body / Bedeutung
Für diesen Endpoint ist keine Fehlerantwort dokumentiert.

API testen

Klicken Sie auf die Schaltfläche unten, um diesen Endpoint live in Ihrem Browser zu testen.

Hinweis: Diese Konsole sendet aus Ihrem Browser eine echte Anfrage an Ihren eigenen Server, mit Ihrem echten API token.
Konsole öffnen
OAuth-Server-Metadaten - DQE One Standalone MCP

RFC-8414-Metadaten: Endpoints und unterstützte Abläufe.

oauthServerMetadata

Anfrage

Senden Sie eine GET-Anfrage.

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

Codebeispiele

Metadaten des Autorisierungsservers (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)) }

Parameter

Dieser Endpoint benötigt keine Parameter.

Authentifizierung: keine — dieser Endpoint ist öffentlich (oder durch ein Token in der URL gesichert, siehe oben).

Antwort

Endpoints, Grant Types (authorization_code, refresh_token), PKCE S256, Authentifizierungsmethoden none/client_secret_post.. HTTP-Status 200.

Antwortbeispiel

Beispielantwort
{ "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" ] }

Fehler

HTTP Body / Bedeutung
Für diesen Endpoint ist keine Fehlerantwort dokumentiert.

API testen

Klicken Sie auf die Schaltfläche unten, um diesen Endpoint live in Ihrem Browser zu testen.

Hinweis: Diese Konsole sendet aus Ihrem Browser eine echte Anfrage an Ihren eigenen Server, mit Ihrem echten API token.
Konsole öffnen
Einen Client registrieren - DQE One Standalone MCP

Dynamische Client-Registrierung (RFC 7591). Offen: keine Authentifizierung.

oauthRegister

Anfrage

Senden Sie einen JSON-Body mit mindestens redirect_uris.

POSThttps://{DOMAIN}/oauth/register

Codebeispiele

Dynamische Client-Registrierung (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)) }

Parameter

Feld Beschreibung Typ Pflicht / Opt.
redirect_uris Nicht leere Liste von Callback-URLs. Array Pflicht
client_name Wird dem Benutzer auf der Zustimmungsseite angezeigt. String Optional
token_endpoint_auth_method client_secret_post gibt zusätzlich einmalig ein client_secret zurück.
Werte: none, client_secret_post · Standardwert: "none"
String Optional
Authentifizierung: keine — dieser Endpoint ist öffentlich (oder durch ein Token in der URL gesichert, siehe oben).

Antwort

Client registriert (client_secret wird bei client_secret_post einmalig zurückgegeben).. HTTP-Status 201.

Antwortbeispiel

Beispielantwort
{ "client_id": "kQ3...", "client_name": "My connector", "redirect_uris": [ "https://client.example.com/callback" ], "token_endpoint_auth_method": "none" }

Fehler

HTTP Body / Bedeutung
400 Ungültige Anfrage.
Zustimmungsseite - DQE One Standalone MCP

Die Seite, auf der Sie einen Connector genehmigen. Sie wird in einem Browser geöffnet und nicht aus Code aufgerufen. Sie müssen im selben Browser bei DQE One angemeldet sein; PKCE S256 ist verpflichtend; der Code gilt 5 Minuten.

oauthAuthorize

Anfrage

Der Client leitet Ihren Browser auf diese URL weiter.

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}

Beispiel-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

Parameter

Feld Beschreibung Typ Pflicht / Opt.
client_id Von /oauth/register zurückgegebene Client-ID. String Pflicht
redirect_uri Muss exakt mit einer der registrierten Redirect-URIs übereinstimmen. String Pflicht
response_type code (Standard). String Optional
code_challenge PKCE-Challenge. String Pflicht
code_challenge_method Muss S256 sein. String Pflicht
state Opaker Wert, der an den Client zurückgegeben wird. String Optional
Authentifizierung: keine — dieser Endpoint ist öffentlich (oder durch ein Token in der URL gesichert, siehe oben).

Antwort

Zustimmungsseite (Allow / Deny).. HTTP-Status 200.

Antwortbeispiel

Beispielantwort
{ "redirect": "https://client.example.com/callback?code=...&state=xyz" }

Fehler

HTTP Body / Bedeutung
400 Ungültige Anfrage.
Token-Endpoint - DQE One Standalone MCP

Tauscht einen Autorisierungscode gegen Tokens ein oder erneuert ein Access-Token. Das Access-Token gilt 1 Stunde; Refresh-Tokens laufen nicht ab und werden nicht rotiert.

oauthToken

Anfrage

Senden Sie einen formularcodierten POST.

POSThttps://{DOMAIN}/oauth/token

Codebeispiele

Einen Code eintauschen oder ein Token erneuern

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)) }

Parameter

Feld Beschreibung Typ Pflicht / Opt.
grant_type
Werte: authorization_code, refresh_token
String Pflicht
code Autorisierungscode (5 Minuten, einmalig verwendbar). String Optional
redirect_uri Derselbe Wert wie in der Autorisierungsanfrage. String Optional
code_verifier PKCE-Verifier. String Optional
refresh_token Für grant_type refresh_token. String Optional
client_id String Optional
client_secret Nur für Clients, die mit client_secret_post registriert wurden. String Optional
Authentifizierung: keine — dieser Endpoint ist öffentlich (oder durch ein Token in der URL gesichert, siehe oben).

Antwort

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

Antwortbeispiel

Beispielantwort
{ "access_token": "...", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "...", "scope": "" }

Fehler

HTTP Body / Bedeutung
400 invalid_grant / invalid_client.
Upload-Seite - DQE One Standalone MCP

Die Browser-Seite hinter dem Link, den das Tool upload_file zurückgibt. Das Token in der URL ist das einzige Credential.

uploadPage

Anfrage

Sie öffnen den Link in einem Browser.

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

Beispiel-URL

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

Parameter

Feld Beschreibung Typ Pflicht / Opt.
token String Pflicht
Authentifizierung: keine — dieser Endpoint ist öffentlich (oder durch ein Token in der URL gesichert, siehe oben).

Antwort

HTML-Seite.. HTTP-Status 200.

Antwortbeispiel

Beispielantwort
{ "info": "HTML page" }

Fehler

HTTP Body / Bedeutung
Für diesen Endpoint ist keine Fehlerantwort dokumentiert.
Die Datei hochladen - DQE One Standalone MCP

Was die Upload-Seite sendet, wenn Sie eine Datei ablegen. Sie rufen sie normalerweise nie selbst auf.

uploadFile

Anfrage

Ein multipart/form-data-POST mit dem Feld file.

Eine Datei pro Link, 1 Stunde gültig. .csv, .xlsx, .xls; Spaltenüberschriften eindeutig und ohne Leerzeichen. Keine serverseitige Größenbeschränkung.
POSThttps://{DOMAIN}/upload/{token}/

Codebeispiele

Die Datei hochladen

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)) }

Parameter

Feld Beschreibung Typ Pflicht / Opt.
token String Pflicht
file String (file) Pflicht
Authentifizierung: keine — dieser Endpoint ist öffentlich (oder durch ein Token in der URL gesichert, siehe oben).

Antwort

{status: success, file_id, name}. HTTP-Status 200.

Antwortbeispiel

Beispielantwort
{ "status": "success", "file_id": 12, "name": "contacts.csv" }

Fehler

HTTP Body / Bedeutung
400 Falsche Dateiendung, ungültige Spaltenüberschriften oder Link bereits verwendet.

Siehe auch

Verknüpfung mit

War dieser Beitrag hilfreich?

0 von 0 fanden dies hilfreich