{
  "openapi": "3.1.0",
  "info": {
    "title": "FreedomOS MCP API",
    "version": "2026-09-22",
    "summary": "The one HTTP API FreedomOS serves: its MCP server.",
    "description": "FreedomOS has one HTTP API: its MCP server (Model Context Protocol, Streamable HTTP transport) at https://getfreedomos.com/api/mcp. Each request is one JSON-RPC 2.0 message sent by POST. The server speaks MCP protocol version 2024-11-05, which `initialize` returns. Each tool's arguments are described by its `inputSchema` in `tools/list`.\n\nEvery message to this endpoint needs a bearer token: a request without one answers 401 with the sign-in challenge, so MCP hosts start sign-in. To read the tool catalog before signing in, send `initialize`, `tools/list`, and the `notifications/initialized` notification to the directory listing URL https://getfreedomos.com/api/mcp/directory instead. The token comes from either:\n\n- FreedomOS sign-in (OAuth 2.0 authorization code with PKCE S256 and dynamic client registration). The authorization server is named in the RFC 9728 metadata at https://getfreedomos.com/.well-known/oauth-protected-resource/api/mcp, and the 401 answer points there in its WWW-Authenticate header. The site's API catalog (RFC 9727) is at https://getfreedomos.com/.well-known/api-catalog.\n- A personal key created at https://getfreedomos.com/mcp (sign-in required), for hosts that cannot run OAuth.\n\nFreedomOS does not use OAuth scopes. What a signed-in connection can do is decided inside FreedomOS by the person's role in each company and that company's approval rules, not by the token.",
    "contact": {
      "name": "FreedomOS",
      "url": "https://getfreedomos.com"
    }
  },
  "externalDocs": {
    "description": "Site summary for AI agents, including how to connect",
    "url": "https://getfreedomos.com/llms.txt"
  },
  "servers": [{ "url": "https://getfreedomos.com" }],
  "paths": {
    "/api/mcp": {
      "post": {
        "operationId": "sendMcpMessage",
        "summary": "Send one MCP JSON-RPC message",
        "description": "Send one JSON-RPC 2.0 message to the FreedomOS MCP server. Every message answers 401 until the request carries `Authorization: Bearer <token>`; the catalog before sign-in is at https://getfreedomos.com/api/mcp/directory (`initialize`, `tools/list`, `notifications/initialized` only). Tool arguments and results are described per tool by `tools/list` (JSON Schema `inputSchema` on every tool).",
        "security": [
          { "freedomosSignIn": [] },
          { "personalKey": [] }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/JsonRpcRequest" },
              "examples": {
                "initialize": {
                  "summary": "Open a session",
                  "value": {
                    "jsonrpc": "2.0",
                    "id": 1,
                    "method": "initialize",
                    "params": {
                      "protocolVersion": "2024-11-05",
                      "capabilities": {},
                      "clientInfo": {
                        "name": "example-client",
                        "version": "1.0.0"
                      }
                    }
                  }
                },
                "listTools": {
                  "summary": "Read the tool catalog",
                  "value": {
                    "jsonrpc": "2.0",
                    "id": 2,
                    "method": "tools/list",
                    "params": {}
                  }
                },
                "callTool": {
                  "summary": "Call a tool",
                  "value": {
                    "jsonrpc": "2.0",
                    "id": 3,
                    "method": "tools/call",
                    "params": {
                      "name": "get_my_companies",
                      "arguments": {}
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The JSON-RPC response. A failed tool call is still a 200: its `result.isError` is true and `result.content` says why.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/JsonRpcResponse" }
              }
            }
          },
          "202": { "description": "Accepted: a notification (a message with no `id`, such as `notifications/initialized`). No body." },
          "401": {
            "description": "Sign-in required. `WWW-Authenticate` names the RFC 9728 metadata URL that leads to the authorization server. A `tools/call` gets a JSON-RPC body whose `result.isError` is true; other requests get `{\"error\":{\"message\":\"Unauthorized\"}}`.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer challenge, for example: Bearer resource_metadata=\"https://getfreedomos.com/.well-known/oauth-protected-resource/api/mcp\", error=\"invalid_token\", error_description=\"Authentication required\"",
                "schema": { "type": "string" }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    { "$ref": "#/components/schemas/McpHttpError" },
                    { "$ref": "#/components/schemas/JsonRpcResponse" }
                  ]
                }
              }
            }
          },
          "502": {
            "description": "The MCP server could not be reached. Retry shortly.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/GatewayError" }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "freedomosSignIn": {
        "type": "oauth2",
        "description": "Sign in with FreedomOS. Authorization code flow with PKCE (S256); public clients may register themselves at https://twuluxmoognlwtmaoqgo.supabase.co/auth/v1/oauth/clients/register. Discovery starts at https://getfreedomos.com/.well-known/oauth-protected-resource/api/mcp. No scopes are defined: access is decided inside FreedomOS by the person's role in each company.",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://twuluxmoognlwtmaoqgo.supabase.co/auth/v1/oauth/authorize",
            "tokenUrl": "https://twuluxmoognlwtmaoqgo.supabase.co/auth/v1/oauth/token",
            "refreshUrl": "https://twuluxmoognlwtmaoqgo.supabase.co/auth/v1/oauth/token",
            "scopes": {}
          }
        }
      },
      "personalKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "A personal key created at https://getfreedomos.com/mcp (sign-in required), sent as `Authorization: Bearer <key>`. For hosts that cannot run OAuth."
      }
    },
    "schemas": {
      "JsonRpcId": {
        "description": "Request id; echoed on the response.",
        "oneOf": [
          { "type": "string" },
          { "type": "integer" }
        ]
      },
      "JsonRpcRequest": {
        "type": "object",
        "description": "One JSON-RPC 2.0 message. Omit `id` for a notification.",
        "required": ["jsonrpc", "method"],
        "properties": {
          "jsonrpc": {
            "type": "string",
            "const": "2.0"
          },
          "id": { "$ref": "#/components/schemas/JsonRpcId" },
          "method": {
            "type": "string",
            "description": "The MCP method, for example `initialize`, `tools/list`, or `tools/call`."
          },
          "params": {
            "type": "object",
            "description": "Method parameters. For `tools/call`: `name` (a tool from `tools/list`) and `arguments` (matching that tool's `inputSchema`).",
            "additionalProperties": true
          }
        }
      },
      "JsonRpcResponse": {
        "type": "object",
        "description": "A JSON-RPC 2.0 response: `result` on success, `error` on a protocol failure.",
        "required": ["jsonrpc"],
        "properties": {
          "jsonrpc": {
            "type": "string",
            "const": "2.0"
          },
          "id": { "$ref": "#/components/schemas/JsonRpcId" },
          "result": {
            "type": "object",
            "description": "Method result. Tool results carry `content` (an array of content blocks) and `isError`.",
            "additionalProperties": true
          },
          "error": { "$ref": "#/components/schemas/JsonRpcError" }
        }
      },
      "JsonRpcError": {
        "type": "object",
        "description": "A JSON-RPC 2.0 error object.",
        "required": ["code", "message"],
        "properties": {
          "code": {
            "type": "integer",
            "description": "JSON-RPC error code, for example -32601 (method not found) or -32602 (invalid params)."
          },
          "message": { "type": "string" },
          "data": { "description": "Optional detail." }
        }
      },
      "McpHttpError": {
        "type": "object",
        "description": "Error body for a request refused before it reaches a JSON-RPC method, such as a missing or invalid token.",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "object",
            "required": ["message"],
            "properties": {
              "message": {
                "type": "string",
                "examples": ["Unauthorized"]
              }
            }
          }
        }
      },
      "GatewayError": {
        "type": "object",
        "description": "Error body when the MCP server cannot be reached.",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "string",
            "examples": ["Upstream unavailable"]
          }
        }
      },
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem document, returned with status 404 and `application/problem+json` for any /api/ path that does not exist.",
        "required": ["type", "title", "status"],
        "properties": {
          "type": {
            "type": "string",
            "examples": ["about:blank"]
          },
          "title": { "type": "string" },
          "status": { "type": "integer" },
          "code": {
            "type": "string",
            "description": "Machine-readable error code, for example `not_found`."
          },
          "detail": { "type": "string" },
          "docs": {
            "type": "string",
            "format": "uri",
            "description": "Where to read about the API."
          }
        }
      }
    }
  }
}
