{
  "openapi": "3.1.1",
  "info": {
    "title": "LegoTechApps Developer API",
    "version": "1.0.0",
    "description": "Public, machine-readable discovery for LegoTechApps integrations and its remote MCP server. REST resources use major-version URL paths. Authenticated product operations are available only to accounts with the relevant module and permissions.",
    "termsOfService": "https://legotechapps.com/terms.html",
    "contact": {
      "name": "LegoTechApps developer support",
      "url": "https://legotechapps.com/developers/",
      "email": "ofir@legotechapps.com"
    }
  },
  "servers": [
    {
      "url": "https://legotechapps.com",
      "description": "LegoTechApps production origin"
    }
  ],
  "tags": [
    { "name": "Discovery", "description": "Unauthenticated product and contract discovery." },
    { "name": "MCP", "description": "Public, read-only Model Context Protocol discovery tools." }
  ],
  "paths": {
    "/api/v1/": {
      "get": {
        "tags": ["Discovery"],
        "summary": "Read the LegoTechApps v1 API index",
        "description": "Returns stable links to the developer portal, version policy, OpenAPI contract, and authenticated MCP endpoint. Use this operation as the first REST discovery call.",
        "operationId": "getLegoTechApiV1Index",
        "parameters": [
          { "$ref": "#/components/parameters/ContractLocale" }
        ],
        "responses": {
          "200": {
            "description": "The v1 discovery document.",
            "headers": {
              "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
              "RateLimit": { "$ref": "#/components/headers/RateLimit" }
            },
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/ApiIndex" } }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "405": { "$ref": "#/components/responses/MethodNotAllowed" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/ServerError" },
          "default": {
            "description": "An unexpected REST failure represented as RFC 9457 Problem Details.",
            "content": {
              "application/problem+json": { "schema": { "$ref": "#/components/schemas/Problem" } }
            }
          }
        }
      }
    },
    "/api/v1/policy": {
      "get": {
        "tags": ["Discovery"],
        "summary": "Read the REST version and deprecation policy",
        "description": "Explains URL-path major versioning, compatibility guarantees, RFC 9745 Deprecation signalling, Sunset timing, errors, and rate-limit conventions.",
        "operationId": "getLegoTechApiVersionPolicy",
        "parameters": [
          { "$ref": "#/components/parameters/ContractLocale" }
        ],
        "responses": {
          "200": {
            "description": "The current public API lifecycle policy.",
            "headers": {
              "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
              "RateLimit": { "$ref": "#/components/headers/RateLimit" }
            },
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/VersionPolicy" } }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "405": { "$ref": "#/components/responses/MethodNotAllowed" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/ServerError" },
          "default": {
            "description": "An unexpected REST failure represented as RFC 9457 Problem Details.",
            "content": {
              "application/problem+json": { "schema": { "$ref": "#/components/schemas/Problem" } }
            }
          }
        }
      }
    },
    "/mcp": {
      "post": {
        "tags": ["MCP"],
        "summary": "Call the public LegoTechApps MCP discovery server",
        "description": "Stateless Streamable HTTP endpoint implementing Model Context Protocol discovery. Its tools return only public developer, lifecycle, and trust resources. Permissioned business tools remain on the separately authenticated account MCP endpoint.",
        "operationId": "callLegoTechPublicMcp",
        "parameters": [
          {
            "name": "MCP-Protocol-Version",
            "in": "header",
            "required": false,
            "description": "MCP protocol version requested by the client. The current supported version is returned in the response header.",
            "schema": { "type": "string", "example": "2025-06-18" }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "A typed JSON-RPC 2.0 MCP request, including initialize, ping, tools/list, or tools/call.",
          "content": {
            "application/json": { "schema": { "$ref": "#/components/schemas/JsonRpcRequest" } }
          }
        },
        "responses": {
          "200": {
            "description": "A successful result or protocol-level JSON-RPC error.",
            "headers": {
              "MCP-Protocol-Version": { "schema": { "type": "string", "example": "2025-06-18" } },
              "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
              "RateLimit": { "$ref": "#/components/headers/RateLimit" }
            },
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/JsonRpcResponse" } },
              "text/event-stream": { "schema": { "type": "string", "description": "MCP server-sent event stream." } }
            }
          },
          "202": {
            "description": "An MCP notification was accepted. Notifications do not have response bodies."
          },
          "400": { "$ref": "#/components/responses/McpRequestError" },
          "403": { "$ref": "#/components/responses/McpForbidden" },
          "405": { "$ref": "#/components/responses/McpMethodNotAllowed" },
          "429": { "$ref": "#/components/responses/McpRateLimited" },
          "500": { "$ref": "#/components/responses/McpServerError" },
          "default": {
            "description": "An unexpected MCP transport or JSON-RPC failure.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/JsonRpcErrorResponse" } }
            }
          }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "ContractLocale": {
        "name": "locale",
        "in": "query",
        "required": false,
        "description": "Language of the machine-readable contract. English is currently available.",
        "schema": { "type": "string", "enum": ["en"], "default": "en" }
      }
    },
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "LegoTechApps API key",
        "description": "A scoped key created by an authorized user in the LegoTechApps dashboard. Keys are read-only unless write access is explicitly granted."
      }
    },
    "headers": {
      "RateLimitPolicy": {
        "description": "IETF HTTPAPI quota policy for the resource.",
        "schema": { "type": "string", "example": "\"public\";q=60;w=60" }
      },
      "RateLimit": {
        "description": "Current remaining quota and seconds until reset.",
        "schema": { "type": "string", "example": "\"public\";r=59;t=60" }
      },
      "RetryAfter": {
        "description": "Seconds the client should wait before retrying.",
        "schema": { "type": "integer", "minimum": 1, "example": 42 }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "The request could not be parsed or validated.",
        "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/Problem" } } }
      },
      "MethodNotAllowed": {
        "description": "The resource does not support this HTTP method.",
        "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/Problem" } } }
      },
      "Unauthorized": {
        "description": "A valid, appropriately scoped API key is required.",
        "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/Problem" } } }
      },
      "RateLimited": {
        "description": "The current request quota has been exhausted.",
        "headers": {
          "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
          "RateLimit": { "$ref": "#/components/headers/RateLimit" },
          "Retry-After": { "$ref": "#/components/headers/RetryAfter" }
        },
        "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/Problem" } } }
      },
      "ServerError": {
        "description": "The server could not complete a valid request.",
        "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/Problem" } } }
      },
      "McpRequestError": {
        "description": "The MCP JSON-RPC request could not be parsed or validated.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/JsonRpcErrorResponse" } } }
      },
      "McpForbidden": {
        "description": "The supplied browser Origin is malformed, opaque, or does not use HTTPS. Server-side MCP clients normally send no Origin header.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/JsonRpcErrorResponse" } } }
      },
      "McpMethodNotAllowed": {
        "description": "The public MCP endpoint accepts POST and OPTIONS only.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/JsonRpcErrorResponse" } } }
      },
      "McpRateLimited": {
        "description": "The current MCP request quota has been exhausted.",
        "headers": {
          "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
          "RateLimit": { "$ref": "#/components/headers/RateLimit" },
          "Retry-After": { "$ref": "#/components/headers/RetryAfter" }
        },
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/JsonRpcErrorResponse" } } }
      },
      "McpServerError": {
        "description": "The MCP server could not complete a valid JSON-RPC request.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/JsonRpcErrorResponse" } } }
      }
    },
    "schemas": {
      "ApiIndex": {
        "type": "object",
        "additionalProperties": false,
        "required": ["name", "locale", "api_version", "status", "documentation", "openapi", "version_policy", "mcp"],
        "properties": {
          "name": { "type": "string", "description": "Product API name.", "example": "LegoTechApps Public API" },
          "locale": { "type": "string", "const": "en", "description": "Language of this contract response." },
          "api_version": { "type": "string", "description": "Major REST API version.", "const": "v1" },
          "status": { "type": "string", "description": "Lifecycle status of this major version.", "enum": ["stable", "deprecated"] },
          "documentation": { "type": "string", "format": "uri", "description": "Human-readable developer portal." },
          "openapi": { "type": "string", "format": "uri", "description": "OpenAPI 3.1 contract." },
          "version_policy": { "type": "string", "format": "uri", "description": "Machine-readable lifecycle policy." },
          "mcp": { "$ref": "#/components/schemas/McpService" }
        }
      },
      "McpService": {
        "type": "object",
        "additionalProperties": false,
        "required": ["transport", "endpoint", "manifest", "authentication", "authenticated_business_endpoint"],
        "properties": {
          "transport": { "type": "string", "const": "streamable-http", "description": "MCP remote transport." },
          "endpoint": { "type": "string", "format": "uri", "description": "Remote MCP endpoint." },
          "manifest": { "type": "string", "format": "uri", "description": "MCP Registry server.json metadata." },
          "authentication": { "type": "string", "description": "Credential acquisition and transport summary." },
          "authenticated_business_endpoint": { "type": "string", "format": "uri", "description": "Separate MCP endpoint for scoped account tools." }
        }
      },
      "VersionPolicy": {
        "type": "object",
        "additionalProperties": false,
        "required": ["current_version", "locale", "strategy", "compatibility", "deprecation", "sunset", "errors", "rate_limits"],
        "properties": {
          "current_version": { "type": "string", "const": "v1" },
          "locale": { "type": "string", "const": "en" },
          "strategy": { "type": "string" },
          "compatibility": { "type": "string" },
          "deprecation": { "type": "string" },
          "sunset": { "type": "string" },
          "errors": { "type": "string" },
          "rate_limits": { "type": "string" }
        }
      },
      "Problem": {
        "type": "object",
        "description": "RFC 9457 Problem Details with stable LegoTechApps extension members.",
        "additionalProperties": true,
        "required": ["type", "title", "status", "detail", "instance", "code", "hint"],
        "properties": {
          "type": { "type": "string", "format": "uri-reference", "description": "Problem type documentation URI." },
          "title": { "type": "string", "description": "Stable summary of the problem type." },
          "status": { "type": "integer", "minimum": 400, "maximum": 599, "description": "HTTP status code." },
          "detail": { "type": "string", "description": "Human-readable detail for this occurrence." },
          "instance": { "type": "string", "format": "uri-reference", "description": "URI reference identifying this occurrence." },
          "code": { "type": "string", "pattern": "^[A-Z][A-Z0-9_]+$", "description": "Machine-readable LegoTechApps error code." },
          "hint": { "type": "string", "description": "A safe resolution hint for an agent or developer." }
        }
      },
      "JsonRpcRequest": {
        "description": "A fully typed request supported by the public MCP discovery server.",
        "oneOf": [
          { "$ref": "#/components/schemas/McpInitializeRequest" },
          { "$ref": "#/components/schemas/McpPingRequest" },
          { "$ref": "#/components/schemas/McpToolsListRequest" },
          { "$ref": "#/components/schemas/McpToolsCallRequest" },
          { "$ref": "#/components/schemas/McpInitializedNotification" }
        ]
      },
      "JsonRpcId": {
        "oneOf": [{ "type": "string" }, { "type": "integer" }],
        "description": "JSON-RPC request correlation identifier."
      },
      "McpInitializeRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["jsonrpc", "method", "params", "id"],
        "properties": {
          "jsonrpc": { "type": "string", "const": "2.0" },
          "method": { "type": "string", "const": "initialize" },
          "params": {
            "type": "object",
            "additionalProperties": false,
            "required": ["protocolVersion", "capabilities", "clientInfo"],
            "properties": {
              "protocolVersion": { "type": "string", "example": "2025-06-18" },
              "capabilities": { "type": "object", "additionalProperties": true },
              "clientInfo": {
                "type": "object",
                "additionalProperties": false,
                "required": ["name", "version"],
                "properties": {
                  "name": { "type": "string", "minLength": 1 },
                  "version": { "type": "string", "minLength": 1 }
                }
              }
            }
          },
          "id": { "$ref": "#/components/schemas/JsonRpcId" }
        }
      },
      "McpPingRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["jsonrpc", "method", "id"],
        "properties": {
          "jsonrpc": { "type": "string", "const": "2.0" },
          "method": { "type": "string", "const": "ping" },
          "id": { "$ref": "#/components/schemas/JsonRpcId" }
        }
      },
      "McpToolsListRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["jsonrpc", "method", "id"],
        "properties": {
          "jsonrpc": { "type": "string", "const": "2.0" },
          "method": { "type": "string", "const": "tools/list" },
          "params": {
            "type": "object",
            "additionalProperties": false,
            "properties": { "cursor": { "type": "string" } }
          },
          "id": { "$ref": "#/components/schemas/JsonRpcId" }
        }
      },
      "McpToolsCallRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["jsonrpc", "method", "params", "id"],
        "properties": {
          "jsonrpc": { "type": "string", "const": "2.0" },
          "method": { "type": "string", "const": "tools/call" },
          "params": {
            "type": "object",
            "additionalProperties": false,
            "required": ["name", "arguments"],
            "properties": {
              "name": {
                "type": "string",
                "enum": ["legotech_get_api_index", "legotech_get_version_policy", "legotech_get_developer_resources"]
              },
              "arguments": { "type": "object", "additionalProperties": false, "properties": {} }
            }
          },
          "id": { "$ref": "#/components/schemas/JsonRpcId" }
        }
      },
      "McpInitializedNotification": {
        "type": "object",
        "additionalProperties": false,
        "required": ["jsonrpc", "method"],
        "properties": {
          "jsonrpc": { "type": "string", "const": "2.0" },
          "method": { "type": "string", "const": "notifications/initialized" }
        }
      },
      "JsonRpcResponse": {
        "oneOf": [
          { "$ref": "#/components/schemas/JsonRpcSuccessResponse" },
          { "$ref": "#/components/schemas/JsonRpcErrorResponse" }
        ]
      },
      "JsonRpcSuccessResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": ["jsonrpc", "id", "result"],
        "properties": {
          "jsonrpc": { "type": "string", "const": "2.0" },
          "result": { "type": "object", "additionalProperties": true, "description": "Method-specific successful result." },
          "id": { "oneOf": [{ "type": "string" }, { "type": "integer" }, { "type": "null" }] }
        }
      },
      "JsonRpcError": {
        "type": "object",
        "additionalProperties": false,
        "required": ["code", "message"],
        "properties": {
          "code": { "type": "integer", "description": "JSON-RPC error code." },
          "message": { "type": "string", "description": "Stable JSON-RPC error summary." },
          "data": {
            "type": "object",
            "additionalProperties": true,
            "properties": { "hint": { "type": "string", "description": "Safe resolution guidance." } }
          }
        }
      },
      "JsonRpcErrorResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": ["jsonrpc", "id", "error"],
        "properties": {
          "jsonrpc": { "type": "string", "const": "2.0" },
          "error": { "$ref": "#/components/schemas/JsonRpcError" },
          "id": { "oneOf": [{ "type": "string" }, { "type": "integer" }, { "type": "null" }] }
        }
      }
    }
  }
}
