{ "openapi": "3.1.0", "info": { "title": "Bodhi App - Management API", "description": "API documentation for Bodhi App.\n\n## Authentication Methods\n\nBodhi App supports three sophisticated authentication methods:\n\n### 1. API Token Authentication (Recommended for API access)\n- **Method**: Bearer token in Authorization header\n- **Format**: `Authorization: Bearer bodhiapp_`\n- **Obtain**: Create via web interface at Menu > Settings > API Tokens\n- **Scopes**: Token-based scopes with hierarchical permissions\n - `scope_token_user`: Basic API access (read operations, OpenAI/Ollama APIs)\n - `scope_token_power_user`: Advanced operations (model creation, downloads)\n - `scope_token_manager`: User management operations\n - `scope_token_admin`: Full administrative access\n- **Usage**: Best for programmatic access, CI/CD, and external integrations\n\n### 2. Session Authentication (Browser-based)\n- **Method**: HTTP cookies (automatic for browsers)\n- **Login**: Initiate via `POST /bodhi/v1/auth/initiate`\n- **Callback**: Complete via `POST /bodhi/v1/auth/callback`\n- **Roles**: Resource-based roles with hierarchical permissions\n - `resource_user`: Basic authenticated access\n - `resource_power_user`: Advanced operations\n - `resource_manager`: User management (session-only)\n - `resource_admin`: Full administration (session-only)\n- **Usage**: Best for web browsers and interactive applications\n- **Session-Only Operations**: Some sensitive operations (token management, settings, user management) require session authentication only for security\n\n### 3. OAuth 2.1 Token Exchange (External integrations)\n- **Method**: Bearer token with exchanged OAuth credentials\n- **Format**: `Authorization: Bearer `\n- **Scopes**: User-based scopes via OAuth 2.1 token exchange\n - `scope_user_user`: Basic user access via OAuth exchange\n - `scope_user_power_user`: Advanced user operations via OAuth exchange \n - `scope_user_manager`: Manager operations via OAuth exchange\n - `scope_user_admin`: Admin operations via OAuth exchange\n- **Usage**: For external OAuth 2.1 providers integrating with Bodhi\n\n## Authorization Hierarchy\n\n**Permission Hierarchy** (higher levels include all lower permissions):\n```\nAdmin > Manager > PowerUser > User\n```\n\n**Scope/Role Mapping**:\n| Permission Level | API Token Scope | OAuth User Scope | Session Role |\n|------------------|----------------|------------------|-------------|\n| User | `scope_token_user` | `scope_user_user` | `resource_user` |\n| PowerUser | `scope_token_power_user` | `scope_user_power_user` | `resource_power_user` |\n| Manager | `scope_token_manager` | `scope_user_manager` | `resource_manager` |\n| Admin | `scope_token_admin` | `scope_user_admin` | `resource_admin` |\n\n## Endpoint Access Patterns\n\n- **Public Endpoints**: No authentication required (ping, health, app_info, setup)\n- **Optional Auth Endpoints**: Work with or without authentication, providing different data (user_info)\n- **Multi-Auth Endpoints**: Accept any of the three authentication methods (most API endpoints)\n- **Session-Only Endpoints**: Require browser session authentication only:\n - Token management (`/bodhi/v1/tokens/*`) - PowerUser+ session required\n - Settings management (`/bodhi/v1/settings/*`) - Admin session required \n - User management (`/bodhi/v1/users/*`) - Manager+ session required\n\n## Security Examples\n\n### API Token Usage:\n```bash\ncurl -H \"Authorization: Bearer bodhiapp_1234567890abcdef\" \\\n https://api.example.com/v1/models\n```\n\n### Session Authentication:\n```bash\n# Login first\ncurl -X POST https://api.example.com/bodhi/v1/auth/initiate \\\n -H \"Content-Type: application/json\" \\\n -d '{\"provider\": \"github\"}'\n\n# Then use session cookie automatically\ncurl https://api.example.com/v1/models \\\n --cookie-jar cookies.txt --cookie cookies.txt\n```\n\n### OAuth 2.1 Token Exchange:\n```bash\ncurl -H \"Authorization: Bearer \" \\\n https://api.example.com/v1/models\n```\n\n## Security Best Practices\n\n1. **Use HTTPS**: Always use HTTPS in production\n2. **Scope Principle**: Request minimal required scopes/roles\n3. **Token Rotation**: Regularly rotate API tokens\n4. **Session Security**: Session-only operations prevent token-based access to sensitive functions\n5. **Hierarchical Permissions**: Higher roles automatically include lower role permissions\n", "contact": { "name": "Bodhi API Support", "url": "https://github.com/BodhiSearch/BodhiApp/issues", "email": "support@getbodhi.app" }, "license": { "name": "" }, "version": "0.0.52-dev" }, "servers": [ { "url": "http://localhost:1135", "description": "Local running instance" } ], "paths": { "/bodhi/v1/access-requests": { "get": { "tags": [ "auth" ], "summary": "List All Access Requests", "description": "List all access requests regardless of status. Requires manager or admin role.", "operationId": "listAllAccessRequests", "parameters": [ { "name": "page", "in": "query", "description": "Page number (1-based indexing)", "required": false, "schema": { "type": "integer", "minimum": 0 } }, { "name": "page_size", "in": "query", "description": "Number of items to return per page (maximum 100)", "required": false, "schema": { "type": "integer", "minimum": 0 } }, { "name": "sort", "in": "query", "description": "Field to sort by. Common values: repo, filename, size, updated_at, snapshot, created_at", "required": false, "schema": { "type": "string" } }, { "name": "sort_order", "in": "query", "description": "Sort order: 'asc' for ascending, 'desc' for descending", "required": false, "schema": { "type": "string" } } ], "responses": { "200": { "description": "All requests retrieved", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PaginatedUserAccessResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "session_auth": [ "resource_manager" ] } ] } }, "/bodhi/v1/access-requests/pending": { "get": { "tags": [ "auth" ], "summary": "List Pending Access Requests", "description": "List all pending access requests. Requires manager or admin role.", "operationId": "listPendingAccessRequests", "parameters": [ { "name": "page", "in": "query", "description": "Page number (1-based indexing)", "required": false, "schema": { "type": "integer", "minimum": 0 } }, { "name": "page_size", "in": "query", "description": "Number of items to return per page (maximum 100)", "required": false, "schema": { "type": "integer", "minimum": 0 } }, { "name": "sort", "in": "query", "description": "Field to sort by. Common values: repo, filename, size, updated_at, snapshot, created_at", "required": false, "schema": { "type": "string" } }, { "name": "sort_order", "in": "query", "description": "Sort order: 'asc' for ascending, 'desc' for descending", "required": false, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Pending requests retrieved", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PaginatedUserAccessResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "session_auth": [ "resource_manager" ] } ] } }, "/bodhi/v1/access-requests/{id}/approve": { "put": { "tags": [ "auth" ], "summary": "Approve Access Request", "description": "Approve access request with tool instance selections. Requires session auth.", "operationId": "approveAppsAccessRequest", "parameters": [ { "name": "id", "in": "path", "description": "Access request ID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "description": "Approval details with tool selections", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApproveAccessRequest" } } }, "required": true }, "responses": { "200": { "description": "Request approved", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AccessRequestActionResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "409": { "description": "Already processed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "session_auth": [] } ] }, "post": { "tags": [ "auth" ], "summary": "Approve Access Request", "description": "Approve an access request and assign a role. Requires manager or admin role.", "operationId": "approveAccessRequest", "parameters": [ { "name": "id", "in": "path", "description": "Access request ID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "description": "Role to assign to the user", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApproveUserAccessRequest" } } }, "required": true }, "responses": { "200": { "description": "Request approved successfully" }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "Request not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "session_auth": [ "resource_manager" ] } ] } }, "/bodhi/v1/access-requests/{id}/deny": { "post": { "tags": [ "auth" ], "summary": "Deny Access Request", "description": "Deny access request. Requires session auth.", "operationId": "denyAccessRequest", "parameters": [ { "name": "id", "in": "path", "description": "Access request ID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Request denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AccessRequestActionResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "409": { "description": "Already processed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "session_auth": [] } ] } }, "/bodhi/v1/access-requests/{id}/reject": { "post": { "tags": [ "auth" ], "summary": "Reject Access Request", "description": "Reject an access request. Requires manager or admin role.", "operationId": "rejectAccessRequest", "parameters": [ { "name": "id", "in": "path", "description": "Access request ID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Request rejected successfully" }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "Request not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "session_auth": [ "resource_manager" ] } ] } }, "/bodhi/v1/access-requests/{id}/review": { "get": { "tags": [ "auth" ], "summary": "Get Access Request Review", "description": "Get full access request details for review page. Returns data regardless of status. Requires session auth.", "operationId": "getAccessRequestReview", "parameters": [ { "name": "id", "in": "path", "description": "Access request ID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Review data retrieved", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AccessRequestReviewResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "410": { "description": "Request expired", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "session_auth": [] } ] } }, "/bodhi/v1/apps/access-requests/{id}": { "get": { "tags": [ "auth" ], "summary": "Get Access Request Status", "description": "Poll access request status. Requires app_client_id query parameter for security.", "operationId": "getAccessRequestStatus", "parameters": [ { "name": "id", "in": "path", "description": "Access request ID", "required": true, "schema": { "type": "string" } }, { "name": "app_client_id", "in": "query", "description": "App client ID for verification", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Status retrieved", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AccessRequestStatusResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "Not found or app_client_id mismatch", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ {} ] } }, "/bodhi/v1/apps/mcps": { "get": { "tags": [ "apps" ], "summary": "List MCP instances accessible to the authenticated external app", "operationId": "appsListMcps", "responses": { "200": { "description": "List of MCP instances accessible to the external app", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListMcpsResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer_oauth_token": [] } ] } }, "/bodhi/v1/apps/mcps/{id}": { "get": { "tags": [ "apps" ], "summary": "Get a specific MCP instance by ID via external app", "operationId": "appsGetMcp", "parameters": [ { "name": "id", "in": "path", "description": "MCP instance UUID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "MCP instance", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Mcp" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "MCP not found" }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer_oauth_token": [] } ] } }, "/bodhi/v1/apps/mcps/{id}/mcp": { "post": { "tags": [ "mcps" ], "summary": "Transparent MCP proxy endpoint", "description": "Forwards MCP Streamable HTTP requests (POST/GET/DELETE) to upstream MCP server with auth injection", "operationId": "mcpProxy", "parameters": [ { "name": "id", "in": "path", "description": "MCP instance UUID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Upstream response forwarded" }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer_oauth_token": [] } ] } }, "/bodhi/v1/apps/request-access": { "post": { "tags": [ "auth" ], "summary": "Create Access Request", "description": "Create an access request for an app to access user resources. Always creates a draft for user review. Unauthenticated endpoint.", "operationId": "createAccessRequest", "requestBody": { "description": "Access request details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateAccessRequest" } } }, "required": true }, "responses": { "201": { "description": "Access request created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateAccessRequestResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "App client not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ {} ] } }, "/bodhi/v1/auth/callback": { "post": { "tags": [ "auth" ], "summary": "Complete OAuth Authentication", "description": "Completes the OAuth authentication flow by exchanging authorization code for tokens and establishing user session.", "operationId": "completeOAuthFlow", "requestBody": { "description": "OAuth callback parameters from authorization server", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AuthCallbackRequest" }, "example": { "code": "auth_code_123", "state": "random_state_456" } } }, "required": true }, "responses": { "200": { "description": "OAuth flow completed successfully, user authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RedirectResponse" }, "example": { "location": "https://app.example.com/dashboard" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "422": { "description": "OAuth error, invalid request parameters, or state mismatch", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" }, "example": { "error": { "code": "oauth_state_mismatch", "message": "State parameter mismatch", "type": "invalid_request_error" } } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ {}, { "bearer_api_token": [] }, { "bearer_oauth_token": [] }, { "session_auth": [] } ] } }, "/bodhi/v1/auth/dashboard/callback": { "post": { "tags": [ "auth" ], "summary": "Complete Dashboard OAuth Authentication", "description": "Completes the dashboard OAuth authentication flow by exchanging authorization code for tokens.", "operationId": "completeDashboardOAuthFlow", "requestBody": { "description": "OAuth callback parameters from authorization server", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AuthCallbackRequest" } } }, "required": true }, "responses": { "200": { "description": "Dashboard OAuth flow completed successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RedirectResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ {}, { "bearer_api_token": [] }, { "bearer_oauth_token": [] }, { "session_auth": [] } ] } }, "/bodhi/v1/auth/dashboard/initiate": { "post": { "tags": [ "auth" ], "summary": "Initiate Dashboard OAuth Authentication", "description": "Initiates the dashboard OAuth authentication flow using the multi-tenant client. Only available in multi-tenant mode.", "operationId": "initiateDashboardOAuthFlow", "requestBody": { "content": { "application/json": { "schema": { "default": null } } }, "required": true }, "responses": { "200": { "description": "User already has a valid dashboard token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RedirectResponse" } } } }, "201": { "description": "OAuth authorization URL provided for dashboard login", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RedirectResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ {}, { "bearer_api_token": [] }, { "bearer_oauth_token": [] }, { "session_auth": [] } ] } }, "/bodhi/v1/auth/initiate": { "post": { "tags": [ "auth" ], "summary": "Initiate OAuth Authentication", "description": "Initiates OAuth authentication flow. Returns OAuth authorization URL for unauthenticated users or home page URL for already authenticated users.", "operationId": "initiateOAuthFlow", "requestBody": { "description": "OAuth initiate parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AuthInitiateRequest" } } }, "required": true }, "responses": { "200": { "description": "User already authenticated, home page URL provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RedirectResponse" }, "example": { "location": "https://app.example.com/dashboard" } } } }, "201": { "description": "User not authenticated, OAuth authorization URL provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RedirectResponse" }, "example": { "location": "https://auth.example.com/auth?client_id=bodhi&redirect_uri=..." } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ {}, { "bearer_api_token": [] }, { "bearer_oauth_token": [] }, { "session_auth": [] } ] } }, "/bodhi/v1/info": { "get": { "tags": [ "system" ], "summary": "Get Application Information", "description": "Retrieves current application version and status information including setup state", "operationId": "getAppInfo", "responses": { "200": { "description": "Application information retrieved successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AppInfo" }, "example": { "client_id": "my-client-id", "commit_sha": "abc1234", "deployment": "standalone", "status": "ready", "url": "https://example.com", "version": "0.1.0" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } } } }, "/bodhi/v1/logout": { "post": { "tags": [ "auth" ], "summary": "Logout User", "description": "Logs out the current user by destroying their session and returns redirect URL to login page", "operationId": "logoutUser", "responses": { "200": { "description": "User logged out successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RedirectResponse" }, "example": { "location": "https://app.example.com/login" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } } } }, "/bodhi/v1/mcps": { "get": { "tags": [ "mcps" ], "summary": "List all MCP instances for the authenticated user", "operationId": "listMcps", "responses": { "200": { "description": "List of user's MCP instances", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListMcpsResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer": [] } ] }, "post": { "tags": [ "mcps" ], "summary": "Create a new MCP instance", "operationId": "createMcp", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/McpRequest" } } }, "required": true }, "responses": { "201": { "description": "MCP created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Mcp" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer": [] } ] } }, "/bodhi/v1/mcps/auth-configs": { "get": { "tags": [ "mcps" ], "summary": "List all auth configs for an MCP server (headers + OAuth configs)", "operationId": "listMcpAuthConfigs", "parameters": [ { "name": "mcp_server_id", "in": "query", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "List of auth configs", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/McpAuthConfigsListResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer": [] } ] }, "post": { "tags": [ "mcps" ], "summary": "Create a new auth config (header, OAuth pre-registered, or OAuth dynamic)", "operationId": "createMcpAuthConfig", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateAuthConfig" } } }, "required": true }, "responses": { "201": { "description": "Auth config created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/McpAuthConfigResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer": [] } ] } }, "/bodhi/v1/mcps/auth-configs/{id}": { "get": { "tags": [ "mcps" ], "summary": "Get an auth config by ID", "operationId": "getMcpAuthConfig", "parameters": [ { "name": "id", "in": "path", "description": "Auth config UUID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Auth config", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/McpAuthConfigResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "Not found" }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer": [] } ] }, "delete": { "tags": [ "mcps" ], "summary": "Delete an auth config by ID (cascades to tokens if OAuth)", "operationId": "deleteMcpAuthConfig", "parameters": [ { "name": "id", "in": "path", "description": "Auth config UUID", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Auth config deleted" }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "Not found" }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer": [] } ] } }, "/bodhi/v1/mcps/auth-configs/{id}/login": { "post": { "tags": [ "mcps" ], "summary": "Initiate OAuth login for a config", "operationId": "mcpOAuthLogin", "parameters": [ { "name": "id", "in": "path", "description": "Auth config UUID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OAuthLoginRequest" } } }, "required": true }, "responses": { "200": { "description": "Authorization URL", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OAuthLoginResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "Auth config not found" }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer": [] } ] } }, "/bodhi/v1/mcps/auth-configs/{id}/token": { "post": { "tags": [ "mcps" ], "summary": "Exchange authorization code for tokens", "operationId": "mcpOAuthTokenExchange", "parameters": [ { "name": "id", "in": "path", "description": "Auth config UUID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OAuthTokenExchangeRequest" } } }, "required": true }, "responses": { "200": { "description": "Token stored", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OAuthTokenResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "Auth config not found" }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer": [] } ] } }, "/bodhi/v1/mcps/oauth-tokens/{token_id}": { "get": { "tags": [ "mcps" ], "summary": "Get an OAuth token by ID", "operationId": "getMcpOAuthToken", "parameters": [ { "name": "token_id", "in": "path", "description": "OAuth token UUID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "OAuth token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OAuthTokenResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "Not found" }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer": [] } ] }, "delete": { "tags": [ "mcps" ], "summary": "Delete an OAuth token by ID", "operationId": "deleteMcpOAuthToken", "parameters": [ { "name": "token_id", "in": "path", "description": "OAuth token UUID", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "OAuth token deleted" }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "Not found" }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer": [] } ] } }, "/bodhi/v1/mcps/oauth/discover-as": { "post": { "tags": [ "mcps" ], "summary": "Discover OAuth metadata from an authorization server URL (RFC 8414)", "operationId": "mcpOAuthDiscoverAs", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OAuthDiscoverAsRequest" } } }, "required": true }, "responses": { "200": { "description": "OAuth discovery metadata", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OAuthDiscoverAsResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer": [] } ] } }, "/bodhi/v1/mcps/oauth/discover-mcp": { "post": { "tags": [ "mcps" ], "summary": "Discover OAuth metadata from an MCP server URL (RFC 9728 + RFC 8414)", "operationId": "mcpOAuthDiscoverMcp", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OAuthDiscoverMcpRequest" } } }, "required": true }, "responses": { "200": { "description": "MCP OAuth discovery metadata", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OAuthDiscoverMcpResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer": [] } ] } }, "/bodhi/v1/mcps/oauth/dynamic-register": { "post": { "tags": [ "mcps" ], "summary": "Standalone dynamic client registration (no server_id required)", "operationId": "mcpOAuthDynamicRegisterStandalone", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DynamicRegisterRequest" } } }, "required": true }, "responses": { "200": { "description": "Dynamic client registration result", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DynamicRegisterResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer": [] } ] } }, "/bodhi/v1/mcps/servers": { "get": { "tags": [ "mcps" ], "summary": "List MCP servers, optionally filtered by enabled status", "operationId": "listMcpServers", "parameters": [ { "name": "enabled", "in": "query", "description": "Filter by enabled status", "required": false, "schema": { "type": "boolean" } } ], "responses": { "200": { "description": "List of MCP servers", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListMcpServersResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer": [] } ] }, "post": { "tags": [ "mcps" ], "summary": "Create a new MCP server entry (admin/manager only)", "operationId": "createMcpServer", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/McpServerRequest" } } }, "required": true }, "responses": { "201": { "description": "MCP server created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/McpServerResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "409": { "description": "URL already exists" }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer": [] } ] } }, "/bodhi/v1/mcps/servers/{id}": { "get": { "tags": [ "mcps" ], "summary": "Get a specific MCP server by ID", "operationId": "getMcpServer", "parameters": [ { "name": "id", "in": "path", "description": "MCP server UUID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "MCP server", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/McpServerResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "Not found" }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer": [] } ] }, "put": { "tags": [ "mcps" ], "summary": "Update an existing MCP server entry (admin/manager only)", "operationId": "updateMcpServer", "parameters": [ { "name": "id", "in": "path", "description": "MCP server UUID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/McpServerRequest" } } }, "required": true }, "responses": { "200": { "description": "MCP server updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/McpServerResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "Not found" }, "409": { "description": "URL already exists" }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer": [] } ] } }, "/bodhi/v1/mcps/{id}": { "get": { "tags": [ "mcps" ], "summary": "Get a specific MCP instance by ID", "operationId": "getMcp", "parameters": [ { "name": "id", "in": "path", "description": "MCP instance UUID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "MCP instance", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Mcp" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "MCP not found" }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer": [] } ] }, "put": { "tags": [ "mcps" ], "summary": "Update an MCP instance", "operationId": "updateMcp", "parameters": [ { "name": "id", "in": "path", "description": "MCP instance UUID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/McpRequest" } } }, "required": true }, "responses": { "200": { "description": "MCP updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Mcp" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "MCP not found" }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer": [] } ] }, "delete": { "tags": [ "mcps" ], "summary": "Delete an MCP instance", "operationId": "deleteMcp", "parameters": [ { "name": "id", "in": "path", "description": "MCP instance UUID", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "MCP deleted" }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "MCP not found" }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer": [] } ] } }, "/bodhi/v1/models": { "get": { "tags": [ "models" ], "summary": "List All Model Aliases", "description": "Retrieves paginated list of all configured model aliases including user-defined aliases, model aliases, and API provider aliases with filtering and sorting options. Requires any authenticated user (User level permissions or higher).", "operationId": "listAllModels", "parameters": [ { "name": "page", "in": "query", "description": "Page number (1-based indexing)", "required": false, "schema": { "type": "integer", "minimum": 0 } }, { "name": "page_size", "in": "query", "description": "Number of items to return per page (maximum 100)", "required": false, "schema": { "type": "integer", "minimum": 0 } }, { "name": "sort", "in": "query", "description": "Field to sort by. Common values: repo, filename, size, updated_at, snapshot, created_at", "required": false, "schema": { "type": "string" } }, { "name": "sort_order", "in": "query", "description": "Sort order: 'asc' for ascending, 'desc' for descending", "required": false, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Paginated list of model aliases retrieved successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PaginatedAliasResponse" }, "example": { "data": [ { "alias": "llama2:chat", "context_params": [ "--ctx_size", "4096" ], "filename": "llama-2-7b-chat.Q4_K_M.gguf", "repo": "TheBloke/Llama-2-7B-Chat-GGUF", "request_params": { "temperature": 0.7, "top_p": 0.95 }, "snapshot": "abc123", "source": "user" }, { "alias": "TheBloke/Llama-2-7B-Chat-GGUF:Q4_K_M", "filename": "llama-2-7b-chat.Q4_K_M.gguf", "repo": "TheBloke/Llama-2-7B-Chat-GGUF", "snapshot": "abc123", "source": "model" }, { "api_format": "openai", "base_url": "https://api.openai.com/v1", "created_at": "2024-01-01T00:00:00Z", "id": "openai-gpt4", "models": [ "gpt-4", "gpt-3.5-turbo" ], "source": "api", "updated_at": "2024-01-01T00:00:00Z" } ], "page": 1, "page_size": 10, "total": 3 } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer_api_token": [ "scope_token_user" ] }, { "bearer_oauth_token": [ "scope_user_user" ] }, { "session_auth": [ "resource_user" ] } ] } }, "/bodhi/v1/models/alias": { "post": { "tags": [ "models-alias" ], "summary": "Create Alias", "operationId": "models_alias_create", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserAliasRequest" } } }, "required": true }, "responses": { "201": { "description": "Alias created succesfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserAliasResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer_api_token": [ "scope_token_power_user" ] }, { "bearer_oauth_token": [ "scope_user_power_user" ] }, { "session_auth": [ "resource_power_user" ] } ] } }, "/bodhi/v1/models/alias/{id}": { "put": { "tags": [ "models-alias" ], "summary": "Update Alias", "operationId": "models_alias_update", "parameters": [ { "name": "id", "in": "path", "description": "UUID of the alias to update", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserAliasRequest" } } }, "required": true }, "responses": { "200": { "description": "Alias updated succesfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserAliasResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer_api_token": [ "scope_token_power_user" ] }, { "bearer_oauth_token": [ "scope_user_power_user" ] }, { "session_auth": [ "resource_power_user" ] } ] }, "delete": { "tags": [ "models-alias" ], "summary": "Delete a model alias by UUID", "operationId": "models_alias_destroy", "parameters": [ { "name": "id", "in": "path", "description": "UUID of the alias to delete", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Alias deleted successfully" }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "Alias not found" }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer_api_token": [ "scope_token_power_user" ] }, { "bearer_oauth_token": [ "scope_user_power_user" ] }, { "session_auth": [ "resource_power_user" ] } ] } }, "/bodhi/v1/models/alias/{id}/copy": { "post": { "tags": [ "models-alias" ], "summary": "Copy a model alias", "operationId": "models_alias_copy", "parameters": [ { "name": "id", "in": "path", "description": "UUID of the alias to copy", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CopyAliasRequest" } } }, "required": true }, "responses": { "201": { "description": "Alias copied successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserAliasResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "Source alias not found" }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer_api_token": [ "scope_token_power_user" ] }, { "bearer_oauth_token": [ "scope_user_power_user" ] }, { "session_auth": [ "resource_power_user" ] } ] } }, "/bodhi/v1/models/api": { "post": { "tags": [ "models-api" ], "summary": "Create a new API model configuration", "operationId": "createApiModel", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiModelRequest" } } }, "required": true }, "responses": { "201": { "description": "API model created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiAliasResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "409": { "description": "Alias already exists", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer_api_token": [ "scope_token_power_user" ] }, { "bearer_oauth_token": [ "scope_user_power_user" ] }, { "session_auth": [ "resource_power_user" ] } ] } }, "/bodhi/v1/models/api/fetch-models": { "post": { "tags": [ "models-api" ], "summary": "Fetch available models from the API.", "operationId": "fetchApiModels", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FetchModelsRequest" } } }, "required": true }, "responses": { "200": { "description": "Available models", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FetchModelsResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer_api_token": [ "scope_token_power_user" ] }, { "bearer_oauth_token": [ "scope_user_power_user" ] }, { "session_auth": [ "resource_power_user" ] } ] } }, "/bodhi/v1/models/api/formats": { "get": { "tags": [ "models-api" ], "summary": "Get Available API Formats", "description": "Retrieves list of supported API formats/protocols: 'openai' (Chat Completions), 'openai_responses' (Responses API), 'anthropic' (Messages API), 'anthropic_oauth' (Anthropic via OAuth Bearer token), and 'gemini' (Google Gemini).", "operationId": "getApiFormats", "responses": { "200": { "description": "API formats retrieved successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiFormatsResponse" }, "example": { "data": [ "openai", "openai_responses", "anthropic", "anthropic_oauth", "gemini" ] } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer_api_token": [ "scope_token_power_user" ] }, { "bearer_oauth_token": [ "scope_user_power_user" ] }, { "session_auth": [ "resource_power_user" ] } ] } }, "/bodhi/v1/models/api/test": { "post": { "tags": [ "models-api" ], "summary": "Test API connectivity with a prompt.", "operationId": "testApiModel", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TestPromptRequest" } } }, "required": true }, "responses": { "200": { "description": "Test result", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TestPromptResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer_api_token": [ "scope_token_power_user" ] }, { "bearer_oauth_token": [ "scope_user_power_user" ] }, { "session_auth": [ "resource_power_user" ] } ] } }, "/bodhi/v1/models/api/{id}": { "get": { "tags": [ "models-api" ], "summary": "Get API Model Configuration", "description": "Retrieves detailed configuration for a specific API model alias by ID. API keys are masked for security unless explicitly requested.", "operationId": "getApiModel", "parameters": [ { "name": "id", "in": "path", "description": "Unique identifier for the API model alias", "required": true, "schema": { "type": "string" }, "example": "openai-gpt4" } ], "responses": { "200": { "description": "API model configuration retrieved successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiAliasResponse" }, "example": { "api_format": "openai", "base_url": "https://api.openai.com/v1", "has_api_key": true, "id": "openai-gpt4", "models": [ "gpt-4" ] } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "API model with specified ID not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" }, "example": { "error": { "code": "entity_not_found", "message": "API model 'invalid-model' not found", "type": "not_found_error" } } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer_api_token": [ "scope_token_power_user" ] }, { "bearer_oauth_token": [ "scope_user_power_user" ] }, { "session_auth": [ "resource_power_user" ] } ] }, "put": { "tags": [ "models-api" ], "summary": "Update an existing API model configuration", "operationId": "updateApiModel", "parameters": [ { "name": "id", "in": "path", "description": "API model ID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiModelRequest" } } }, "required": true }, "responses": { "200": { "description": "API model updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiAliasResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "API model not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer_api_token": [ "scope_token_power_user" ] }, { "bearer_oauth_token": [ "scope_user_power_user" ] }, { "session_auth": [ "resource_power_user" ] } ] }, "delete": { "tags": [ "models-api" ], "summary": "Delete an API model configuration", "operationId": "deleteApiModel", "parameters": [ { "name": "id", "in": "path", "description": "API model ID", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "API model deleted" }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "API model not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer_api_token": [ "scope_token_power_user" ] }, { "bearer_oauth_token": [ "scope_user_power_user" ] }, { "session_auth": [ "resource_power_user" ] } ] } }, "/bodhi/v1/models/api/{id}/sync-models": { "post": { "tags": [ "models-api" ], "summary": "Sync Models to Cache", "description": "Synchronously fetches models from the external API and populates the cache. This ensures the cache is populated before returning. Primarily used for testing to avoid timing issues.", "operationId": "syncModels", "parameters": [ { "name": "id", "in": "path", "description": "Unique identifier for the API model alias", "required": true, "schema": { "type": "string" }, "example": "openai-gpt4" } ], "responses": { "200": { "description": "Models synced to cache successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiAliasResponse" }, "example": { "api_format": "openai", "base_url": "https://api.openai.com/v1", "created_at": "2024-01-01T00:00:00Z", "forward_all_with_prefix": false, "has_api_key": true, "id": "openai-gpt4", "models": [ "gpt-4", "gpt-3.5-turbo", "gpt-4-turbo" ], "prefix": null, "updated_at": "2024-01-01T00:00:00Z" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "API model not found" }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer_api_token": [ "scope_token_power_user" ] }, { "bearer_oauth_token": [ "scope_user_power_user" ] }, { "session_auth": [ "resource_power_user" ] } ] } }, "/bodhi/v1/models/files": { "get": { "tags": [ "models-files" ], "summary": "List Local Model Files", "description": "Retrieves paginated list of GGUF model files available in the local HuggingFace cache directory with metadata including repository, filename, snapshot ID, and file size. Requires any authenticated user (User level permissions or higher).", "operationId": "listModelFiles", "parameters": [ { "name": "page", "in": "query", "description": "Page number (1-based indexing)", "required": false, "schema": { "type": "integer", "minimum": 0 } }, { "name": "page_size", "in": "query", "description": "Number of items to return per page (maximum 100)", "required": false, "schema": { "type": "integer", "minimum": 0 } }, { "name": "sort", "in": "query", "description": "Field to sort by. Common values: repo, filename, size, updated_at, snapshot, created_at", "required": false, "schema": { "type": "string" } }, { "name": "sort_order", "in": "query", "description": "Sort order: 'asc' for ascending, 'desc' for descending", "required": false, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Local model files retrieved successfully from cache", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PaginatedLocalModelResponse" }, "example": { "data": [ { "filename": "mistral-7b-instruct-v0.1.Q4_K_M.gguf", "repo": "TheBloke/Mistral-7B-Instruct-v0.1-GGUF", "size": 4815162, "snapshot_id": "ab12cd34" } ], "page": 1, "page_size": 10, "total": 1 } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer_api_token": [ "scope_token_user" ] }, { "bearer_oauth_token": [ "scope_user_user" ] }, { "session_auth": [ "resource_user" ] } ] } }, "/bodhi/v1/models/files/pull": { "get": { "tags": [ "models-files" ], "summary": "List Model Download Requests", "description": "Retrieves paginated list of all model download requests with their current status, progress, and metadata. Includes both active downloads and completed/failed requests.", "operationId": "listDownloads", "parameters": [ { "name": "page", "in": "query", "description": "Page number (1-based indexing)", "required": false, "schema": { "type": "integer", "minimum": 0 } }, { "name": "page_size", "in": "query", "description": "Number of items to return per page (maximum 100)", "required": false, "schema": { "type": "integer", "minimum": 0 } }, { "name": "sort", "in": "query", "description": "Field to sort by. Common values: repo, filename, size, updated_at, snapshot, created_at", "required": false, "schema": { "type": "string" } }, { "name": "sort_order", "in": "query", "description": "Sort order: 'asc' for ascending, 'desc' for descending", "required": false, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Model download requests retrieved successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PaginatedDownloadResponse" }, "example": { "data": [ { "created_at": "2024-01-15T10:30:00Z", "filename": "mistral-7b-instruct-v0.1.Q4_K_M.gguf", "id": "download_123", "progress": 45.5, "repo": "TheBloke/Mistral-7B-Instruct-v0.1-GGUF", "status": "downloading", "updated_at": "2024-01-15T10:35:00Z" } ], "page": 1, "page_size": 10, "total": 1 } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer_api_token": [ "scope_token_power_user" ] }, { "bearer_oauth_token": [ "scope_user_power_user" ] }, { "session_auth": [ "resource_power_user" ] } ] }, "post": { "tags": [ "models-files" ], "summary": "Start Model File Download", "description": "Initiates a new model file download from HuggingFace repository. Creates a download request that can be tracked for progress. Returns existing request if download is already in progress.", "operationId": "pullModelFile", "requestBody": { "description": "Model file download specification with repository and filename", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NewDownloadRequest" }, "example": { "filename": "mistral-7b-instruct-v0.1.Q8_0.gguf", "repo": "TheBloke/Mistral-7B-Instruct-v0.1-GGUF" } } }, "required": true }, "responses": { "200": { "description": "Existing download request found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DownloadRequest" }, "example": { "created_at": "2024-11-10T04:52:06.786Z", "error": null, "filename": "mistral-7b-instruct-v0.1.Q8_0.gguf", "id": "550e8400-e29b-41d4-a716-446655440000", "repo": "TheBloke/Mistral-7B-Instruct-v0.1-GGUF", "status": "pending", "updated_at": "2024-11-10T04:52:06.786Z" } } } }, "201": { "description": "Download request created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DownloadRequest" }, "example": { "created_at": "2024-11-10T04:52:06.786Z", "error": null, "filename": "mistral-7b-instruct-v0.1.Q8_0.gguf", "id": "550e8400-e29b-41d4-a716-446655440000", "repo": "TheBloke/Mistral-7B-Instruct-v0.1-GGUF", "status": "pending", "updated_at": "2024-11-10T04:52:06.786Z" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer_api_token": [ "scope_token_power_user" ] }, { "bearer_oauth_token": [ "scope_user_power_user" ] }, { "session_auth": [ "resource_power_user" ] } ] } }, "/bodhi/v1/models/files/pull/{id}": { "get": { "tags": [ "models-files" ], "summary": "Get Download Request Status", "description": "Retrieves the current status and progress information for a specific model download request. Includes download progress, error details, and completion status.", "operationId": "getDownloadStatus", "parameters": [ { "name": "id", "in": "path", "description": "Unique identifier of the download request (UUID format)", "required": true, "schema": { "type": "string" }, "example": "550e8400-e29b-41d4-a716-446655440000" } ], "responses": { "200": { "description": "Download request found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DownloadRequest" }, "example": { "created_at": "2024-11-10T04:52:06.786Z", "error": null, "filename": "mistral-7b-instruct-v0.1.Q8_0.gguf", "id": "550e8400-e29b-41d4-a716-446655440000", "repo": "TheBloke/Mistral-7B-Instruct-v0.1-GGUF", "status": "completed", "updated_at": "2024-01-20T12:00:10Z" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "Download request not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" }, "example": { "error": { "code": "db_error-item_not_found", "message": "item '550e8400-e29b-41d4-a716-446655440000' of type 'download_requests' not found in db", "type": "not_found_error" } } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer_api_token": [ "scope_token_power_user" ] }, { "bearer_oauth_token": [ "scope_user_power_user" ] }, { "session_auth": [ "resource_power_user" ] } ] } }, "/bodhi/v1/models/refresh": { "post": { "tags": [ "models" ], "summary": "Refresh Model Metadata", "description": "Refresh metadata for models. Supports two modes via discriminated request body:\n\n- Bulk async: `{\"source\": \"all\"}` triggers background extraction for all local GGUF models (202 Accepted)\n\n- Single sync: `{\"source\": \"model\", \"repo\": \"...\", \"filename\": \"...\", \"snapshot\": \"...\"}` performs immediate extraction (200 OK)\n\nRequires PowerUser permissions.", "operationId": "refreshModelMetadata", "requestBody": { "description": "Refresh request - either bulk (source='all') or single model (source='model' with identifiers)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RefreshRequest" } } }, "required": true }, "responses": { "200": { "description": "Metadata refreshed successfully (sync mode)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ModelAliasResponse" } } } }, "202": { "description": "Metadata refresh queued in background (bulk mode)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RefreshResponse" }, "example": { "num_queued": "all" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "Model alias not found for specified repo/filename/snapshot" }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "session_auth": [ "resource_power_user" ] } ] } }, "/bodhi/v1/models/{id}": { "get": { "tags": [ "models" ], "summary": "Get Model Alias Details", "description": "Retrieves detailed information for a specific model alias by UUID. Requires any authenticated user (User level permissions or higher).", "operationId": "getAlias", "parameters": [ { "name": "id", "in": "path", "description": "UUID of the alias", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Model alias details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserAliasResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "Alias not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" }, "example": { "error": { "code": "alias_not_found", "message": "Alias 'unknown:model' not found", "type": "not_found_error" } } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "bearer_api_token": [ "scope_token_user" ] }, { "bearer_oauth_token": [ "scope_user_user" ] }, { "session_auth": [ "resource_user" ] } ] } }, "/bodhi/v1/queue": { "get": { "tags": [ "models" ], "summary": "Get Queue Status", "description": "Returns the current status of the metadata refresh queue. Requires PowerUser permissions.", "operationId": "getQueueStatus", "responses": { "200": { "description": "Queue status retrieved successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/QueueStatusResponse" }, "example": { "status": "idle" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "session_auth": [ "resource_power_user" ] } ] } }, "/bodhi/v1/settings": { "get": { "tags": [ "settings" ], "summary": "List Application Settings", "description": "Retrieves all configurable application settings with their current values, default values, sources, and metadata including validation constraints.\n\n**Security Note:** Admin session authentication required for system configuration access.", "operationId": "listSettings", "responses": { "200": { "description": "Application settings retrieved successfully", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/SettingInfo" } }, "example": [ { "current_value": "info", "default_value": "warn", "key": "BODHI_LOG_LEVEL", "metadata": { "options": [ "error", "warn", "info", "debug", "trace" ], "type": "option" }, "source": "environment" }, { "current_value": 1135, "default_value": 1135, "key": "BODHI_PORT", "metadata": { "max": 65535, "min": 1025, "type": "number" }, "source": "default" } ] } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "session_auth": [ "resource_admin" ] } ] } }, "/bodhi/v1/settings/{key}": { "put": { "tags": [ "settings" ], "summary": "Update Application Setting", "description": "Updates the value of a specific application setting. The new value is validated against the setting's constraints and persisted to the application database.\n\n**Security Note:** Admin session authentication required for system configuration changes.", "operationId": "updateSetting", "parameters": [ { "name": "key", "in": "path", "description": "Setting key identifier (e.g., BODHI_LOG_LEVEL, BODHI_PORT)", "required": true, "schema": { "type": "string" }, "example": "BODHI_LOG_LEVEL" } ], "requestBody": { "description": "New setting value", "content": { "application/json": { "schema": { "type": "object", "description": "Request to update a setting value", "required": [ "value" ], "properties": { "value": { "description": "New value for the setting (type depends on setting metadata)" } }, "example": { "value": "debug" } }, "example": { "value": "debug" } } }, "required": true }, "responses": { "200": { "description": "Setting updated successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SettingInfo" }, "example": { "current_value": "debug", "default_value": "warn", "key": "BODHI_LOG_LEVEL", "metadata": { "options": [ "error", "warn", "info", "debug", "trace" ], "type": "option" }, "source": "database" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "Setting not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" }, "example": { "error": { "code": "settings_route_error-not_found", "message": "Setting not found: INVALID_KEY", "type": "not_found_error" } } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "session_auth": [ "resource_admin" ] } ] }, "delete": { "tags": [ "settings" ], "summary": "Reset Setting to Default", "description": "Resets a specific application setting to its default value by removing any custom overrides. Some critical settings like BODHI_HOME cannot be reset.\n\n**Security Note:** Admin session authentication required.", "operationId": "deleteSetting", "parameters": [ { "name": "key", "in": "path", "description": "Setting key identifier to reset to default value", "required": true, "schema": { "type": "string" }, "example": "BODHI_LOG_LEVEL" } ], "responses": { "200": { "description": "Setting reset to default successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SettingInfo" }, "example": { "current_value": "warn", "default_value": "warn", "key": "BODHI_LOG_LEVEL", "metadata": { "options": [ "error", "warn", "info", "debug", "trace" ], "type": "option" }, "source": "default" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "Setting not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" }, "example": { "error": { "code": "settings_route_error-not_found", "message": "Setting not found: INVALID_KEY", "type": "not_found_error" } } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "session_auth": [ "resource_admin" ] } ] } }, "/bodhi/v1/setup": { "post": { "tags": [ "setup" ], "summary": "Setup Application", "description": "Initializes the application with authentication configuration and registers with the auth server", "operationId": "setupApp", "requestBody": { "description": "Application setup configuration", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetupRequest" }, "example": { "description": "My personal AI server", "name": "My Bodhi Server" } } }, "required": true }, "responses": { "200": { "description": "Application setup completed successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetupResponse" }, "example": { "status": "resource_admin" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } } } }, "/bodhi/v1/tenants": { "get": { "tags": [ "tenants" ], "summary": "List Tenants", "description": "Lists all tenants visible to the authenticated dashboard user. Each tenant includes whether it is currently active and whether the user has a valid session for it.", "operationId": "tenantsList", "responses": { "200": { "description": "List of tenants", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TenantListResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ {}, { "bearer_api_token": [] }, { "bearer_oauth_token": [] }, { "session_auth": [] } ] }, "post": { "tags": [ "tenants" ], "summary": "Create Tenant", "description": "Creates a new tenant (Keycloak client) via the Bodhi SPI and registers it locally.", "operationId": "tenantsCreate", "requestBody": { "description": "Tenant creation parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateTenantRequest" } } }, "required": true }, "responses": { "201": { "description": "Tenant created successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateTenantResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ {}, { "bearer_api_token": [] }, { "bearer_oauth_token": [] }, { "session_auth": [] } ] } }, "/bodhi/v1/tenants/{client_id}/activate": { "post": { "tags": [ "tenants" ], "summary": "Activate Tenant", "description": "Sets the given tenant as the active tenant for the current session. The user must already be logged into this tenant.", "operationId": "tenantsActivate", "parameters": [ { "name": "client_id", "in": "path", "description": "The client_id of the tenant to activate", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Tenant activated successfully" }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ {}, { "bearer_api_token": [] }, { "bearer_oauth_token": [] }, { "session_auth": [] } ] } }, "/bodhi/v1/tokens": { "get": { "tags": [ "api-keys" ], "summary": "List API Tokens", "description": "Retrieves paginated list of API tokens owned by the current user. Includes token metadata but not the actual token values for security.\n\n**Security Note:** Session-only authentication required to prevent information disclosure via tokens.", "operationId": "listApiTokens", "parameters": [ { "name": "page", "in": "query", "description": "Page number (1-based indexing)", "required": false, "schema": { "type": "integer", "minimum": 0 } }, { "name": "page_size", "in": "query", "description": "Number of items to return per page (maximum 100)", "required": false, "schema": { "type": "integer", "minimum": 0 } }, { "name": "sort", "in": "query", "description": "Field to sort by. Common values: repo, filename, size, updated_at, snapshot, created_at", "required": false, "schema": { "type": "string" } }, { "name": "sort_order", "in": "query", "description": "Sort order: 'asc' for ascending, 'desc' for descending", "required": false, "schema": { "type": "string" } } ], "responses": { "200": { "description": "List of API tokens", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PaginatedTokenResponse" }, "example": { "data": [ { "created_at": "2024-11-10T04:52:06.786Z", "id": "550e8400-e29b-41d4-a716-446655440000", "name": "Development Token", "status": "active", "token_id": "jwt-token-id-1", "updated_at": "2024-11-10T04:52:06.786Z", "user_id": "user@email.com" }, { "created_at": "2024-11-10T04:52:06.786Z", "id": "660e8400-e29b-41d4-a716-446655440000", "name": "Test Token", "status": "inactive", "token_id": "jwt-token-id-2", "updated_at": "2024-11-10T04:52:06.786Z", "user_id": "user@email.com" } ], "page": 1, "page_size": 10, "total": 2 } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "session_auth": [ "resource_power_user" ] } ] }, "post": { "tags": [ "api-keys" ], "summary": "Create API Token", "description": "Creates a new API token for programmatic access to the API. The token can be used for bearer authentication in API requests. Tokens are scoped based on user role: User role receives scope_token_user (basic access), while Admin/Manager/PowerUser roles receive scope_token_power_user (administrative access).\n\n**Security Note:** Session-only authentication required to prevent token-based privilege escalation.", "operationId": "createApiToken", "requestBody": { "description": "API token creation parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateTokenRequest" }, "example": { "name": "My Integration Token", "scopes": [ "scope_token_user" ] } } }, "required": true }, "responses": { "201": { "description": "API token created successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TokenCreated" }, "example": { "token": "bodhiapp_1234567890abcdef" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "session_auth": [ "resource_power_user" ] } ] } }, "/bodhi/v1/tokens/{id}": { "put": { "tags": [ "api-keys" ], "summary": "Update API Token", "description": "Updates the name and status of an existing API token. Only the token owner can update their tokens. Token values cannot be changed after creation.\n\n**Security Note:** Session-only authentication required to prevent token-based privilege escalation.", "operationId": "updateApiToken", "parameters": [ { "name": "id", "in": "path", "description": "Unique identifier of the API token to update", "required": true, "schema": { "type": "string" }, "example": "550e8400-e29b-41d4-a716-446655440000" } ], "requestBody": { "description": "Token update request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateTokenRequest" }, "example": { "name": "Updated Token Name", "status": "inactive" } } }, "required": true }, "responses": { "200": { "description": "Token updated successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TokenDetail" }, "example": { "created_at": "2024-11-10T04:52:06.786Z", "id": "550e8400-e29b-41d4-a716-446655440000", "name": "Updated Token Name", "status": "inactive", "token_id": "jwt-token-id-1", "updated_at": "2024-11-10T04:52:06.786Z", "user_id": "auth0|123456789" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "Token not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" }, "example": { "error": { "code": "entity_error-not_found", "message": "Token not found", "type": "not_found_error" } } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "session_auth": [ "resource_power_user" ] } ] } }, "/bodhi/v1/user": { "get": { "tags": [ "auth" ], "summary": "Get Current User Information", "description": "Retrieves information about the currently authenticated user. This endpoint supports optional authentication - returns `logged_out` status if not authenticated, or user details with roles/scopes if authenticated via any method (session, API token, or OAuth exchange). Includes `dashboard` object when the user has an active dashboard session.", "operationId": "getCurrentUser", "responses": { "200": { "description": "User information (authenticated or not)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserInfoEnvelope" }, "examples": { "authenticated": { "summary": "Fully authenticated with dashboard", "value": { "auth_status": "logged_in", "dashboard": { "first_name": "Test", "last_name": "User", "user_id": "550e8400-e29b-41d4-a716-446655440000", "username": "user@example.com" }, "role": "resource_admin", "user_id": "550e8400-e29b-41d4-a716-446655440000", "username": "user@example.com" } }, "dashboard_only": { "summary": "Dashboard session only (no tenant login)", "value": { "auth_status": "logged_out", "dashboard": { "first_name": "Test", "last_name": "User", "user_id": "550e8400-e29b-41d4-a716-446655440000", "username": "user@example.com" } } }, "unauthenticated": { "summary": "Unauthenticated request", "value": { "auth_status": "logged_out" } } } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ {}, { "bearer_api_token": [] }, { "bearer_oauth_token": [] }, { "session_auth": [] } ] } }, "/bodhi/v1/user/request-access": { "post": { "tags": [ "auth" ], "summary": "Request User Access", "description": "Authenticated users without roles can request access to the system. Only one pending request is allowed per user.", "operationId": "requestUserAccess", "responses": { "201": { "description": "Access request created successfully" }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "409": { "description": "Pending request already exists", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "422": { "description": "User already has role", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ {}, { "bearer_api_token": [] }, { "bearer_oauth_token": [] }, { "session_auth": [] } ] } }, "/bodhi/v1/user/request-status": { "get": { "tags": [ "auth" ], "summary": "Get Access Request Status", "description": "Check the status of the current user's access request.", "operationId": "getUserAccessStatus", "responses": { "200": { "description": "Request status retrieved", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserAccessStatusResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "Request not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ {}, { "bearer_api_token": [] }, { "bearer_oauth_token": [] }, { "session_auth": [] } ] } }, "/bodhi/v1/users": { "get": { "tags": [ "auth" ], "summary": "List users", "description": "List all users with roles and status information. Available to managers and admins.", "operationId": "listUsers", "parameters": [ { "name": "page", "in": "query", "description": "Page number (1-based)", "required": false, "schema": { "type": "integer", "format": "int32", "minimum": 0 }, "example": 1 }, { "name": "page_size", "in": "query", "description": "Number of users per page", "required": false, "schema": { "type": "integer", "format": "int32", "minimum": 0 }, "example": 10 } ], "responses": { "200": { "description": "Users retrieved successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserListResponse" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "session_auth": [ "resource_manager" ] } ] } }, "/bodhi/v1/users/{user_id}": { "delete": { "tags": [ "auth" ], "summary": "Remove user access", "description": "Remove a user's access to the application. Only managers or above can remove users.", "operationId": "removeUser", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID to remove", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "User removed successfully" }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "User not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "session_auth": [ "resource_manager" ] } ] } }, "/bodhi/v1/users/{user_id}/role": { "put": { "tags": [ "auth" ], "summary": "Change user role", "description": "Assign a new role to a user. Admins can assign any role, managers can assign user/power_user/manager roles.", "operationId": "changeUserRole", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID to change role for", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChangeRoleRequest" } } }, "required": true }, "responses": { "200": { "description": "Role changed successfully" }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "403": { "description": "Insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "404": { "description": "User not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } }, "security": [ { "session_auth": [ "resource_manager" ] } ] } }, "/health": { "get": { "tags": [ "system" ], "summary": "Health Check", "description": "Comprehensive health check to verify all application components are operational", "operationId": "healthCheck", "responses": { "200": { "description": "Application is healthy and fully operational", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PingResponse" }, "example": { "message": "pong" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } } } }, "/ping": { "get": { "tags": [ "system" ], "summary": "Ping Server", "description": "Simple connectivity check to verify the server is responding", "operationId": "pingServer", "responses": { "200": { "description": "Server is responding normally", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PingResponse" }, "example": { "message": "pong" } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BodhiErrorResponse" } } } } } } } }, "components": { "schemas": { "AccessRequestActionResponse": { "type": "object", "required": [ "status", "flow_type" ], "properties": { "status": { "$ref": "#/components/schemas/AppAccessRequestStatus", "description": "Updated status after action" }, "flow_type": { "$ref": "#/components/schemas/FlowType", "description": "Flow type of the access request" }, "redirect_url": { "type": [ "string", "null" ], "description": "Redirect URL (present for redirect flow)" } } }, "AccessRequestReviewResponse": { "type": "object", "required": [ "id", "app_client_id", "flow_type", "status", "requested_role", "requested" ], "properties": { "id": { "type": "string", "description": "Access request ID" }, "app_client_id": { "type": "string", "description": "App client ID" }, "app_name": { "type": [ "string", "null" ], "description": "App name from KC (if available)" }, "app_description": { "type": [ "string", "null" ], "description": "App description from KC (if available)" }, "flow_type": { "$ref": "#/components/schemas/FlowType", "description": "Flow type: \"redirect\" or \"popup\"" }, "status": { "$ref": "#/components/schemas/AppAccessRequestStatus", "description": "Current status" }, "requested_role": { "type": "string", "description": "Role requested by the app" }, "requested": { "$ref": "#/components/schemas/RequestedResources", "description": "Resources requested" }, "mcps_info": { "type": "array", "items": { "$ref": "#/components/schemas/McpServerReviewInfo" }, "description": "MCP server information with user instances" } } }, "AccessRequestStatusResponse": { "type": "object", "required": [ "id", "status", "requested_role" ], "properties": { "id": { "type": "string", "description": "Access request ID" }, "status": { "$ref": "#/components/schemas/AppAccessRequestStatus", "description": "Current status: \"draft\", \"approved\", \"denied\", \"failed\"" }, "requested_role": { "$ref": "#/components/schemas/UserScope", "description": "Role requested by the app" }, "approved_role": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/UserScope", "description": "Role approved (present when approved)" } ] }, "access_request_scope": { "type": [ "string", "null" ], "description": "Access request scope (present when user-approved with tools)" } }, "example": { "access_request_scope": "scope_access_request:550e8400-e29b-41d4-a716-446655440000", "approved_role": "scope_user_user", "id": "550e8400-e29b-41d4-a716-446655440000", "requested_role": "scope_user_user", "status": "approved" } }, "Alias": { "oneOf": [ { "allOf": [ { "$ref": "#/components/schemas/UserAlias", "description": "User-defined local model (source: \"user\")" }, { "type": "object", "required": [ "source" ], "properties": { "source": { "type": "string", "enum": [ "user" ] } } } ], "description": "User-defined local model (source: \"user\")" }, { "allOf": [ { "$ref": "#/components/schemas/ModelAlias", "description": "Auto-discovered local model (source: \"model\")" }, { "type": "object", "required": [ "source" ], "properties": { "source": { "type": "string", "enum": [ "model" ] } } } ], "description": "Auto-discovered local model (source: \"model\")" }, { "allOf": [ { "$ref": "#/components/schemas/ApiAlias", "description": "Remote API model (source: \"api\")" }, { "type": "object", "required": [ "source" ], "properties": { "source": { "type": "string", "enum": [ "api" ] } } } ], "description": "Remote API model (source: \"api\")" } ], "description": "Flat enum representing all types of model aliases\nEach variant is identified by the source field" }, "AliasResponse": { "oneOf": [ { "$ref": "#/components/schemas/UserAliasResponse", "description": "User-defined local model (source: \"user\")" }, { "$ref": "#/components/schemas/ModelAliasResponse", "description": "Auto-discovered local model (source: \"model\")" }, { "$ref": "#/components/schemas/ApiAliasResponse", "description": "Remote API model (source: \"api\")" } ], "description": "Response envelope for model aliases - hides internal implementation details\nUses untagged serialization - each variant has its own \"source\" field" }, "AnthropicModel": { "type": "object", "description": "Mirrors Anthropic's `ModelInfo` schema — full model metadata returned by\n`GET /anthropic/v1/models` and stored alongside model IDs in `ApiAlias.models`.\n\n**IMPORTANT**: Do NOT add `#[serde(skip_serializing_if = \"Option::is_none\")]` on the\n`Option` fields below. The Anthropic API spec marks `capabilities`, `max_input_tokens`,\nand `max_tokens` as **required** (nullable via `anyOf [T, null]`). They must serialize\nas `null` when absent, not be omitted from the JSON output.", "required": [ "id", "display_name", "created_at", "type" ], "properties": { "id": { "type": "string" }, "display_name": { "type": "string" }, "created_at": { "type": "string", "description": "RFC 3339 datetime string representing the model's release date." }, "capabilities": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/AnthropicModelCapabilities" } ] }, "max_input_tokens": { "type": [ "integer", "null" ], "format": "int64" }, "max_tokens": { "type": [ "integer", "null" ], "format": "int64" }, "type": { "type": "string", "description": "Always `\"model\"` — included for Anthropic API compatibility." } } }, "AnthropicModelCapabilities": { "type": "object", "description": "Model capability information (Anthropic ModelCapabilities schema).", "required": [ "batch", "citations", "code_execution", "context_management", "effort", "image_input", "pdf_input", "structured_outputs", "thinking" ], "properties": { "batch": { "$ref": "#/components/schemas/CapabilitySupport" }, "citations": { "$ref": "#/components/schemas/CapabilitySupport" }, "code_execution": { "$ref": "#/components/schemas/CapabilitySupport" }, "context_management": { "$ref": "#/components/schemas/ContextManagementCapability" }, "effort": { "$ref": "#/components/schemas/EffortCapability" }, "image_input": { "$ref": "#/components/schemas/CapabilitySupport" }, "pdf_input": { "$ref": "#/components/schemas/CapabilitySupport" }, "structured_outputs": { "$ref": "#/components/schemas/CapabilitySupport" }, "thinking": { "$ref": "#/components/schemas/ThinkingCapability" } } }, "ApiAlias": { "type": "object", "required": [ "id", "api_format", "base_url", "models", "forward_all_with_prefix", "created_at", "updated_at" ], "properties": { "id": { "type": "string" }, "api_format": { "$ref": "#/components/schemas/ApiFormat" }, "base_url": { "type": "string" }, "models": { "$ref": "#/components/schemas/ApiModelVec" }, "prefix": { "type": [ "string", "null" ] }, "forward_all_with_prefix": { "type": "boolean" }, "extra_headers": {}, "extra_body": {}, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" } } }, "ApiAliasResponse": { "type": "object", "description": "API response for API model aliases - hides internal cache fields", "required": [ "source", "id", "api_format", "base_url", "has_api_key", "models", "forward_all_with_prefix", "created_at", "updated_at" ], "properties": { "source": { "type": "string" }, "id": { "type": "string" }, "api_format": { "$ref": "#/components/schemas/ApiFormat" }, "base_url": { "type": "string" }, "has_api_key": { "type": "boolean" }, "models": { "type": "array", "items": { "$ref": "#/components/schemas/ApiModel" }, "description": "Models available through this alias with full provider metadata" }, "prefix": { "type": [ "string", "null" ] }, "forward_all_with_prefix": { "type": "boolean" }, "extra_headers": {}, "extra_body": {}, "llm_liberty": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/LlmLibertySummary", "description": "Non-secret summary of LLM Liberty OAuth credentials (only present for llm_liberty_oauth format)." } ] }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" } } }, "ApiFormat": { "type": "string", "description": "API format/protocol specification", "enum": [ "openai", "openai_responses", "anthropic", "anthropic_oauth", "gemini", "llm_liberty_oauth" ] }, "ApiFormatsResponse": { "type": "object", "description": "Response containing available API formats", "required": [ "data" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/ApiFormat" } } }, "example": { "data": [ "openai" ] } }, "ApiKey": { "type": [ "string", "null" ], "description": "Validated API key wrapper - validates length when Some, allows None for public APIs" }, "ApiKeyUpdate": { "oneOf": [ { "type": "object", "description": "Keep the existing API key unchanged", "required": [ "action" ], "properties": { "action": { "type": "string", "enum": [ "keep" ] } } }, { "type": "object", "description": "Set a new API key (or add one if none exists) - ApiKey validates length", "required": [ "value", "action" ], "properties": { "value": { "$ref": "#/components/schemas/ApiKey", "description": "Set a new API key (or add one if none exists) - ApiKey validates length" }, "action": { "type": "string", "enum": [ "set" ] } } } ], "description": "Represents an API key update operation for API model aliases." }, "ApiModel": { "oneOf": [ { "allOf": [ { "$ref": "#/components/schemas/Model" }, { "type": "object", "required": [ "provider" ], "properties": { "provider": { "type": "string", "enum": [ "openai" ] } } } ] }, { "allOf": [ { "$ref": "#/components/schemas/AnthropicModel" }, { "type": "object", "required": [ "provider" ], "properties": { "provider": { "type": "string", "enum": [ "anthropic" ] } } } ] }, { "allOf": [ { "$ref": "#/components/schemas/GeminiModel" }, { "type": "object", "required": [ "provider" ], "properties": { "provider": { "type": "string", "enum": [ "gemini" ] } } } ] } ], "description": "Discriminated union of provider-specific model metadata.\nStored as JSON in `api_model_aliases.models`." }, "ApiModelRequest": { "oneOf": [ { "allOf": [ { "$ref": "#/components/schemas/DefaultApiModelRequest" }, { "type": "object", "required": [ "api_format" ], "properties": { "api_format": { "type": "string", "enum": [ "openai" ] } } } ] }, { "allOf": [ { "$ref": "#/components/schemas/DefaultApiModelRequest" }, { "type": "object", "required": [ "api_format" ], "properties": { "api_format": { "type": "string", "enum": [ "openai_responses" ] } } } ] }, { "allOf": [ { "$ref": "#/components/schemas/DefaultApiModelRequest" }, { "type": "object", "required": [ "api_format" ], "properties": { "api_format": { "type": "string", "enum": [ "anthropic" ] } } } ] }, { "allOf": [ { "$ref": "#/components/schemas/DefaultApiModelRequest" }, { "type": "object", "required": [ "api_format" ], "properties": { "api_format": { "type": "string", "enum": [ "anthropic_oauth" ] } } } ] }, { "allOf": [ { "$ref": "#/components/schemas/DefaultApiModelRequest" }, { "type": "object", "required": [ "api_format" ], "properties": { "api_format": { "type": "string", "enum": [ "gemini" ] } } } ] }, { "allOf": [ { "$ref": "#/components/schemas/LlmLibertyApiModelRequest" }, { "type": "object", "required": [ "api_format" ], "properties": { "api_format": { "type": "string", "enum": [ "llm_liberty_oauth" ] } } } ] } ], "description": "Input request for creating or updating an API model configuration.\nDiscriminated by `api_format` — `llm_liberty_oauth` uses `LlmLibertyApiModelRequest`,\nevery other format uses `DefaultApiModelRequest`.", "example": { "api_format": "openai", "api_key": { "action": "set", "value": "sk-..." }, "base_url": "https://api.openai.com/v1", "models": [ "gpt-4", "gpt-3.5-turbo" ], "prefix": "openai" } }, "ApiModelVec": { "type": "array", "items": { "$ref": "#/components/schemas/ApiModel" }, "description": "DB-storable `Vec` — stored as JSON binary in SeaORM columns." }, "AppAccessRequestStatus": { "type": "string", "enum": [ "draft", "approved", "denied", "failed", "expired" ] }, "AppInfo": { "type": "object", "description": "Application information and status", "required": [ "version", "commit_sha", "status", "deployment", "url" ], "properties": { "version": { "type": "string", "description": "Application version number (semantic versioning)", "example": "0.1.0" }, "commit_sha": { "type": "string", "description": "Git commit SHA of the build", "example": "abc1234" }, "status": { "$ref": "#/components/schemas/AppStatus", "description": "Current application setup and operational status" }, "deployment": { "$ref": "#/components/schemas/DeploymentMode", "description": "Deployment mode: \"standalone\" or \"multi_tenant\"" }, "client_id": { "type": [ "string", "null" ], "description": "Active tenant's OAuth client_id (present when authenticated with an active tenant)", "example": "my-client-id" }, "url": { "type": "string", "description": "Public URL of the server", "example": "https://example.com" } }, "example": { "client_id": "my-client-id", "commit_sha": "abc1234", "deployment": "standalone", "status": "ready", "url": "https://example.com", "version": "0.1.0" } }, "AppRole": { "oneOf": [ { "$ref": "#/components/schemas/ResourceRole" }, { "$ref": "#/components/schemas/TokenScope" }, { "$ref": "#/components/schemas/UserScope" } ] }, "AppStatus": { "type": "string", "enum": [ "setup", "ready", "resource_admin" ], "example": "ready" }, "ApprovalStatus": { "type": "string", "enum": [ "approved", "denied" ] }, "ApproveAccessRequest": { "type": "object", "description": "Request for approving an app access request", "required": [ "approved_role", "approved" ], "properties": { "approved_role": { "$ref": "#/components/schemas/UserScope", "description": "Role to grant for the approved request (scope_user_user or scope_user_power_user)" }, "approved": { "$ref": "#/components/schemas/ApprovedResources", "description": "Approved resources with selections" } }, "example": { "approved": { "mcps": [ { "instance": { "id": "instance-uuid", "path": "/bodhi/v1/apps/mcps/instance-uuid/mcp" }, "status": "approved", "url": "https://mcp.deepwiki.com/mcp" } ], "version": "1" }, "approved_role": "scope_user_user" } }, "ApproveUserAccessRequest": { "type": "object", "description": "Request body for approving access with role assignment", "required": [ "role" ], "properties": { "role": { "$ref": "#/components/schemas/ResourceRole", "description": "Role to assign to the user" } }, "example": { "role": "resource_user" } }, "ApprovedResources": { "oneOf": [ { "allOf": [ { "$ref": "#/components/schemas/ApprovedResourcesV1" }, { "type": "object", "required": [ "version" ], "properties": { "version": { "type": "string", "enum": [ "1" ] } } } ] } ], "description": "Versioned envelope for approved resources.\nThe `version` tag is mandatory and must match the corresponding `RequestedResources` version." }, "ApprovedResourcesV1": { "type": "object", "properties": { "mcps": { "type": "array", "items": { "$ref": "#/components/schemas/McpApproval" } } } }, "AuthCallbackRequest": { "type": "object", "properties": { "code": { "type": [ "string", "null" ], "description": "OAuth authorization code from successful authentication (required for success flow)", "example": "auth_code_123" }, "state": { "type": [ "string", "null" ], "description": "OAuth state parameter for CSRF protection (must match initiated request)", "example": "random_state_456" }, "error": { "type": [ "string", "null" ], "description": "OAuth error code if authentication failed (e.g., \"access_denied\")", "example": "access_denied" }, "error_description": { "type": [ "string", "null" ], "description": "Human-readable OAuth error description if authentication failed", "example": "The user denied the request" } }, "additionalProperties": { "type": "string", "description": "Additional OAuth 2.1 parameters sent by the authorization server", "additionalProperties": true }, "example": { "code": "auth_code_123", "state": "random_state_456" } }, "AuthInitiateRequest": { "type": "object", "description": "Request body for initiating OAuth authentication", "required": [ "client_id" ], "properties": { "client_id": { "type": "string", "description": "The OAuth client_id of the tenant to authenticate with", "example": "my-client-id" } }, "example": { "client_id": "my-client-id" } }, "BodhiError": { "type": "object", "required": [ "message", "type" ], "properties": { "message": { "type": "string", "description": "Human-readable error message describing what went wrong", "example": "Validation failed: name is required" }, "type": { "type": "string", "description": "Error type categorizing the kind of error that occurred", "example": "invalid_request_error" }, "code": { "type": [ "string", "null" ], "description": "Specific error code for programmatic error handling", "example": "validation_error" }, "params": { "type": [ "object", "null" ], "description": "Additional error parameters as key-value pairs (for validation errors)", "additionalProperties": { "type": "string" }, "propertyNames": { "type": "string" }, "example": { "field": "name", "value": "invalid" } }, "param": { "type": [ "string", "null" ], "description": "JSON-encoded form of `params`. Superset field so clients that speak the\nOpenAI `Error` shape (where `param` is a String) can still read it.\nPopulated automatically from `params` by `BodhiError::new`.", "example": "{\"field\":\"name\",\"value\":\"invalid\"}" } }, "example": { "code": "validation_error", "message": "Validation failed: name is required", "param": "{\"field\":\"name\",\"value\":\"invalid\"}", "params": { "field": "name", "value": "invalid" }, "type": "invalid_request_error" } }, "BodhiErrorResponse": { "type": "object", "required": [ "error" ], "properties": { "error": { "$ref": "#/components/schemas/BodhiError", "description": "Error details following Bodhi API error format" } }, "example": { "error": { "code": "validation_error", "message": "Validation failed: name is required", "param": "{\"field\":\"name\"}", "params": { "field": "name" }, "type": "invalid_request_error" } } }, "CapabilitySupport": { "type": "object", "description": "Whether a single capability is supported by the model.", "required": [ "supported" ], "properties": { "supported": { "type": "boolean" } } }, "ChangeRoleRequest": { "type": "object", "description": "Change user role request", "required": [ "role" ], "properties": { "role": { "$ref": "#/components/schemas/ResourceRole", "description": "Role to assign to the user" } } }, "ContextLimits": { "type": "object", "properties": { "max_input_tokens": { "type": [ "integer", "null" ], "format": "int64", "minimum": 0 }, "max_output_tokens": { "type": [ "integer", "null" ], "format": "int64", "minimum": 0 } } }, "ContextManagementCapability": { "type": "object", "description": "Context management capability details.", "properties": { "clear_thinking_20251015": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/CapabilitySupport" } ] }, "clear_tool_uses_20250919": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/CapabilitySupport" } ] }, "compact_20260112": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/CapabilitySupport" } ] } } }, "CopyAliasRequest": { "type": "object", "required": [ "alias" ], "properties": { "alias": { "type": "string" } } }, "CreateAccessRequest": { "type": "object", "description": "Request for creating an app access request", "required": [ "app_client_id", "flow_type", "requested_role", "requested" ], "properties": { "app_client_id": { "type": "string", "description": "App client ID from Keycloak" }, "flow_type": { "$ref": "#/components/schemas/FlowType", "description": "Flow type: \"redirect\" or \"popup\"" }, "redirect_url": { "type": [ "string", "null" ], "description": "Redirect URL for result notification (required for redirect flow)" }, "requested_role": { "$ref": "#/components/schemas/UserScope", "description": "Role requested for the external app (scope_user_user or scope_user_power_user)" }, "requested": { "$ref": "#/components/schemas/RequestedResources", "description": "Resources requested (tools, etc.)" } }, "example": { "app_client_id": "my-app-client", "flow_type": "redirect", "redirect_url": "https://myapp.com/callback", "requested": { "mcp_servers": [ { "url": "https://mcp.example.com/mcp" } ], "version": "1" }, "requested_role": "scope_user_user" } }, "CreateAccessRequestResponse": { "type": "object", "required": [ "id", "status", "review_url" ], "properties": { "id": { "type": "string", "description": "Access request ID" }, "status": { "$ref": "#/components/schemas/AppAccessRequestStatus", "description": "Status (always \"draft\")" }, "review_url": { "type": "string", "description": "Review URL for user to approve/deny" } }, "example": { "id": "550e8400-e29b-41d4-a716-446655440000", "review_url": "http://localhost:1135/ui/apps/access-requests/review?id=550e8400-e29b-41d4-a716-446655440000", "status": "draft" } }, "CreateAuthConfig": { "allOf": [ { "$ref": "#/components/schemas/CreateMcpAuthConfigRequest" }, { "type": "object", "required": [ "mcp_server_id" ], "properties": { "mcp_server_id": { "type": "string" } } } ], "description": "Wrapper for creating auth configs with server_id in body instead of path" }, "CreateMcpAuthConfigRequest": { "oneOf": [ { "type": "object", "required": [ "name", "entries", "type" ], "properties": { "name": { "type": "string" }, "entries": { "type": "array", "items": { "$ref": "#/components/schemas/McpAuthConfigParamInput" } }, "type": { "type": "string", "enum": [ "header" ] } } }, { "type": "object", "required": [ "name", "client_id", "authorization_endpoint", "token_endpoint", "type" ], "properties": { "name": { "type": "string" }, "client_id": { "type": "string" }, "authorization_endpoint": { "type": "string" }, "token_endpoint": { "type": "string" }, "client_secret": { "type": [ "string", "null" ] }, "scopes": { "type": [ "string", "null" ] }, "registration_type": { "$ref": "#/components/schemas/RegistrationType", "description": "`\"pre_registered\"` (default) or `\"dynamic_registration\"`" }, "registration_access_token": { "type": [ "string", "null" ] }, "registration_endpoint": { "type": [ "string", "null" ] }, "token_endpoint_auth_method": { "type": [ "string", "null" ] }, "client_id_issued_at": { "type": [ "integer", "null" ], "format": "int64" }, "type": { "type": "string", "enum": [ "oauth" ] } } } ], "description": "Discriminated union for creating any type of MCP auth config.\nThe JSON `\"type\"` field determines the variant: `\"header\"` or `\"oauth\"`." }, "CreateTenantRequest": { "type": "object", "required": [ "name" ], "properties": { "name": { "type": "string" }, "description": { "type": [ "string", "null" ] } } }, "CreateTenantResponse": { "type": "object", "required": [ "client_id" ], "properties": { "client_id": { "type": "string" } } }, "CreateTokenRequest": { "type": "object", "required": [ "scope" ], "properties": { "name": { "type": [ "string", "null" ], "description": "Descriptive name for the API token", "example": "My Integration Token", "maxLength": 100, "minLength": 0 }, "scope": { "$ref": "#/components/schemas/TokenScope", "description": "Token scope defining access level" } }, "example": { "name": "My Integration Token", "scope": "scope_token_user" } }, "DashboardUser": { "type": "object", "description": "Dashboard user information from a validated dashboard session token", "required": [ "user_id", "username" ], "properties": { "user_id": { "type": "string" }, "username": { "type": "string" }, "first_name": { "type": [ "string", "null" ] }, "last_name": { "type": [ "string", "null" ] } } }, "DefaultApiModelRequest": { "type": "object", "description": "Inner request shape for the five non-llm-liberty `api_format` values.\nShared across `openai`, `openai_responses`, `anthropic`, `anthropic_oauth`, `gemini`.", "required": [ "base_url", "models" ], "properties": { "base_url": { "type": "string", "description": "API base URL" }, "api_key": { "$ref": "#/components/schemas/ApiKeyUpdate", "description": "API key update action (Keep/Set with Some or None)" }, "models": { "type": "array", "items": { "type": "string" }, "description": "List of available models" }, "prefix": { "type": [ "string", "null" ], "description": "Optional prefix for model namespacing (e.g., \"azure/\" for \"azure/gpt-4\")" }, "forward_all_with_prefix": { "type": "boolean", "description": "Whether to forward all requests with this prefix (true) or only selected models (false)" }, "extra_headers": { "description": "Optional extra HTTP headers to send upstream. Cannot include `Authorization`\nor `x-api-key` — those are owned by provider clients." }, "extra_body": { "description": "Optional extra fields to merge into the request body sent upstream" } } }, "DefaultFetchModelsRequest": { "type": "object", "description": "Inner request for the five non-llm-liberty `api_format` values.", "required": [ "base_url" ], "properties": { "creds": { "$ref": "#/components/schemas/TestCreds", "description": "Credentials to use for fetching models" }, "base_url": { "type": "string", "description": "API base URL (required - always needed to know where to fetch models from)" }, "extra_headers": { "description": "Optional extra HTTP headers. `Authorization` / `x-api-key` are forbidden." }, "extra_body": { "description": "Optional extra fields to merge into the request body" } } }, "DefaultTestPromptRequest": { "type": "object", "description": "Inner request for the five non-llm-liberty `api_format` values.", "required": [ "base_url", "model", "prompt" ], "properties": { "creds": { "$ref": "#/components/schemas/TestCreds", "description": "Credentials to use for testing" }, "base_url": { "type": "string", "description": "API base URL" }, "model": { "type": "string", "description": "Model to use for testing" }, "prompt": { "type": "string", "description": "Test prompt (max 30 characters for cost control)" }, "extra_headers": { "description": "Optional extra HTTP headers. `Authorization` / `x-api-key` are forbidden." }, "extra_body": { "description": "Optional extra fields to merge into the request body" } } }, "DeploymentMode": { "type": "string", "enum": [ "standalone", "multi_tenant" ] }, "DownloadRequest": { "type": "object", "required": [ "id", "repo", "filename", "status", "downloaded_bytes", "created_at", "updated_at" ], "properties": { "id": { "type": "string" }, "repo": { "type": "string" }, "filename": { "type": "string" }, "status": { "$ref": "#/components/schemas/DownloadStatus" }, "error": { "type": [ "string", "null" ] }, "total_bytes": { "type": [ "integer", "null" ], "format": "int64" }, "downloaded_bytes": { "type": "integer", "format": "int64" }, "started_at": { "type": [ "string", "null" ], "format": "date-time" }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" } } }, "DownloadStatus": { "type": "string", "enum": [ "pending", "completed", "error" ] }, "DynamicRegisterRequest": { "type": "object", "required": [ "registration_endpoint", "redirect_uri" ], "properties": { "registration_endpoint": { "type": "string" }, "redirect_uri": { "type": "string" }, "scopes": { "type": [ "string", "null" ] } } }, "DynamicRegisterResponse": { "type": "object", "required": [ "client_id" ], "properties": { "client_id": { "type": "string" }, "client_secret": { "type": [ "string", "null" ] }, "client_id_issued_at": { "type": [ "integer", "null" ], "format": "int64" }, "token_endpoint_auth_method": { "type": [ "string", "null" ] }, "registration_access_token": { "type": [ "string", "null" ] } } }, "EffortCapability": { "type": "object", "description": "Effort (reasoning_effort) capability details.", "required": [ "high", "low", "max" ], "properties": { "high": { "$ref": "#/components/schemas/CapabilitySupport" }, "low": { "$ref": "#/components/schemas/CapabilitySupport" }, "max": { "$ref": "#/components/schemas/CapabilitySupport" } } }, "FetchModelsRequest": { "oneOf": [ { "allOf": [ { "$ref": "#/components/schemas/DefaultFetchModelsRequest" }, { "type": "object", "required": [ "api_format" ], "properties": { "api_format": { "type": "string", "enum": [ "openai" ] } } } ] }, { "allOf": [ { "$ref": "#/components/schemas/DefaultFetchModelsRequest" }, { "type": "object", "required": [ "api_format" ], "properties": { "api_format": { "type": "string", "enum": [ "openai_responses" ] } } } ] }, { "allOf": [ { "$ref": "#/components/schemas/DefaultFetchModelsRequest" }, { "type": "object", "required": [ "api_format" ], "properties": { "api_format": { "type": "string", "enum": [ "anthropic" ] } } } ] }, { "allOf": [ { "$ref": "#/components/schemas/DefaultFetchModelsRequest" }, { "type": "object", "required": [ "api_format" ], "properties": { "api_format": { "type": "string", "enum": [ "anthropic_oauth" ] } } } ] }, { "allOf": [ { "$ref": "#/components/schemas/DefaultFetchModelsRequest" }, { "type": "object", "required": [ "api_format" ], "properties": { "api_format": { "type": "string", "enum": [ "gemini" ] } } } ] }, { "allOf": [ { "$ref": "#/components/schemas/LlmLibertyFetchModelsRequest" }, { "type": "object", "required": [ "api_format" ], "properties": { "api_format": { "type": "string", "enum": [ "llm_liberty_oauth" ] } } } ] } ], "description": "Request to fetch available models from provider. Discriminated on `api_format`.", "example": { "api_format": "openai", "base_url": "http://localhost:8080/v1", "creds": { "type": "api_key", "value": null } } }, "FetchModelsResponse": { "type": "object", "description": "Returns model IDs only (not full metadata) to minimize information exposure —\nthe endpoint accepts an API key parameter. Full metadata is stored on create/update.", "required": [ "models" ], "properties": { "models": { "type": "array", "items": { "type": "string" } } }, "example": { "models": [ "gpt-4", "gpt-3.5-turbo", "gpt-4-turbo" ] } }, "FlowType": { "type": "string", "enum": [ "redirect", "popup" ] }, "GeminiModel": { "type": "object", "description": "Gemini `Model` schema (see `openapi-gemini.json`).", "required": [ "name" ], "properties": { "name": { "type": "string" }, "version": { "type": [ "string", "null" ] }, "displayName": { "type": [ "string", "null" ] }, "description": { "type": [ "string", "null" ] }, "inputTokenLimit": { "type": [ "integer", "null" ], "format": "int64" }, "outputTokenLimit": { "type": [ "integer", "null" ], "format": "int64" }, "supportedGenerationMethods": { "type": "array", "items": { "type": "string" } }, "temperature": { "type": [ "number", "null" ], "format": "float" }, "maxTemperature": { "type": [ "number", "null" ], "format": "float" }, "topP": { "type": [ "number", "null" ], "format": "float" }, "topK": { "type": [ "integer", "null" ], "format": "int32" }, "thinking": { "type": [ "boolean", "null" ] } } }, "JsonVec": { "type": "array", "items": { "type": "string" } }, "ListMcpServersResponse": { "type": "object", "required": [ "mcp_servers" ], "properties": { "mcp_servers": { "type": "array", "items": { "$ref": "#/components/schemas/McpServerResponse" } } } }, "ListMcpsResponse": { "type": "object", "required": [ "mcps" ], "properties": { "mcps": { "type": "array", "items": { "$ref": "#/components/schemas/Mcp" } } } }, "ListUsersParams": { "type": "object", "description": "List users query parameters. Intentionally omits sort fields (unlike PaginationSortParams)\nbecause user listing is fetched from the auth service which handles its own ordering.", "properties": { "page": { "type": [ "integer", "null" ], "format": "int32", "example": 1, "minimum": 0 }, "page_size": { "type": [ "integer", "null" ], "format": "int32", "example": 10, "minimum": 0 } } }, "LlmLibertyApiEndpoints": { "type": "object", "required": [ "base_url", "chat_url" ], "properties": { "base_url": { "type": "string" }, "chat_url": { "type": "string" }, "models_url": { "type": [ "string", "null" ] } } }, "LlmLibertyApiModelRequest": { "type": "object", "description": "Request shape for `api_format == \"llm_liberty_oauth\"`. Carries the full envelope\n(or `Keep` to leave existing credentials untouched on update).", "properties": { "envelope": { "$ref": "#/components/schemas/LlmLibertyEnvelopeUpdate", "description": "Envelope update action — Keep (update only) or Set (create/replace credentials)." }, "models": { "type": "array", "items": { "type": "string" }, "description": "List of available models" }, "prefix": { "type": [ "string", "null" ], "description": "Optional prefix for model namespacing" }, "forward_all_with_prefix": { "type": "boolean", "description": "Whether to forward all requests with this prefix" } } }, "LlmLibertyAuthSpec": { "type": "object", "required": [ "in", "key", "scheme" ], "properties": { "in": { "type": "string" }, "key": { "type": "string" }, "scheme": { "type": "string" } } }, "LlmLibertyEnvelope": { "type": "object", "description": "The JSON blob emitted by `npx @bodhiapp/llm-liberty@latest login`.\n\nVersion field allows BodhiApp to detect breaking changes in the envelope\nschema (major-version bump = breaking). Currently only `\"1.0.0\"` is accepted.", "required": [ "version", "provider", "access_token", "refresh_token", "expires_at", "auth", "oauth", "api" ], "properties": { "version": { "type": "string", "description": "Envelope schema version — must be \"1.0.0\"." }, "provider": { "type": "string", "description": "Provider identifier, e.g. \"anthropic\". Only \"anthropic\" is supported in v1." }, "access_token": { "type": "string" }, "refresh_token": { "type": "string" }, "expires_at": { "type": "integer", "format": "int64", "description": "Unix epoch seconds when the access token expires." }, "auth": { "$ref": "#/components/schemas/LlmLibertyAuthSpec" }, "oauth": { "$ref": "#/components/schemas/LlmLibertyOauthEndpoints" }, "api": { "$ref": "#/components/schemas/LlmLibertyApiEndpoints" }, "headers": {}, "body": {}, "extra": {} } }, "LlmLibertyEnvelopeUpdate": { "oneOf": [ { "type": "object", "description": "Keep the stored credentials unchanged.", "required": [ "action" ], "properties": { "action": { "type": "string", "enum": [ "keep" ] } } }, { "type": "object", "description": "Replace with a new envelope (atomic re-paste).", "required": [ "value", "action" ], "properties": { "value": { "$ref": "#/components/schemas/LlmLibertyEnvelope", "description": "Replace with a new envelope (atomic re-paste)." }, "action": { "type": "string", "enum": [ "set" ] } } } ], "description": "Tagged envelope update action — either keep the existing credentials or replace them." }, "LlmLibertyFetchModelsRequest": { "type": "object", "description": "Inner request for `api_format == \"llm_liberty_oauth\"`. Either `id` (use stored creds)\nor `envelope` (use the provided envelope directly) must be set, never both.", "properties": { "id": { "type": [ "string", "null" ], "description": "Edit mode: alias id whose stored credentials should be used." }, "envelope": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/LlmLibertyEnvelope", "description": "Create mode: full envelope (mutually exclusive with `id`)." } ] } } }, "LlmLibertyOauthEndpoints": { "type": "object", "required": [ "authorize_url", "token_url", "client_id" ], "properties": { "authorize_url": { "type": "string" }, "token_url": { "type": "string" }, "revoke_url": { "type": [ "string", "null" ] }, "client_id": { "type": "string" }, "client_secret": { "type": [ "string", "null" ] } } }, "LlmLibertySummary": { "type": "object", "description": "Non-secret summary of stored LLM Liberty OAuth credentials for API responses.", "required": [ "provider", "envelope_version", "expires_at", "has_refresh_token" ], "properties": { "provider": { "type": "string" }, "envelope_version": { "type": "string" }, "expires_at": { "type": "integer", "format": "int64", "description": "Unix epoch seconds — when the stored access token expires." }, "has_refresh_token": { "type": "boolean" } } }, "LlmLibertyTestPromptRequest": { "type": "object", "description": "Inner request for `api_format == \"llm_liberty_oauth\"`. Either `id` (use stored creds)\nor `envelope` (use the provided envelope directly) must be set, never both.", "required": [ "model", "prompt" ], "properties": { "id": { "type": [ "string", "null" ], "description": "Edit mode: alias id whose stored credentials should be used." }, "envelope": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/LlmLibertyEnvelope", "description": "Create mode: full envelope (mutually exclusive with `id`)." } ] }, "model": { "type": "string", "description": "Model to use for testing" }, "prompt": { "type": "string", "description": "Test prompt (max 30 characters for cost control)" } } }, "LocalModelResponse": { "type": "object", "description": "Local model file response", "required": [ "repo", "filename", "snapshot", "model_params" ], "properties": { "repo": { "type": "string" }, "filename": { "type": "string" }, "snapshot": { "type": "string" }, "size": { "type": [ "integer", "null" ], "format": "int64", "minimum": 0 }, "model_params": { "type": "object", "additionalProperties": {}, "propertyNames": { "type": "string" } }, "metadata": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ModelMetadata", "description": "Model metadata extracted from GGUF file (optional)" } ] } } }, "Mcp": { "type": "object", "description": "User-owned MCP server instance.", "required": [ "id", "mcp_server", "slug", "name", "enabled", "path", "auth_type", "created_at", "updated_at" ], "properties": { "id": { "type": "string", "description": "Unique instance identifier (UUID)" }, "mcp_server": { "$ref": "#/components/schemas/McpServerInfo", "description": "Server info resolved via JOIN" }, "slug": { "type": "string", "description": "User-defined slug for this instance" }, "name": { "type": "string", "description": "Human-readable name" }, "description": { "type": [ "string", "null" ], "description": "Optional description for this instance" }, "enabled": { "type": "boolean", "description": "Whether this instance is enabled" }, "path": { "type": "string", "description": "MCP proxy path for this instance" }, "auth_type": { "$ref": "#/components/schemas/McpAuthType" }, "auth_config_id": { "type": [ "string", "null" ], "description": "Reference to the auth config (mcp_auth_configs.id)" }, "created_at": { "type": "string", "format": "date-time", "description": "When this instance was created", "example": "2024-11-10T04:52:06.786Z" }, "updated_at": { "type": "string", "format": "date-time", "description": "When this instance was last updated", "example": "2024-11-10T04:52:06.786Z" } } }, "McpApproval": { "type": "object", "required": [ "url", "status" ], "properties": { "url": { "type": "string" }, "status": { "$ref": "#/components/schemas/ApprovalStatus" }, "instance": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/McpInstance" } ] } } }, "McpAuthConfigParam": { "type": "object", "required": [ "id", "param_type", "param_key" ], "properties": { "id": { "type": "string" }, "param_type": { "$ref": "#/components/schemas/McpAuthParamType" }, "param_key": { "type": "string" } } }, "McpAuthConfigParamInput": { "type": "object", "required": [ "param_type", "param_key" ], "properties": { "param_type": { "$ref": "#/components/schemas/McpAuthParamType" }, "param_key": { "type": "string" } } }, "McpAuthConfigResponse": { "oneOf": [ { "type": "object", "required": [ "id", "name", "mcp_server_id", "created_by", "entries", "created_at", "updated_at", "type" ], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "mcp_server_id": { "type": "string" }, "created_by": { "type": "string" }, "entries": { "type": "array", "items": { "$ref": "#/components/schemas/McpAuthConfigParam" } }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" }, "type": { "type": "string", "enum": [ "header" ] } } }, { "type": "object", "required": [ "id", "name", "mcp_server_id", "created_by", "registration_type", "client_id", "authorization_endpoint", "token_endpoint", "has_client_secret", "has_registration_access_token", "created_at", "updated_at", "type" ], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "mcp_server_id": { "type": "string" }, "created_by": { "type": "string" }, "registration_type": { "$ref": "#/components/schemas/RegistrationType" }, "client_id": { "type": "string" }, "authorization_endpoint": { "type": "string" }, "token_endpoint": { "type": "string" }, "registration_endpoint": { "type": [ "string", "null" ] }, "scopes": { "type": [ "string", "null" ] }, "client_id_issued_at": { "type": [ "integer", "null" ], "format": "int64" }, "token_endpoint_auth_method": { "type": [ "string", "null" ] }, "has_client_secret": { "type": "boolean" }, "has_registration_access_token": { "type": "boolean" }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" }, "type": { "type": "string", "enum": [ "oauth" ] } } } ], "description": "Discriminated union response for any type of MCP auth config.\nThe JSON `\"type\"` field determines the variant: `\"header\"` or `\"oauth\"`." }, "McpAuthConfigType": { "type": "string", "enum": [ "header", "oauth" ] }, "McpAuthConfigsListResponse": { "type": "object", "description": "List wrapper for unified auth config responses.", "required": [ "auth_configs" ], "properties": { "auth_configs": { "type": "array", "items": { "$ref": "#/components/schemas/McpAuthConfigResponse" } } } }, "McpAuthParam": { "type": "object", "required": [ "id", "param_type", "param_key", "has_value" ], "properties": { "id": { "type": "string" }, "param_type": { "$ref": "#/components/schemas/McpAuthParamType" }, "param_key": { "type": "string" }, "has_value": { "type": "boolean" } } }, "McpAuthParamInput": { "type": "object", "required": [ "param_type", "param_key", "value" ], "properties": { "param_type": { "$ref": "#/components/schemas/McpAuthParamType" }, "param_key": { "type": "string" }, "value": { "type": "string" } } }, "McpAuthParamType": { "type": "string", "enum": [ "header", "query" ] }, "McpAuthType": { "type": "string", "enum": [ "public", "header", "oauth" ] }, "McpInstance": { "type": "object", "required": [ "id", "path" ], "properties": { "id": { "type": "string" }, "path": { "type": "string", "description": "MCP proxy path for this instance (e.g. `/bodhi/v1/apps/mcps/{id}/mcp`)" } } }, "McpRequest": { "type": "object", "description": "Input for creating or updating an MCP instance.", "required": [ "name", "slug", "enabled" ], "properties": { "name": { "type": "string", "description": "Human-readable name (required)" }, "slug": { "type": "string", "description": "User-defined slug for this instance (1-24 chars, alphanumeric + hyphens)" }, "mcp_server_id": { "type": [ "string", "null" ], "description": "MCP server ID (required for create, ignored for update)" }, "description": { "type": [ "string", "null" ], "description": "Optional description" }, "enabled": { "type": "boolean", "description": "Whether this instance is enabled" }, "auth_type": { "$ref": "#/components/schemas/McpAuthType", "description": "Authentication type" }, "auth_config_id": { "type": [ "string", "null" ], "description": "Reference to auth config" }, "credentials": { "type": [ "array", "null" ], "items": { "$ref": "#/components/schemas/McpAuthParamInput" }, "description": "Instance-level auth params (values for the auth config's key definitions)" }, "oauth_token_id": { "type": [ "string", "null" ], "description": "OAuth token ID to link to this MCP instance (set after OAuth flow)" } } }, "McpServer": { "type": "object", "description": "Admin-managed MCP server registry entry.\nAdmins/managers register MCP server URLs that users can then create instances of.", "required": [ "id", "url", "name", "enabled", "created_by", "updated_by", "created_at", "updated_at" ], "properties": { "id": { "type": "string", "description": "Unique identifier (UUID)" }, "url": { "type": "string", "description": "MCP server endpoint URL (trimmed, case-insensitive unique)" }, "name": { "type": "string", "description": "Human-readable display name" }, "description": { "type": [ "string", "null" ], "description": "Optional description" }, "enabled": { "type": "boolean", "description": "Whether this MCP server is enabled" }, "created_by": { "type": "string", "description": "User who created this entry" }, "updated_by": { "type": "string", "description": "User who last updated this entry" }, "created_at": { "type": "string", "format": "date-time", "description": "When this entry was created", "example": "2024-11-10T04:52:06.786Z" }, "updated_at": { "type": "string", "format": "date-time", "description": "When this entry was last updated", "example": "2024-11-10T04:52:06.786Z" } } }, "McpServerInfo": { "type": "object", "description": "Minimal MCP server info embedded in MCP instance responses.", "required": [ "id", "url", "name", "enabled" ], "properties": { "id": { "type": "string" }, "url": { "type": "string" }, "name": { "type": "string" }, "enabled": { "type": "boolean" } } }, "McpServerRequest": { "type": "object", "description": "Input for creating or updating an MCP server.", "required": [ "url", "name", "enabled" ], "properties": { "url": { "type": "string", "description": "MCP server endpoint URL (trimmed, case-insensitive unique)" }, "name": { "type": "string", "description": "Human-readable display name" }, "description": { "type": [ "string", "null" ], "description": "Optional description" }, "enabled": { "type": "boolean", "description": "Whether this MCP server is enabled" }, "auth_config": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/CreateMcpAuthConfigRequest", "description": "Optional auth config to create alongside the server (create only)" } ] } } }, "McpServerResponse": { "allOf": [ { "$ref": "#/components/schemas/McpServer" }, { "type": "object", "required": [ "enabled_mcp_count", "disabled_mcp_count" ], "properties": { "enabled_mcp_count": { "type": "integer", "format": "int64" }, "disabled_mcp_count": { "type": "integer", "format": "int64" }, "auth_config": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/McpAuthConfigResponse" } ] } } } ], "description": "MCP server response with computed mcp counts and optional auth config." }, "McpServerReviewInfo": { "type": "object", "required": [ "url", "instances" ], "properties": { "url": { "type": "string", "description": "Requested MCP server URL" }, "instances": { "type": "array", "items": { "$ref": "#/components/schemas/Mcp" }, "description": "User's MCP instances connected to this server URL" } } }, "Model": { "type": "object", "description": "Describes an OpenAI model offering that can be used with the API.", "required": [ "id", "object", "created", "owned_by" ], "properties": { "id": { "type": "string", "description": "The model identifier, which can be referenced in the API endpoints." }, "object": { "type": "string", "description": "The object type, which is always \"model\"." }, "created": { "type": "integer", "format": "int32", "description": "The Unix timestamp (in seconds) when the model was created.", "minimum": 0 }, "owned_by": { "type": "string", "description": "The organization that owns the model." } } }, "ModelAlias": { "type": "object", "required": [ "alias", "repo", "filename", "snapshot" ], "properties": { "alias": { "type": "string" }, "repo": { "type": "string", "format": "string" }, "filename": { "type": "string" }, "snapshot": { "type": "string" } } }, "ModelAliasResponse": { "type": "object", "description": "Response for auto-discovered model aliases", "required": [ "source", "alias", "repo", "filename", "snapshot" ], "properties": { "source": { "type": "string" }, "alias": { "type": "string" }, "repo": { "type": "string" }, "filename": { "type": "string" }, "snapshot": { "type": "string" }, "metadata": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ModelMetadata", "description": "Model metadata extracted from GGUF file (optional)" } ] } } }, "ModelArchitecture": { "type": "object", "required": [ "format" ], "properties": { "family": { "type": [ "string", "null" ] }, "parameter_count": { "type": [ "integer", "null" ], "format": "int64", "minimum": 0 }, "quantization": { "type": [ "string", "null" ] }, "format": { "type": "string" } } }, "ModelCapabilities": { "type": "object", "required": [ "tools" ], "properties": { "vision": { "type": [ "boolean", "null" ] }, "audio": { "type": [ "boolean", "null" ] }, "thinking": { "type": [ "boolean", "null" ] }, "tools": { "$ref": "#/components/schemas/ToolCapabilities" } } }, "ModelMetadata": { "type": "object", "description": "Model metadata for API responses", "required": [ "capabilities", "context", "architecture" ], "properties": { "capabilities": { "$ref": "#/components/schemas/ModelCapabilities" }, "context": { "$ref": "#/components/schemas/ContextLimits" }, "architecture": { "$ref": "#/components/schemas/ModelArchitecture" }, "chat_template": { "type": [ "string", "null" ] } } }, "NewDownloadRequest": { "type": "object", "description": "Request for creating a new download request", "required": [ "repo", "filename" ], "properties": { "repo": { "type": "string", "description": "HuggingFace repository name in format 'username/repository-name'", "example": "TheBloke/Mistral-7B-Instruct-v0.1-GGUF", "pattern": "^[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+$" }, "filename": { "type": "string", "description": "Model file name to download (typically .gguf format)", "example": "mistral-7b-instruct-v0.1.Q4_K_M.gguf", "pattern": ".*\\.(gguf|bin|safetensors)$" } }, "example": { "filename": "mistral-7b-instruct-v0.1.Q4_K_M.gguf", "repo": "TheBloke/Mistral-7B-Instruct-v0.1-GGUF" } }, "OAIRequestParams": { "type": "object", "properties": { "frequency_penalty": { "type": [ "number", "null" ], "format": "float" }, "max_tokens": { "type": [ "integer", "null" ], "format": "int32", "minimum": 0 }, "presence_penalty": { "type": [ "number", "null" ], "format": "float" }, "seed": { "type": [ "integer", "null" ], "format": "int64" }, "stop": { "type": "array", "items": { "type": "string" } }, "temperature": { "type": [ "number", "null" ], "format": "float" }, "top_p": { "type": [ "number", "null" ], "format": "float" }, "user": { "type": [ "string", "null" ] } } }, "OAuthDiscoverAsRequest": { "type": "object", "required": [ "url" ], "properties": { "url": { "type": "string" } } }, "OAuthDiscoverAsResponse": { "type": "object", "required": [ "authorization_endpoint", "token_endpoint" ], "properties": { "authorization_endpoint": { "type": "string" }, "token_endpoint": { "type": "string" }, "scopes_supported": { "type": [ "array", "null" ], "items": { "type": "string" } } } }, "OAuthDiscoverMcpRequest": { "type": "object", "required": [ "mcp_server_url" ], "properties": { "mcp_server_url": { "type": "string" } } }, "OAuthDiscoverMcpResponse": { "type": "object", "properties": { "authorization_endpoint": { "type": [ "string", "null" ] }, "token_endpoint": { "type": [ "string", "null" ] }, "registration_endpoint": { "type": [ "string", "null" ] }, "scopes_supported": { "type": [ "array", "null" ], "items": { "type": "string" } }, "resource": { "type": [ "string", "null" ] }, "authorization_server_url": { "type": [ "string", "null" ] } } }, "OAuthLoginRequest": { "type": "object", "required": [ "redirect_uri" ], "properties": { "redirect_uri": { "type": "string" } } }, "OAuthLoginResponse": { "type": "object", "required": [ "authorization_url" ], "properties": { "authorization_url": { "type": "string" } } }, "OAuthTokenExchangeRequest": { "type": "object", "required": [ "code", "redirect_uri", "state" ], "properties": { "mcp_id": { "type": [ "string", "null" ] }, "code": { "type": "string" }, "redirect_uri": { "type": "string" }, "state": { "type": "string" } } }, "OAuthTokenResponse": { "type": "object", "required": [ "id", "auth_config_id", "has_refresh_token", "user_id", "created_at", "updated_at" ], "properties": { "id": { "type": "string" }, "mcp_id": { "type": [ "string", "null" ] }, "auth_config_id": { "type": "string" }, "scopes_granted": { "type": [ "string", "null" ] }, "expires_at": { "type": [ "integer", "null" ], "format": "int64" }, "has_refresh_token": { "type": "boolean" }, "user_id": { "type": "string" }, "created_at": { "type": "string" }, "updated_at": { "type": "string" } } }, "PaginatedAliasResponse": { "type": "object", "description": "Paginated list of all model aliases (user, model, and API)", "required": [ "data", "total", "page", "page_size" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/AliasResponse" } }, "total": { "type": "integer", "minimum": 0 }, "page": { "type": "integer", "minimum": 0 }, "page_size": { "type": "integer", "minimum": 0 } } }, "PaginatedDownloadResponse": { "type": "object", "description": "Paginated list of download requests", "required": [ "data", "total", "page", "page_size" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/DownloadRequest" } }, "total": { "type": "integer", "minimum": 0 }, "page": { "type": "integer", "minimum": 0 }, "page_size": { "type": "integer", "minimum": 0 } } }, "PaginatedLocalModelResponse": { "type": "object", "description": "Paginated list of local model files", "required": [ "data", "total", "page", "page_size" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/LocalModelResponse" } }, "total": { "type": "integer", "minimum": 0 }, "page": { "type": "integer", "minimum": 0 }, "page_size": { "type": "integer", "minimum": 0 } } }, "PaginatedTokenResponse": { "type": "object", "required": [ "data", "total", "page", "page_size" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/TokenDetail" } }, "total": { "type": "integer", "minimum": 0 }, "page": { "type": "integer", "minimum": 0 }, "page_size": { "type": "integer", "minimum": 0 } } }, "PaginatedUserAccessResponse": { "type": "object", "description": "Paginated response for access requests", "required": [ "requests", "total", "page", "page_size" ], "properties": { "requests": { "type": "array", "items": { "$ref": "#/components/schemas/UserAccessRequest" }, "description": "List of access requests" }, "total": { "type": "integer", "description": "Total number of requests", "minimum": 0 }, "page": { "type": "integer", "description": "Current page number", "minimum": 0 }, "page_size": { "type": "integer", "description": "Number of items per page", "minimum": 0 } }, "example": { "page": 1, "page_size": 20, "requests": [ { "created_at": "2024-01-01T12:00:00Z", "id": "01HXXXXXX", "status": "pending", "updated_at": "2024-01-01T12:00:00Z", "user_id": "auth0|123", "username": "user@example.com" } ], "total": 1 } }, "PaginatedUserAliasResponse": { "type": "object", "description": "Paginated list of user-defined model aliases", "required": [ "data", "total", "page", "page_size" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/UserAliasResponse" } }, "total": { "type": "integer", "minimum": 0 }, "page": { "type": "integer", "minimum": 0 }, "page_size": { "type": "integer", "minimum": 0 } } }, "PaginationSortParams": { "type": "object", "description": "Query parameters for pagination and sorting", "properties": { "page": { "type": "integer", "description": "Page number (1-based indexing)", "example": 1, "minimum": 1 }, "page_size": { "type": "integer", "description": "Number of items to return per page (maximum 100)", "example": 30, "maximum": 100, "minimum": 1 }, "sort": { "type": [ "string", "null" ], "description": "Field to sort by. Common values: repo, filename, size, updated_at, snapshot, created_at", "example": "updated_at" }, "sort_order": { "type": "string", "description": "Sort order: 'asc' for ascending, 'desc' for descending", "example": "desc", "pattern": "^(asc|desc)$" } } }, "PingResponse": { "type": "object", "description": "Response to the ping endpoint", "required": [ "message" ], "properties": { "message": { "type": "string", "description": "Simple ping response message", "example": "pong" } }, "example": { "message": "pong" } }, "QueueStatusResponse": { "type": "object", "description": "Response for queue status operations", "required": [ "status" ], "properties": { "status": { "type": "string", "description": "Queue status (\"idle\" or \"processing\")" } } }, "RedirectResponse": { "type": "object", "required": [ "location" ], "properties": { "location": { "type": "string", "description": "The URL to redirect to (OAuth authorization URL or application home page)", "example": "https://oauth.example.com/auth?client_id=test&redirect_uri=..." } }, "example": { "location": "https://oauth.example.com/auth?client_id=test&redirect_uri=..." } }, "RefreshRequest": { "oneOf": [ { "type": "object", "description": "Bulk async refresh for all models - Request: {\"source\": \"all\"}", "required": [ "source" ], "properties": { "source": { "type": "string", "enum": [ "all" ] } } }, { "type": "object", "description": "Single sync refresh for specific model - Request: {\"source\": \"model\", \"repo\": \"...\", \"filename\": \"...\", \"snapshot\": \"...\"}", "required": [ "repo", "filename", "snapshot", "source" ], "properties": { "repo": { "type": "string", "description": "Repository in format \"user/repo\"", "example": "bartowski/Qwen2.5-3B-Instruct-GGUF" }, "filename": { "type": "string", "description": "Filename of the GGUF model", "example": "Qwen2.5-3B-Instruct-Q4_K_M.gguf" }, "snapshot": { "type": "string", "description": "Snapshot/commit identifier", "example": "8ba1c3c3ee94ba4b86ff92a749ae687dc41fce3f" }, "source": { "type": "string", "enum": [ "model" ] } } } ], "description": "Refresh request - discriminated union by source field" }, "RefreshResponse": { "type": "object", "description": "Response for metadata refresh operations", "required": [ "num_queued" ], "properties": { "num_queued": { "type": "string", "description": "Number of models queued (\"all\" for bulk refresh, \"1\" for single)" }, "alias": { "type": [ "string", "null" ], "description": "Model alias (only for single model refresh)" } } }, "RefreshSource": { "type": "string", "description": "Source type discriminator for refresh requests", "enum": [ "all", "model" ] }, "RegistrationType": { "type": "string", "description": "OAuth 2.1 registration type: pre-registered client or dynamic client registration (DCR).", "enum": [ "pre_registered", "dynamic_registration" ] }, "RequestedMcpServer": { "type": "object", "required": [ "url" ], "properties": { "url": { "type": "string" } } }, "RequestedResources": { "oneOf": [ { "allOf": [ { "$ref": "#/components/schemas/RequestedResourcesV1" }, { "type": "object", "required": [ "version" ], "properties": { "version": { "type": "string", "enum": [ "1" ] } } } ] } ], "description": "Versioned envelope for requested resources.\nThe `version` tag is mandatory — clients must specify which version they are using." }, "RequestedResourcesV1": { "type": "object", "properties": { "mcp_servers": { "type": "array", "items": { "$ref": "#/components/schemas/RequestedMcpServer" } } } }, "ResourceRole": { "type": "string", "enum": [ "resource_anonymous", "resource_guest", "resource_user", "resource_power_user", "resource_manager", "resource_admin" ] }, "SettingInfo": { "type": "object", "required": [ "key", "current_value", "default_value", "source", "metadata" ], "properties": { "key": { "type": "string" }, "current_value": {}, "default_value": {}, "source": { "$ref": "#/components/schemas/SettingSource" }, "metadata": { "$ref": "#/components/schemas/SettingMetadata" } } }, "SettingMetadata": { "oneOf": [ { "type": "object", "required": [ "type" ], "properties": { "type": { "type": "string", "enum": [ "string" ] } } }, { "type": "object", "required": [ "min", "max", "type" ], "properties": { "min": { "type": "integer", "format": "int64" }, "max": { "type": "integer", "format": "int64" }, "type": { "type": "string", "enum": [ "number" ] } } }, { "type": "object", "required": [ "type" ], "properties": { "type": { "type": "string", "enum": [ "boolean" ] } } }, { "type": "object", "required": [ "options", "type" ], "properties": { "options": { "type": "array", "items": { "type": "string" } }, "type": { "type": "string", "enum": [ "option" ] } } } ] }, "SettingSource": { "type": "string", "enum": [ "system", "command_line", "environment", "database", "settings_file", "default" ] }, "SetupRequest": { "type": "object", "description": "Request to setup the application in authenticated mode", "required": [ "name" ], "properties": { "name": { "type": "string", "description": "Server name for identification (minimum 10 characters)", "example": "My Bodhi Server", "maxLength": 100, "minLength": 10 }, "description": { "type": [ "string", "null" ], "description": "Optional description of the server's purpose", "example": "My personal AI server", "maxLength": 500 } }, "example": { "description": "My personal AI server", "name": "My Bodhi Server" } }, "SetupResponse": { "type": "object", "description": "Response containing the updated application status after setup", "required": [ "status" ], "properties": { "status": { "$ref": "#/components/schemas/AppStatus", "description": "New application status after successful setup" } }, "example": { "status": "resource_admin" } }, "TenantListItem": { "type": "object", "required": [ "client_id", "name", "status", "is_active", "logged_in" ], "properties": { "client_id": { "type": "string" }, "name": { "type": "string" }, "description": { "type": [ "string", "null" ] }, "status": { "$ref": "#/components/schemas/AppStatus" }, "is_active": { "type": "boolean" }, "logged_in": { "type": "boolean" } } }, "TenantListResponse": { "type": "object", "required": [ "tenants" ], "properties": { "tenants": { "type": "array", "items": { "$ref": "#/components/schemas/TenantListItem" } } } }, "TestCreds": { "oneOf": [ { "type": "object", "description": "Look up credentials from stored API model", "required": [ "value", "type" ], "properties": { "value": { "type": "string", "description": "Look up credentials from stored API model" }, "type": { "type": "string", "enum": [ "id" ] } }, "example": { "type": "id", "value": "openai-gpt4" } }, { "type": "object", "description": "Use direct API key (null for no authentication)", "required": [ "value", "type" ], "properties": { "value": { "$ref": "#/components/schemas/ApiKey", "description": "Use direct API key (null for no authentication)" }, "type": { "type": "string", "enum": [ "api_key" ] } }, "example": { "type": "api_key", "value": "sk-1234567890abcdef" } } ], "description": "Credentials for test/fetch operations" }, "TestPromptRequest": { "oneOf": [ { "allOf": [ { "$ref": "#/components/schemas/DefaultTestPromptRequest" }, { "type": "object", "required": [ "api_format" ], "properties": { "api_format": { "type": "string", "enum": [ "openai" ] } } } ] }, { "allOf": [ { "$ref": "#/components/schemas/DefaultTestPromptRequest" }, { "type": "object", "required": [ "api_format" ], "properties": { "api_format": { "type": "string", "enum": [ "openai_responses" ] } } } ] }, { "allOf": [ { "$ref": "#/components/schemas/DefaultTestPromptRequest" }, { "type": "object", "required": [ "api_format" ], "properties": { "api_format": { "type": "string", "enum": [ "anthropic" ] } } } ] }, { "allOf": [ { "$ref": "#/components/schemas/DefaultTestPromptRequest" }, { "type": "object", "required": [ "api_format" ], "properties": { "api_format": { "type": "string", "enum": [ "anthropic_oauth" ] } } } ] }, { "allOf": [ { "$ref": "#/components/schemas/DefaultTestPromptRequest" }, { "type": "object", "required": [ "api_format" ], "properties": { "api_format": { "type": "string", "enum": [ "gemini" ] } } } ] }, { "allOf": [ { "$ref": "#/components/schemas/LlmLibertyTestPromptRequest" }, { "type": "object", "required": [ "api_format" ], "properties": { "api_format": { "type": "string", "enum": [ "llm_liberty_oauth" ] } } } ] } ], "description": "Request to test API connectivity with a prompt. Discriminated on `api_format`.", "example": { "api_format": "openai", "base_url": "https://api.openai.com/v1", "creds": { "type": "api_key", "value": "sk-..." }, "model": "gpt-4", "prompt": "Hello, how are you?" } }, "TestPromptResponse": { "type": "object", "description": "Response from testing API connectivity", "required": [ "success" ], "properties": { "success": { "type": "boolean" }, "response": { "type": [ "string", "null" ] }, "error": { "type": [ "string", "null" ] } }, "example": { "error": null, "response": "Hello! I'm doing well, thank you.", "success": true } }, "ThinkingCapability": { "type": "object", "description": "Thinking capability and supported type configurations.", "required": [ "supported", "types" ], "properties": { "supported": { "type": "boolean" }, "types": { "$ref": "#/components/schemas/ThinkingTypes" } } }, "ThinkingTypes": { "type": "object", "description": "Supported thinking type configurations.", "required": [ "adaptive", "enabled" ], "properties": { "adaptive": { "$ref": "#/components/schemas/CapabilitySupport" }, "enabled": { "$ref": "#/components/schemas/CapabilitySupport" } } }, "TokenCreated": { "type": "object", "required": [ "token" ], "properties": { "token": { "type": "string", "description": "API token with bodhiapp_ prefix for programmatic access", "example": "bodhiapp_1234567890abcdef" } }, "example": { "token": "bodhiapp_1234567890abcdef" } }, "TokenDetail": { "type": "object", "required": [ "id", "user_id", "name", "token_prefix", "scopes", "status", "created_at", "updated_at" ], "properties": { "id": { "type": "string" }, "user_id": { "type": "string" }, "name": { "type": "string" }, "token_prefix": { "type": "string" }, "scopes": { "type": "string" }, "status": { "$ref": "#/components/schemas/TokenStatus" }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" } } }, "TokenInfo": { "type": "object", "description": "API Token information response", "required": [ "role" ], "properties": { "role": { "$ref": "#/components/schemas/TokenScope" } } }, "TokenScope": { "type": "string", "enum": [ "scope_token_user", "scope_token_power_user" ] }, "TokenStatus": { "type": "string", "enum": [ "active", "inactive" ] }, "ToolCapabilities": { "type": "object", "properties": { "function_calling": { "type": [ "boolean", "null" ] }, "structured_output": { "type": [ "boolean", "null" ] } } }, "UpdateSettingRequest": { "type": "object", "description": "Request to update a setting value", "required": [ "value" ], "properties": { "value": { "description": "New value for the setting (type depends on setting metadata)" } }, "example": { "value": "debug" } }, "UpdateTokenRequest": { "type": "object", "required": [ "name", "status" ], "properties": { "name": { "type": "string", "description": "New descriptive name for the token", "example": "Updated Token Name", "maxLength": 100, "minLength": 3 }, "status": { "$ref": "#/components/schemas/TokenStatus", "description": "New status for the token (active/inactive)" } }, "example": { "name": "Updated Token Name", "status": "inactive" } }, "UserAccessRequest": { "type": "object", "description": "User access request output type for API responses", "required": [ "id", "username", "user_id", "status", "created_at", "updated_at" ], "properties": { "id": { "type": "string" }, "username": { "type": "string" }, "user_id": { "type": "string" }, "reviewer": { "type": [ "string", "null" ] }, "status": { "$ref": "#/components/schemas/UserAccessRequestStatus" }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" } } }, "UserAccessRequestStatus": { "type": "string", "enum": [ "pending", "approved", "rejected" ] }, "UserAccessStatusResponse": { "type": "object", "description": "Response for checking access request status", "required": [ "username", "status", "created_at", "updated_at" ], "properties": { "username": { "type": "string", "description": "Username of the requesting user" }, "status": { "$ref": "#/components/schemas/UserAccessRequestStatus", "description": "Current status of the request (pending, approved, rejected)" }, "created_at": { "type": "string", "format": "date-time", "description": "Creation timestamp" }, "updated_at": { "type": "string", "format": "date-time", "description": "Last update timestamp" } }, "example": { "created_at": "2024-01-01T12:00:00Z", "status": "pending", "updated_at": "2024-01-01T12:00:00Z", "username": "user@example.com" } }, "UserAlias": { "type": "object", "required": [ "id", "alias", "repo", "filename", "snapshot", "created_at", "updated_at" ], "properties": { "id": { "type": "string" }, "alias": { "type": "string" }, "repo": { "type": "string", "format": "string" }, "filename": { "type": "string" }, "snapshot": { "type": "string" }, "request_params": { "$ref": "#/components/schemas/OAIRequestParams" }, "context_params": { "$ref": "#/components/schemas/JsonVec" }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" } } }, "UserAliasRequest": { "type": "object", "description": "Input request for creating or updating a user model alias.", "required": [ "alias", "repo", "filename" ], "properties": { "alias": { "type": "string", "description": "Alias name — unique per (tenant_id, user_id) scope" }, "repo": { "type": "string", "description": "Repository in format \"user/repo\"" }, "filename": { "type": "string", "description": "Filename of the GGUF model" }, "snapshot": { "type": [ "string", "null" ], "description": "Snapshot/commit identifier (optional — defaults to latest available)" }, "request_params": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/OAIRequestParams", "description": "Request parameters for the model" } ] }, "context_params": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Context parameters for the model" } }, "example": { "alias": "llama3:instruct", "context_params": [ "--ctx-size 4096" ], "filename": "Meta-Llama-3-8B-Instruct.Q4_K_M.gguf", "repo": "QuantFactory/Meta-Llama-3-8B-Instruct-GGUF", "request_params": { "temperature": 0.7 } } }, "UserAliasResponse": { "type": "object", "description": "User-defined model alias response", "required": [ "id", "alias", "repo", "filename", "snapshot", "source", "model_params", "request_params", "context_params", "created_at", "updated_at" ], "properties": { "id": { "type": "string" }, "alias": { "type": "string" }, "repo": { "type": "string" }, "filename": { "type": "string" }, "snapshot": { "type": "string" }, "source": { "type": "string" }, "model_params": { "type": "object", "additionalProperties": {}, "propertyNames": { "type": "string" } }, "request_params": { "$ref": "#/components/schemas/OAIRequestParams" }, "context_params": { "type": "array", "items": { "type": "string" } }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" }, "metadata": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ModelMetadata", "description": "Model metadata extracted from GGUF file (optional)" } ] } } }, "UserInfo": { "type": "object", "required": [ "user_id", "username" ], "properties": { "user_id": { "type": "string", "example": "550e8400-e29b-41d4-a716-446655440000" }, "username": { "type": "string", "example": "user@example.com" }, "first_name": { "type": [ "string", "null" ], "example": "John" }, "last_name": { "type": [ "string", "null" ], "example": "Doe" }, "role": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/AppRole" } ] } } }, "UserInfoEnvelope": { "allOf": [ { "$ref": "#/components/schemas/UserResponse", "description": "Core user authentication response" }, { "type": "object", "properties": { "dashboard": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/DashboardUser", "description": "Dashboard user info when a validated dashboard session exists" } ] } } } ], "description": "Envelope wrapping UserResponse with additional session info" }, "UserListResponse": { "type": "object", "required": [ "client_id", "users", "page", "page_size", "total_pages", "total_users", "has_next", "has_previous" ], "properties": { "client_id": { "type": "string", "example": "resource-abc123def456" }, "users": { "type": "array", "items": { "$ref": "#/components/schemas/UserInfo" } }, "page": { "type": "integer", "format": "int32", "example": 1, "minimum": 0 }, "page_size": { "type": "integer", "format": "int32", "example": 10, "minimum": 0 }, "total_pages": { "type": "integer", "format": "int32", "example": 5, "minimum": 0 }, "total_users": { "type": "integer", "format": "int32", "example": 45, "minimum": 0 }, "has_next": { "type": "boolean", "example": true }, "has_previous": { "type": "boolean", "example": false } } }, "UserResponse": { "oneOf": [ { "type": "object", "description": "User is not authenticated", "required": [ "auth_status" ], "properties": { "auth_status": { "type": "string", "enum": [ "logged_out" ] } } }, { "allOf": [ { "$ref": "#/components/schemas/UserInfo", "description": "User is authenticated with details" }, { "type": "object", "required": [ "auth_status" ], "properties": { "auth_status": { "type": "string", "enum": [ "logged_in" ] } } } ], "description": "User is authenticated with details" }, { "allOf": [ { "$ref": "#/components/schemas/TokenInfo", "description": "API token authentication" }, { "type": "object", "required": [ "auth_status" ], "properties": { "auth_status": { "type": "string", "enum": [ "api_token" ] } } } ], "description": "API token authentication" } ], "description": "User authentication response with discriminated union", "example": { "auth_status": "logged_in", "role": "resource_user", "user_id": "550e8400-e29b-41d4-a716-446655440000", "username": "user@example.com" } }, "UserScope": { "type": "string", "enum": [ "scope_user_user", "scope_user_power_user" ] } }, "securitySchemes": { "bearer_api_token": { "type": "http", "scheme": "bearer", "bearerFormat": "bodhiapp_", "description": "API token authentication. Create tokens via web interface at Menu > Settings > API Tokens. Format: 'bodhiapp_'. Use as: Authorization: Bearer \n\nScopes:\n- scope_token_user: Basic API access - read operations\n- scope_token_power_user: Advanced operations - create/update models, downloads\n- scope_token_manager: User management operations\n- scope_token_admin: Full administrative access" }, "bearer_oauth_token": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT", "description": "OAuth 2.1 token exchange authentication. External OAuth providers can exchange tokens with UserScope claims for access to Bodhi resources. Use as: Authorization: Bearer \n\nScopes:\n- scope_user_user: Basic user access via OAuth 2.1 token exchange\n- scope_user_power_user: Advanced user operations via OAuth 2.1 token exchange\n- scope_user_manager: Manager operations via OAuth 2.1 token exchange\n- scope_user_admin: Admin operations via OAuth 2.1 token exchange" }, "session_auth": { "type": "oauth2", "flows": { "authorizationCode": { "authorizationUrl": "/bodhi/v1/auth/initiate", "tokenUrl": "/bodhi/v1/auth/callback", "scopes": { "resource_admin": "Admin operations via browser session (session-only)", "resource_manager": "Manager operations via browser session (session-only)", "resource_power_user": "Power user operations via browser session", "resource_user": "Basic authenticated user access via browser session" } } }, "description": "Browser session authentication. Login via /bodhi/v1/auth/initiate. Some operations (token management, settings, user management) require session authentication only." } } }, "tags": [ { "name": "system", "description": "System information and operations" }, { "name": "setup", "description": "Application setup and initialization" }, { "name": "auth", "description": "Authentication and session management" }, { "name": "api-keys", "description": "API keys management" }, { "name": "models", "description": "Model files and aliases" }, { "name": "models-alias", "description": "User-created model aliases" }, { "name": "models-api", "description": "Remote AI API model configuration" }, { "name": "models-files", "description": "Local model files and downloads" }, { "name": "settings", "description": "Application settings management" }, { "name": "mcps", "description": "MCP server management and tool execution" }, { "name": "apps", "description": "External app API endpoints (OAuth token required)" }, { "name": "tenants", "description": "Tenant management endpoints" } ], "externalDocs": { "url": "https://getbodhi.app/docs/api", "description": "Find more info here" } }