Agent & FastMCP gateway
The gateway is a FastAPI and FastMCP policy layer over the Go API. It does not issue Kibegi JWTs and it does not replace Go authorization. A mutation is rejected before forwarding unless confirm is explicitly true; Go then evaluates the supplied end-user JWT and its normal domain permissions.
FastAPI endpoints
| Method and path | Headers and body | Result |
|---|---|---|
GET /health | No request body. | { "service": "…", "go_api": { "http_status": 200, "response": { … } } }. |
POST /v1/proxy | Optional gateway header Authorization: Bearer <GO_API_SERVICE_TOKEN> when configured, plus the JSON object below. | { "http_status": <downstream status>, "response": <Go JSON or fallback> }. |
FastMCP HTTP /mcp | The configured MCP HTTP transport and ingress authentication. | FastMCP JSON responses for the typed tools below. |
The request model accepted by /v1/proxy is exactly:
{
"method": "POST",
"path": "/api/v1/classes/join/",
"user_token": "<end-user Kibegi access JWT>",
"params": null,
"body": {"class_code":"ABCD12"},
"confirm": true
}method must be one of GET, POST, PUT, PATCH, or DELETE. path must start with an allowlisted migrated /api/v1/ prefix. params is a JSON object of query parameters; body is a JSON object or array; user_token is optional only for downstream public routes. Any non-GET method needs confirm: true. The gateway forwards the user token as Authorization: Bearer <user_token> and adds X-Service-Token when the gateway’s Go service token is configured.
export AGENT_URL="http://127.0.0.1:8091"
export GATEWAY_TOKEN="<gateway ingress token>"
curl --fail-with-body -X POST "$AGENT_URL/v1/proxy" \
-H "Authorization: Bearer $GATEWAY_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"method":"POST",
"path":"/api/v1/classes/join/",
"user_token":"<end-user access JWT>",
"body":{"class_code":"ABCD12"},
"confirm":true
}'Multipart constraint:
api_requestand/v1/proxyforward JSON, not multipart. Use theupload_fileMCP tool for uploads. It base64-decodes content, enforces the Go API’s 50MB limit, and sends multipart fields to Go.
Generic MCP tool
The api_request tool has the same arguments as /v1/proxy:
| Argument | Type | Required | Meaning |
|---|---|---|---|
method | GET | POST | PUT | PATCH | DELETE | Yes | Downstream Go method. |
path | string | Yes | Allowlisted /api/v1/… path with its trailing slash. |
user_token | string or null | No | End-user access JWT for protected downstream paths. |
params | object or null | No | Downstream query parameters. |
body | object, array, or null | No | Downstream JSON body. |
confirm | boolean | No; mandatory for non-GET | Explicit mutation approval. |
For example, an agent can create a share without bypassing Go’s ownership check:
{
"method": "POST",
"path": "/api/v1/sharing/",
"user_token": "<end-user access JWT>",
"body": {"file_code":"ABC123","shared_with_id":42,"message":"Please review"},
"confirm": true
}Typed FastMCP tools and exact arguments
Each typed tool returns the gateway wrapper { "http_status": …, "response": … }, except download_file, which returns base64 transport data on success.
| Tool | Exact arguments | Downstream call |
|---|---|---|
health | None | GET /api/v1/health/ |
search_kibegi | query, user_token | GET /api/v1/search/?q={query} |
list_classes | user_token, optional query | GET /api/v1/classes/; uses search={query} when supplied. |
list_uploads | user_token, optional query | GET /api/v1/uploads/; uses search={query} when supplied. |
get_storage | user_token | GET /api/v1/storage/ |
get_schedule | user_token | GET /api/v1/schedule/calendars/ |
get_ai_status | upload_id, user_token | GET /api/v1/ai/status/{upload_id}/ |
list_notifications | user_token | GET /api/v1/notifications/ |
list_friends | user_token | GET /api/v1/friends/ |
list_shares | user_token | GET /api/v1/sharing/ |
list_marketplace | user_token | GET /api/v1/marketplace/listings/ |
list_library | user_token | GET /api/v1/library/items/ |
list_channels | user_token | GET /api/v1/channel/channels/ |
list_class_comms | class_id, user_token | GET /api/v1/class-comms/classes/{class_id}/contacts/ |
list_assignments | class_id, user_token | GET /api/v1/assignments/classes/{class_id}/ |
list_sms_deliveries | user_token | GET /api/v1/sms/deliveries/ |
upload_file | file_name, content_base64, class_id, user_token, confirm | Multipart POST /api/v1/uploads/ with class_obj, file_name, and file; confirm must be true. |
download_file | file_code, user_token | GET /api/v1/uploads/{file_code}/download/; success returns file_name, content_type, and content_base64. |
An actual upload_file tool call needs base64 without a data-URL prefix:
{
"file_name": "week-01-notes.pdf",
"content_base64": "JVBERi0xLjQK…",
"class_id": "11111111-2222-3333-4444-555555555555",
"user_token": "<end-user access JWT>",
"confirm": true
}Operational rules
The allowlist exposes health, auth, classes, uploads/files, storage, sharing, notifications, friends, schedule and public schedule, marketplace, library, channel and public channel, class communications and public class communications, assignments, AI, search, and SMS. Unknown paths are rejected before an outbound HTTP request. The gateway cannot be used to access private database, Redis, MinIO/S3, or indexer endpoints.
For production, serve /mcp behind TLS and authenticated ingress; set an explicit origin list; log request identifiers and action metadata without persisting user JWTs, file bytes, or provider credentials.