API · 17 operationer
mcp-gateway
Genererad ur services/mcp-gateway/openapi.json, kontraktsversion 0.1.0. Auth-modell och anropare står i atlasen.
GET /healthz
Healthz
| Svar | Beskrivning | Kropp |
|---|---|---|
200 | Successful Response | { [nyckel]: string } application/json |
GET /readyz
Readyz
| Svar | Beskrivning | Kropp |
|---|---|---|
200 | Successful Response | any application/json |
POST /v1/admin/knowledge/preview
Knowledge Preview Endpoint
| Parameter | I | Typ | Krävs |
|---|---|---|---|
authorization | header | string | null | nej |
Kropp: PreviewRequest application/json
| Svar | Beskrivning | Kropp |
|---|---|---|
200 | Successful Response | any application/json |
422 | Validation Error | HTTPValidationError application/json |
GET /v1/admin/mcp-servers
List Servers
List all MCP servers for the tenant.
| Parameter | I | Typ | Krävs |
|---|---|---|---|
authorization | header | string | null | nej |
| Svar | Beskrivning | Kropp |
|---|---|---|
200 | Successful Response | ServerResponse[] application/json |
422 | Validation Error | HTTPValidationError application/json |
POST /v1/admin/mcp-servers
Register
Register a new MCP server and run initial tool discovery. Discovery is part of the create transaction: if the server is unreachable the registration is rolled back and a 503 is returned. This keeps the mcp_servers row consistent with its tools from the start. To register a server that is not yet reachable, the operator must ensure the server is running before calling this endpoint, or use the PATCH + rediscover endpoints after the server comes online.
| Parameter | I | Typ | Krävs |
|---|---|---|---|
authorization | header | string | null | nej |
Kropp: RegisterServerRequest application/json
| Svar | Beskrivning | Kropp |
|---|---|---|
201 | Successful Response | ServerResponse application/json |
422 | Validation Error | HTTPValidationError application/json |
DELETE /v1/admin/mcp-servers/{server_id}
Delete Server
Soft-delete a server: set status=disabled, hide all tools, evict from registry.
| Parameter | I | Typ | Krävs |
|---|---|---|---|
server_id | path | string (uuid) | ja |
authorization | header | string | null | nej |
| Svar | Beskrivning | Kropp |
|---|---|---|
204 | Successful Response | — |
422 | Validation Error | HTTPValidationError application/json |
GET /v1/admin/mcp-servers/{server_id}
Get Server
Get a single MCP server with tools populated.
| Parameter | I | Typ | Krävs |
|---|---|---|---|
server_id | path | string (uuid) | ja |
authorization | header | string | null | nej |
| Svar | Beskrivning | Kropp |
|---|---|---|
200 | Successful Response | ServerResponse application/json |
422 | Validation Error | HTTPValidationError application/json |
PATCH /v1/admin/mcp-servers/{server_id}
Patch Server
Partially update a server's description, status, egress_allowlist, or auth_config.
| Parameter | I | Typ | Krävs |
|---|---|---|---|
server_id | path | string (uuid) | ja |
authorization | header | string | null | nej |
Kropp: PatchServerRequest application/json
| Svar | Beskrivning | Kropp |
|---|---|---|
200 | Successful Response | ServerResponse application/json |
422 | Validation Error | HTTPValidationError application/json |
GET /v1/admin/mcp-servers/{server_id}/grants
List Grants
Serverns behörigheter, med personen bakom varje subjektbunden grant. Tenant-predikatet ligger i SQL på BÅDA leden: `_load_tenant_server` för servern och `AccessGrant.tenant_id` för raderna. Ingen databasinvariant binder de två (`D-70` `Kvarstår 7`), så predikatet ÄR isoleringen här.
| Parameter | I | Typ | Krävs |
|---|---|---|---|
server_id | path | string (uuid) | ja |
authorization | header | string | null | nej |
| Svar | Beskrivning | Kropp |
|---|---|---|
200 | Successful Response | GrantOut[] application/json |
422 | Validation Error | HTTPValidationError application/json |
POST /v1/admin/mcp-servers/{server_id}/grants
Create Grant
Ge en person eller en grupp åtkomst till serverns verktyg (`P19`). **`tenant_id` tas ur `ctx`, aldrig ur bodyn**, och servern laddas med tenant-predikat. Kombinationen "grant för tenant A på tenant B:s server" är därför inte konstruerbar genom ytan — vilket är det enda skyddet som finns, eftersom ingen FK binder de två (`D-70` `Kvarstår 7`). Den sammansatta FK:n är en migrering mot befintliga rader och kräver ett eget vägval. **Auditraden skrivs FÖRE `commit()`**, samma audit-first-invariant som `app/services/tool_call.py`. Kedjan bor i plattforms-databasen och granten i den tenant-lokala, så EN transaktion är fysiskt omöjlig — ordningen är det som gör felfallet fail-closed. Faller skrivningen finns ingen grant, bara ett 500. Motsatt ordning hade lämnat en behörighetsändring utan spår, vilket är precis det den hårda regeln förbjuder. Raden bär den beviljade personens id — aldrig e-posten (GDPR first).
| Parameter | I | Typ | Krävs |
|---|---|---|---|
server_id | path | string (uuid) | ja |
authorization | header | string | null | nej |
Kropp: GrantCreate application/json
| Svar | Beskrivning | Kropp |
|---|---|---|
201 | Successful Response | GrantOut application/json |
422 | Validation Error | HTTPValidationError application/json |
DELETE /v1/admin/mcp-servers/{server_id}/grants/{grant_id}
Delete Grant
Ta tillbaka en behörighet. Hård radering — en grant är ett tillstånd, inte en liggare. Spåret ligger i auditkedjan, som är append-only; raden i `access_grants` behöver inte bära sin egen historik.
| Parameter | I | Typ | Krävs |
|---|---|---|---|
server_id | path | string (uuid) | ja |
grant_id | path | string (uuid) | ja |
authorization | header | string | null | nej |
| Svar | Beskrivning | Kropp |
|---|---|---|
204 | Successful Response | — |
422 | Validation Error | HTTPValidationError application/json |
POST /v1/admin/mcp-servers/{server_id}/rediscover
Rediscover
Trigger tools/list and upsert for an existing server.
| Parameter | I | Typ | Krävs |
|---|---|---|---|
server_id | path | string (uuid) | ja |
authorization | header | string | null | nej |
| Svar | Beskrivning | Kropp |
|---|---|---|
200 | Successful Response | ServerResponse application/json |
422 | Validation Error | HTTPValidationError application/json |
PATCH /v1/admin/mcp-servers/{server_id}/tools/{tool_name}/scope
Update Tool Scope
Update the scope of a single tool on a server.
| Parameter | I | Typ | Krävs |
|---|---|---|---|
server_id | path | string (uuid) | ja |
tool_name | path | string | ja |
authorization | header | string | null | nej |
Kropp: ToolScopeUpdate application/json
| Svar | Beskrivning | Kropp |
|---|---|---|
204 | Successful Response | — |
422 | Validation Error | HTTPValidationError application/json |
GET /v1/admin/tool-usage
Get Tool Usage
Aggregerad verktygsanvändning för anroparens EGEN tenant. `period` är valfri (`YYYY-MM`); utelämnad ⇒ INNEVARANDE MÅNAD (samma default som llm-gatewayens `tenant_usage_report` — Task 6 slår ihop de två halvorna för SAMMA period, så "utelämnad" måste betyda samma sak på båda sidor). Formatfel ⇒ 400: `tool_usage_report` reser `ValueError` (regeln bor i `_month_start_local`, delad logik med SQL-fönstret), och den fångas HÄR — inte en dubblerad regex i routern som kan glida isär från den som faktiskt styr frågan.
| Parameter | I | Typ | Krävs |
|---|---|---|---|
period | query | string | null | nej |
authorization | header | string | null | nej |
| Svar | Beskrivning | Kropp |
|---|---|---|
200 | Successful Response | ToolUsageOut application/json |
422 | Validation Error | HTTPValidationError application/json |
GET /v1/operator/tenants/{tenant_id}/tool-usage
Get Tool Usage For Operator
Samma aggregat som `/v1/admin/tool-usage`, för operatörens fakturakörning (P48). Tenanten är instansens, prövad mot sökvägen i `require_operator_usage_read`. Läsningen auditeras FÖRE svaret: går raden inte att skriva lämnar inga siffror tjänsten (503). Rapporten räknas först, så att ett formatfel på `period` ger 400 utan en auditrad för en läsning som aldrig skedde.
| Parameter | I | Typ | Krävs |
|---|---|---|---|
tenant_id | path | string | ja |
period | query | string | null | nej |
authorization | header | string | null | nej |
| Svar | Beskrivning | Kropp |
|---|---|---|
200 | Successful Response | ToolUsageOut application/json |
422 | Validation Error | HTTPValidationError application/json |
GET /v1/tools
List Tools
| Parameter | I | Typ | Krävs |
|---|---|---|---|
authorization | header | string | null | nej |
| Svar | Beskrivning | Kropp |
|---|---|---|
200 | Successful Response | ToolListResponse application/json |
422 | Validation Error | HTTPValidationError application/json |
POST /v1/tools/call
Call Tool
| Parameter | I | Typ | Krävs |
|---|---|---|---|
authorization | header | string | null | nej |
Kropp: ToolCallRequest application/json
| Svar | Beskrivning | Kropp |
|---|---|---|
200 | Successful Response | ToolCallResponse application/json |
422 | Validation Error | HTTPValidationError application/json |
Scheman
AuthConfig
Registreringens auth_config — STRIKT. Svarsvägen använder `AuthConfigView`. Strikthet hör hemma där ny data kommer in. Läsvägen är tolerant med flit; skälet står i `AuthConfigView`.
| Fält | Typ | Krävs |
|---|---|---|
password_secret_ref | string | null | nej |
token | string | null | nej |
token_secret_ref | string | null | nej |
type | "none" | "bearer" | "basic" | nej |
username_secret_ref | string | null | nej |
AuthConfigView
Svarsvägens auth_config — TOLERANT med flit, till skillnad från `AuthConfig`. Två skäl, båda mätta i `P15`: 1. **Läsvägen får inte 500:a på gammal data.** `AuthConfig` är strikt sedan `P15` (en `bearer` utan källa avvisas). Rader skrivna innan den regeln fanns bryter mot den, och `_to_response*` bygger sitt svar UR raden. En strikt svarsmodell hade gjort registret oläsbart precis när någon försöker städa det. 2. **Modellen har inget `token`-fält.** `AuthConfig` bär ett, för dev-lägets inline-token. Att svarsvägen använder en modell som inte KAN uttrycka en hemlighet är starkare än att komma ihåg att inte fylla i den.
| Fält | Typ | Krävs |
|---|---|---|
password_secret_ref | string | null | nej |
token_secret_ref | string | null | nej |
type | string | nej |
username_secret_ref | string | null | nej |
ClassCountOut
| Fält | Typ | Krävs |
|---|---|---|
calls | integer | ja |
information_class | string | null | ja |
GrantCreate
En ny behörighet: EN person (e-post) eller EN grupp, aldrig båda (`P19`). **Ingen parameter för ett rått `subject`, och det är designen.** `access_grants.subject` är definierad att bära `platform:<auth.users.id>` (`D-99`) och konstrueras av ytan ur ett uppslaget användar-id. En människa som klistrar in en subjektsträng gissar en form som databasens CHECK sedan avvisar — och den CHECK:en är det enda som håller, eftersom modellens motsvarighet är dokumentation utan grind (`D-99` `Kvarstår 3`). `tool_name=None` betyder "alla verktyg på servern" — samma semantik som `app/services/grants.py` läser, inte en ny.
| Fält | Typ | Krävs |
|---|---|---|
group_name | string | null | nej |
scope_cap | "read_only" | "read_write" | "destructive" | nej |
tool_name | string | null | nej |
user_email | string | null | nej |
GrantOut
En grant som den visas för en administratör. `subject` ekas ALDRIG. Det som visas är personen: `user_id` plus den upplösta `user_email`/`user_status`. Är personen inte upplösbar — raderad eller borttagen — är de två `null`, och det är hur en föräldralös grant blir SYNLIG i stället för att tyst ligga kvar (`P19`). `group_mapped` gör samma sak för grupper (`P59`): `false` när tenanten saknar mappning för gruppen, så granten aldrig kan matcha; `null` för en person-grant.
| Fält | Typ | Krävs |
|---|---|---|
created_at | string | ja |
group_mapped | boolean | null | ja |
group_name | string | null | ja |
id | string (uuid) | ja |
scope_cap | string | ja |
tool_name | string | null | ja |
user_email | string | null | ja |
user_id | string (uuid) | null | ja |
user_status | string | null | ja |
GroupCountOut
| Fält | Typ | Krävs |
|---|---|---|
calls | integer | ja |
group | string | ja |
HTTPValidationError
| Fält | Typ | Krävs |
|---|---|---|
detail | ValidationError[] | nej |
PatchServerRequest
| Fält | Typ | Krävs |
|---|---|---|
auth_config | AuthConfig | null | nej |
description | string | null | nej |
egress_allowlist | string[] | null | nej |
identity_mode | "service" | "delegated" | null | nej |
status | "active" | "disabled" | null | nej |
PreviewRequest
K3-requestet. extra='forbid': platform_context är gateway-konstruerat (K1) — ett caller-angivet fält (t.ex. platform_context) ska 422:a, inte tyst ignoreras eller skugga gatewayens egen kontext.
| Fält | Typ | Krävs |
|---|---|---|
collection_id | string (uuid) | ja |
include_drafts | boolean | nej |
question | string | ja |
RegisterServerRequest
| Fält | Typ | Krävs |
|---|---|---|
auth_config | AuthConfig | nej |
description | string | null | nej |
egress_allowlist | string[] | nej |
endpoint | string | ja |
identity_mode | "service" | "delegated" | nej |
name | string | ja |
transport | "sse" | "http" | ja |
ServerResponse
| Fält | Typ | Krävs |
|---|---|---|
auth_config | AuthConfigView | ja |
description | string | null | ja |
egress_allowlist | string[] | ja |
endpoint | string | ja |
id | string (uuid) | ja |
identity_mode | string | ja |
name | string | ja |
status | string | ja |
tenant_id | string (uuid) | ja |
tools | ToolInfo[] | nej |
transport | string | ja |
version | integer | ja |
ToolCallRequest
| Fält | Typ | Krävs |
|---|---|---|
assistant_id | string (uuid) | ja |
tool_args | object | nej |
tool_name | string | ja |
trace_id | string | ja |
ToolCallResponse
| Fält | Typ | Krävs |
|---|---|---|
audit_event_id | string (uuid) | ja |
result | any | ja |
ToolCountOut
| Fält | Typ | Krävs |
|---|---|---|
calls | integer | ja |
tool_name | string | ja |
ToolDescriptor
| Fält | Typ | Krävs |
|---|---|---|
description | string | null | nej |
input_schema | object | ja |
name | string | ja |
scope | string | ja |
ToolInfo
| Fält | Typ | Krävs |
|---|---|---|
description | string | null | nej |
scope | string | ja |
status | string | ja |
timeout_ms | integer | ja |
tool_name | string | ja |
tool_schema | object | ja |
ToolListResponse
| Fält | Typ | Krävs |
|---|---|---|
tools | ToolDescriptor[] | ja |
ToolScopeUpdate
| Fält | Typ | Krävs |
|---|---|---|
scope | "read_only" | "read_write" | "destructive" | ja |
tool_name | string | ja |
ToolUsageOut
| Fält | Typ | Krävs |
|---|---|---|
by_group | GroupCountOut[] | ja |
by_information_class | ClassCountOut[] | ja |
by_tool | ToolCountOut[] | ja |
oldest_classified_at | string (date-time) | null | ja |
period | string | null | ja |
tenant_id | string | ja |
total_calls | integer | ja |
turns | integer | ja |
ValidationError
| Fält | Typ | Krävs |
|---|---|---|
ctx | object | nej |
input | any | nej |
loc | string | integer[] | ja |
msg | string | ja |
type | string | ja |