Alles, was das Produkt kann, aufrufbar
Das Dashboard ist ein Client einer dokumentierten API. 27 Operationen, eine geschlossene Menge von 83 stabilen Fehlercodes, zwei generierte Clients und ein MCP-Server, der über dieselben Handler arbeitet, statt sie neu zu implementieren.
// VERSIONEN
Die aktuelle API-Version ist v2
v2 ist dieselbe Handler-Gruppe unter der verschachtelten Fehlerhülle, die der Standard dieses Projekts vorschreibt, plus einer nach Berechtigungen gefilterten Fähigkeitenerkennung. Sie ist stabil und hat kein Abschaltdatum.
v2
AktuellVerschachtelte Fehlerhülle, Fähigkeitenerkennung gefiltert nach dem, was Ihre Berechtigung tatsächlich tun darf. Beginnen Sie hier für alles Neue.
v1
VeraltetSeit dem 2026-09-07 veraltet, Abschaltung am 2027-09-07. Sie behält ihre flache Fehlerhülle bis dahin unverändert bei — beide generierten Clients lesen sie direkt, daher wird sie nie an Ort und Stelle verändert. Jede Antwort trägt die Header Deprecation, Sunset und einen Nachfolge-Version-Link.
// CLIENTS
Zwei Clients, aus dem Dokument generiert
Keiner der Clients ist handgeschrieben, und keiner darf abweichen: Ein Build-Gate schlägt fehl, wenn sich das OpenAPI-Dokument ändert und die eingecheckten Clients nicht mitziehen. Die Codebeispiele unten sind Ausschnitte aus den Beispielen, die CI gegen eine laufende API ausführt — es sind also die Aufrufe, die tatsächlich funktionieren, und nicht die, die jemand einmal dokumentiert hat.
@ai-stack-qr/sdkPython ai-stack-qrEine Sache behalten diese Codebeispiele aus ihrer Quelle bei: Die Imports verweisen auf den Client in diesem Repository und nicht auf das veröffentlichte Paket, weil die Datei, die CI ausführt, so geschrieben ist. Ersetzen Sie den Import durch den obigen Paketnamen, und alles andere bleibt unverändert.
import { AiStackQrClient, ApiError } from "../src/index";
const apiKey = process.env["AI_STACK_QR_API_KEY"];
const baseUrl = process.env["AI_STACK_QR_BASE_URL"] ?? "http://localhost:18005";
if (!apiKey) {
console.error("Set AI_STACK_QR_API_KEY to an sk_ key with the write scope.");
process.exit(1);
}
const client = new AiStackQrClient({ apiKey, baseUrl });const created = await client.createQr(
{
payloadType: "url",
payload: { value: "https://example.com/quickstart" },
accessMode: "link",
title: "SDK quickstart",
},
{ idempotencyKey },
);
console.log("created", created.id, created.gate_url);from ai_stack_qr import AiStackQrClient, ApiError # noqa: E402
api_key = os.environ.get("AI_STACK_QR_API_KEY")
base_url = os.environ.get("AI_STACK_QR_BASE_URL", "http://localhost:18005")
if not api_key:
print("Set AI_STACK_QR_API_KEY to an sk_ key with the write scope.", file=sys.stderr)
raise SystemExit(1)
client = AiStackQrClient(api_key=api_key, base_url=base_url)payload = {
"payloadType": "url",
"payload": {"value": "https://example.com/quickstart"},
"accessMode": "link",
"title": "SDK quickstart",
}
created = client.create_qr(body=payload, idempotency_key=idempotency_key)
print("created", created["id"], created["gate_url"])Wiederholungen sind sicher, und eine falsche Wiederholung wird abgelehnt
Senden Sie pro Absicht einen Idempotenz-Schlüssel und verwenden Sie ihn bei jeder Wiederholung dieser Absicht erneut: Die Wiederholung liefert die ursprüngliche Antwort zurück, statt einen zweiten Code zu erzeugen. Denselben Schlüssel mit einem anderen Inhalt zu senden ist ein Client-Fehler, und er wird als solcher beantwortet, statt stillschweigend das Falsche zu tun.
try {
await client.createQr(
{
payloadType: "url",
payload: { value: "https://example.com/different" },
accessMode: "link",
},
{ idempotencyKey },
);
throw new Error("expected a 409 for a reused Idempotency-Key");
} catch (err) {
if (!(err instanceof ApiError) || err.status !== 409) throw err;
console.log("reusing the key for different content was refused:", err.reason);
}// MCP
Ein MCP-Server, der seine eigene Autorisierung erbt
Werkzeuge laufen über die veröffentlichte API zurück, statt Handler neu zu implementieren, sodass Scopes, Mandantenisolation, Ratenlimits, Idempotenz und der Audit-Verlauf für einen Werkzeugaufruf genauso gelten wie für einen HTTP-Aufruf. Es gibt keinen zweiten Codepfad, der synchron gehalten werden muss, und keinen zweiten Ort, an dem eine Berechtigungsprüfung vergessen werden kann.
Scopes, keine Rollen
Ein Schlüssel trägt Aktions-Scopes — 8 an der Zahl. Das Lesen eines Inhalts ist ein eigener Scope und liegt bewusst außerhalb der älteren read/write-Erweiterung, sodass ein älterer Schlüssel an dem Tag, an dem sie ausgeliefert wurde, nie Klartext-Zugriff erhalten hat.
Ablehnungen binden den Agenten
Kein Werkzeug kann einen öffentlichen Code erstellen oder einen bestehenden Zugangsschutz schwächen. Die Ablehnung liegt in der Werkzeugschicht, sodass ein Mensch diese Entscheidung weiterhin im Dashboard treffen kann, während ein automatisierter Aufrufer sie nicht für ihn treffen kann.
Ein festgeschriebener Werkzeugvertrag
Werkzeugnamen, Versionen, erforderliche Argumente, Enum-Werte, Ausgabefelder, Scopes und Wirkungsannotationen werden bei jedem Build mit einem eingecheckten Snapshot verglichen. Die gespeicherte Konfiguration eines Agenten bricht nicht, weil ein Release etwas umbenannt hat.
Die Regeln, die ein Agent vor seinem ersten Aufruf lesen sollte, sind unter /agents.md veröffentlicht, und der Maschinenindex der Website liegt unter /llms.txt.
// VERTRÄGE
Alles oben Genannte ist maschinenlesbar
- /api/v1/openapi.json — der maßgebliche Vertrag. Er hat Vorrang vor allem, was auf dieser Seite geschrieben steht.
- /api/v1/errors — der geschlossene Fehlerkatalog als JSON. Verzweigen Sie auf
code, nie aufmessage. - /agents.md — Vorbedingungen, was abgelehnt wird, wie man einen Fehler liest, wann man stoppt.
- /llms.txt — der Index, dem ein Modell folgt, um den Rest zu finden.