{
  "openapi": "3.1.1",
  "info": {
    "title": "PaRi Portfolio API",
    "version": "1.0.0",
    "description": "Versioned, read-only JSON-RPC API for discovering public PaRi Portfolio identity, capabilities, and case studies. The canonical API is /api/v1/mcp. The legacy /api/mcp alias is deprecated and the API publishes a 60-request, 60-second advisory rate-limit policy. The API exposes no private data or mutation operations."
  },
  "servers": [
    { "url": "https://pari-portfolio-brown.vercel.app" }
  ],
  "paths": {
    "/api/v1/mcp": {
      "post": {
        "operationId": "mcpJsonRpcRequestV1",
        "summary": "Send an MCP JSON-RPC request",
        "description": "Canonical v1 endpoint. Initialize the read-only MCP server, list its tools, or call get_portfolio/get_project. Clients should send MCP-Protocol-Version: 2025-06-18 after initialization and accept application/json or text/event-stream.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/McpRequest" },
              "examples": {
                "initialize": { "value": { "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2025-06-18", "capabilities": {}, "clientInfo": { "name": "example-client", "version": "1.0.0" } } } },
                "getProject": { "value": { "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "get_project", "arguments": { "slug": "cashlift" } } } }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A JSON-RPC MCP result or protocol error.",
            "headers": { "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" }, "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" }, "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" }, "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" } },
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/McpResponse" } } }
          },
          "202": {
            "description": "A JSON-RPC notification was accepted without a response body."
          },
          "400": {
            "description": "Malformed JSON-RPC request.",
            "headers": { "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" }, "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" }, "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" }, "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" } },
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/McpResponse" } } }
          },
          "405": {
            "description": "The method is not supported at this endpoint.",
            "headers": { "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" }, "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" }, "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" }, "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" } },
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HttpError" } } }
          },
          "429": {
            "description": "The hosting platform has temporarily rate-limited the client.",
            "headers": { "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" }, "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" }, "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" }, "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" }, "Retry-After": { "$ref": "#/components/headers/RetryAfter" } },
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HttpError" } } }
          }
        }
      }
    },
    "/api/mcp": {
      "post": {
        "deprecated": true,
        "operationId": "mcpJsonRpcRequestLegacy",
        "summary": "Legacy MCP JSON-RPC compatibility alias",
        "description": "Deprecated compatibility alias for /api/v1/mcp. Migrate to the versioned endpoint and follow the Deprecation and successor Link response headers.",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/McpRequest" } } } },
        "responses": {
          "200": { "description": "A JSON-RPC MCP result or protocol error.", "headers": { "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" }, "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" }, "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" }, "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/McpResponse" } } } },
          "202": { "description": "A JSON-RPC notification was accepted without a response body." },
          "400": { "description": "Malformed JSON-RPC request.", "headers": { "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" }, "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" }, "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" }, "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/McpResponse" } } } },
          "405": { "description": "The method is not supported at this endpoint.", "headers": { "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" }, "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" }, "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" }, "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HttpError" } } } },
          "429": { "description": "The hosting platform has temporarily rate-limited the client.", "headers": { "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" }, "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" }, "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" }, "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" }, "Retry-After": { "$ref": "#/components/headers/RetryAfter" } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HttpError" } } } }
        }
      }
    }
  },
  "components": {
    "headers": {
      "RateLimitLimit": { "description": "Maximum requests in the current 60-second advisory window.", "schema": { "type": "integer", "example": 60 } },
      "RateLimitRemaining": { "description": "Requests remaining in the current advisory window.", "schema": { "type": "integer", "example": 60 } },
      "RateLimitReset": { "description": "Seconds until the advisory window resets.", "schema": { "type": "integer", "example": 60 } },
      "RateLimitPolicy": { "description": "The 60-request, 60-second advisory policy.", "schema": { "type": "string", "example": "60;w=60" } },
      "RetryAfter": { "description": "Seconds to wait before retrying after a 429 response.", "schema": { "oneOf": [{ "type": "integer" }, { "type": "string", "format": "http-date" }] } }
    },
    "schemas": {
      "McpRequest": {
        "oneOf": [
          { "$ref": "#/components/schemas/InitializeRequest" },
          { "$ref": "#/components/schemas/ToolsListRequest" },
          { "$ref": "#/components/schemas/ToolCallRequest" }
        ],
        "description": "A supported JSON-RPC 2.0 request for the PaRi Portfolio MCP endpoint."
      },
      "InitializeRequest": {
        "type": "object",
        "required": ["jsonrpc", "id", "method", "params"],
        "properties": {
          "jsonrpc": { "const": "2.0" },
          "id": { "type": ["string", "integer"] },
          "method": { "const": "initialize" },
          "params": { "$ref": "#/components/schemas/InitializeParams" }
        },
        "additionalProperties": false
      },
      "InitializeParams": {
        "type": "object",
        "required": ["protocolVersion", "capabilities", "clientInfo"],
        "properties": {
          "protocolVersion": { "type": "string", "description": "The MCP protocol version requested by the client.", "examples": ["2025-06-18"] },
          "capabilities": { "type": "object", "description": "Client capability declarations." },
          "clientInfo": { "$ref": "#/components/schemas/ImplementationInfo" }
        },
        "additionalProperties": true
      },
      "ToolsListRequest": {
        "type": "object",
        "required": ["jsonrpc", "id", "method"],
        "properties": {
          "jsonrpc": { "const": "2.0" },
          "id": { "type": ["string", "integer"] },
          "method": { "const": "tools/list" },
          "params": { "type": "object", "additionalProperties": false }
        },
        "additionalProperties": false
      },
      "ToolCallRequest": {
        "type": "object",
        "required": ["jsonrpc", "id", "method", "params"],
        "properties": {
          "jsonrpc": { "const": "2.0" },
          "id": { "type": ["string", "integer"] },
          "method": { "const": "tools/call" },
          "params": { "$ref": "#/components/schemas/ToolCallParams" }
        },
        "additionalProperties": false
      },
      "ToolCallParams": {
        "type": "object",
        "required": ["name"],
        "properties": {
          "name": { "type": "string", "enum": ["get_portfolio", "get_project"], "description": "The read-only portfolio tool to call." },
          "arguments": { "type": "object", "properties": { "slug": { "type": "string", "enum": ["cashlift", "mydears", "devbrief"], "description": "Case-study slug, required for get_project." } }, "additionalProperties": false }
        },
        "additionalProperties": false
      },
      "McpResponse": {
        "type": "object",
        "required": ["jsonrpc"],
        "properties": {
          "jsonrpc": { "const": "2.0" },
          "id": { "type": ["string", "integer", "null"] },
          "result": { "type": "object", "description": "Successful MCP result." },
          "error": { "$ref": "#/components/schemas/JsonRpcError" }
        },
        "oneOf": [{ "required": ["result"], "not": { "required": ["error"] } }, { "required": ["error"], "not": { "required": ["result"] } }],
        "additionalProperties": false
      },
      "JsonRpcError": {
        "type": "object",
        "required": ["code", "message"],
        "properties": { "code": { "type": "integer", "description": "JSON-RPC error code." }, "message": { "type": "string" }, "data": {} },
        "additionalProperties": true
      },
      "HttpError": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "object",
            "required": ["code", "message", "hint"],
            "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "hint": { "type": "string" }, "path": { "type": ["string", "null"] } },
            "additionalProperties": false
          }
        },
        "additionalProperties": false
      },
      "ImplementationInfo": {
        "type": "object",
        "required": ["name", "version"],
        "properties": { "name": { "type": "string" }, "version": { "type": "string" } },
        "additionalProperties": false
      }
    }
  }
}
