{
  "openapi": "3.1.0",
  "info": {
    "title": "AppDeploy MCP API",
    "version": "2.x",
    "description": "Public HTTP and OAuth discovery surface for the AppDeploy Model Context Protocol server. MCP JSON-RPC tool calls are sent to /mcp. The scope required for a tools/call request depends on the selected tool.",
    "termsOfService": "https://appdeploy.ai/terms",
    "contact": {
      "name": "AppDeploy Support",
      "email": "support@appdeploy.ai",
      "url": "https://appdeploy.ai/mcp-docs"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://appdeploy.ai/terms"
    }
  },
  "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
  "servers": [
    {
      "url": "https://api-v2.appdeploy.ai",
      "description": "Production floating v2 MCP endpoint"
    }
  ],
  "externalDocs": {
    "description": "AppDeploy MCP documentation",
    "url": "https://appdeploy.ai/mcp-docs"
  },
  "tags": [
    {
      "name": "MCP",
      "description": "Streamable HTTP transport for MCP JSON-RPC messages"
    },
    {
      "name": "OAuth discovery",
      "description": "RFC 8414 authorization-server metadata and RFC 9728 protected-resource metadata"
    }
  ],
  "paths": {
    "/mcp": {
      "post": {
        "tags": ["MCP"],
        "operationId": "sendMcpMessage",
        "summary": "Send an MCP JSON-RPC message",
        "description": "Sends MCP initialize, tools/list, tools/call, resources/list, resources/read, or notification messages. Read-only tools require deploy:read; deployment and app mutation tools require deploy:write; delete_app requires deploy:delete.",
        "security": [{ "AppDeployOAuth": [] }, { "AppDeployBearerToken": [] }],
        "parameters": [
          {
            "name": "Mcp-Session-Id",
            "in": "header",
            "required": false,
            "description": "Session identifier returned by a prior initialize response.",
            "schema": { "type": "string" }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/JsonRpcRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "MCP JSON-RPC response or event stream. A tools/call made with insufficient scope returns a successful JSON-RPC envelope whose tool result has isError: true and identifies the required scope.",
            "headers": {
              "Mcp-Session-Id": {
                "description": "Session identifier to send with subsequent MCP requests.",
                "schema": { "type": "string" }
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/JsonRpcResponse" }
              },
              "text/event-stream": {
                "schema": { "type": "string" }
              }
            }
          },
          "202": {
            "description": "Accepted notification with no response body"
          },
          "400": {
            "description": "Invalid JSON-RPC or MCP request",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/JsonRpcErrorResponse" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "406": { "$ref": "#/components/responses/NotAcceptable" },
          "415": { "$ref": "#/components/responses/UnsupportedMediaType" }
        },
        "x-appdeploy-tool-scopes": {
          "deploy:read": "Instructions, templates, SDK reference, app lists, status, versions, logs, and source inspection.",
          "deploy:write": "Create or update deployments, apply versions, update coding progress, domains, and secrets.",
          "deploy:delete": "Delete an app. This destructive scope is not required for read or write tools."
        }
      }
    },
    "/.well-known/oauth-protected-resource/mcp": {
      "get": {
        "tags": ["OAuth discovery"],
        "operationId": "getProtectedResourceMetadata",
        "summary": "Get RFC 9728 protected-resource metadata",
        "description": "Returns the authorization servers, OAuth scopes, and bearer-token delivery methods supported by the production AppDeploy MCP resource. MCP clients use this document to discover how to authenticate and which permission scopes are defined for the resource.",
        "security": [],
        "responses": {
          "200": {
            "description": "OAuth protected-resource metadata for the MCP endpoint",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ProtectedResourceMetadata" }
              }
            }
          },
          "404": {
            "description": "Protected-resource metadata path is not available"
          }
        }
      }
    },
    "/.well-known/oauth-authorization-server": {
      "get": {
        "tags": ["OAuth discovery"],
        "operationId": "getAuthorizationServerMetadata",
        "summary": "Get RFC 8414 authorization-server metadata",
        "description": "Returns the OAuth authorization, token, and dynamic client registration endpoints, plus the supported grants, PKCE methods, and scopes for AppDeploy MCP authentication.",
        "security": [],
        "responses": {
          "200": {
            "description": "OAuth authorization-server metadata",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/AuthorizationServerMetadata" }
              }
            }
          },
          "404": {
            "description": "Authorization-server metadata path is not available"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "AppDeployOAuth": {
        "type": "oauth2",
        "description": "OAuth 2.0 Authorization Code flow with PKCE and dynamic client registration. AppDeploy declares separate tool permission scopes for read, write, and delete operations.",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://api-v2.appdeploy.ai/mcp/authorize",
            "tokenUrl": "https://api-v2.appdeploy.ai/mcp/token",
            "scopes": {
              "deploy:read": "Read deployment instructions and SDK reference; list and inspect apps, deployment status, versions, logs, and source.",
              "deploy:write": "Create or update app deployments, apply versions, and change app configuration.",
              "deploy:delete": "Delete an app. Intended only for an explicit destructive delete operation."
            }
          }
        }
      },
      "AppDeployBearerToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "Bearer access token issued by AppDeploy OAuth or an AppDeploy API key for clients that cannot complete OAuth. OAuth is preferred because it declares scopes."
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing, expired, or invalid bearer token. Inspect WWW-Authenticate for the protected-resource metadata URL.",
        "headers": {
          "WWW-Authenticate": {
            "description": "Bearer challenge containing the RFC 9728 protected-resource metadata URL and, when applicable, an OAuth error.",
            "schema": { "type": "string" }
          }
        },
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/JsonRpcErrorResponse" },
            "example": {
              "jsonrpc": "2.0",
              "error": {
                "code": -32001,
                "message": "Authentication required",
                "data": { "error": "unauthorized" }
              },
              "id": null,
              "_meta": {
                "mcp/www_authenticate": "Bearer resource_metadata=\"https://api-v2.appdeploy.ai/.well-known/oauth-protected-resource/mcp\""
              }
            }
          }
        }
      },
      "NotAcceptable": {
        "description": "The request Accept header does not list both application/json and text/event-stream as supported response types.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/JsonRpcErrorResponse" },
            "example": {
              "jsonrpc": "2.0",
              "error": {
                "code": -32000,
                "message": "Not Acceptable: Client must accept both application/json and text/event-stream"
              },
              "id": null
            }
          }
        }
      },
      "UnsupportedMediaType": {
        "description": "The request Content-Type is not application/json.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/JsonRpcErrorResponse" },
            "example": {
              "jsonrpc": "2.0",
              "error": {
                "code": -32000,
                "message": "Unsupported Media Type: Content-Type must be application/json"
              },
              "id": null
            }
          }
        }
      }
    },
    "schemas": {
      "JsonRpcRequest": {
        "type": "object",
        "required": ["jsonrpc", "method"],
        "properties": {
          "jsonrpc": { "const": "2.0" },
          "id": {
            "oneOf": [{ "type": "string" }, { "type": "integer" }, { "type": "null" }]
          },
          "method": {
            "type": "string",
            "examples": ["initialize", "tools/list", "tools/call"]
          },
          "params": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "additionalProperties": false
      },
      "JsonRpcResponse": {
        "type": "object",
        "required": ["jsonrpc"],
        "properties": {
          "jsonrpc": { "const": "2.0" },
          "id": {
            "oneOf": [{ "type": "string" }, { "type": "integer" }, { "type": "null" }]
          },
          "result": {},
          "error": { "$ref": "#/components/schemas/JsonRpcError" }
        }
      },
      "JsonRpcError": {
        "type": "object",
        "required": ["code", "message"],
        "properties": {
          "code": { "type": "integer" },
          "message": { "type": "string" },
          "data": {}
        },
        "additionalProperties": false
      },
      "JsonRpcErrorResponse": {
        "type": "object",
        "required": ["jsonrpc", "error", "id"],
        "properties": {
          "jsonrpc": { "const": "2.0" },
          "error": { "$ref": "#/components/schemas/JsonRpcError" },
          "id": {
            "oneOf": [{ "type": "string" }, { "type": "integer" }, { "type": "null" }]
          },
          "_meta": {
            "type": "object",
            "properties": {
              "mcp/www_authenticate": { "type": "string" }
            },
            "additionalProperties": true
          }
        }
      },
      "ProtectedResourceMetadata": {
        "type": "object",
        "required": ["resource"],
        "properties": {
          "resource": {
            "type": "string",
            "format": "uri",
            "const": "https://api-v2.appdeploy.ai/mcp"
          },
          "authorization_servers": {
            "type": "array",
            "items": { "type": "string", "format": "uri" }
          },
          "scopes_supported": {
            "type": "array",
            "items": {
              "enum": ["deploy:read", "deploy:write", "deploy:delete"]
            }
          },
          "bearer_methods_supported": {
            "type": "array",
            "items": { "enum": ["header"] }
          }
        }
      },
      "AuthorizationServerMetadata": {
        "type": "object",
        "required": ["issuer", "authorization_endpoint", "token_endpoint"],
        "properties": {
          "issuer": { "type": "string", "format": "uri" },
          "authorization_endpoint": { "type": "string", "format": "uri" },
          "token_endpoint": { "type": "string", "format": "uri" },
          "registration_endpoint": { "type": "string", "format": "uri" },
          "response_types_supported": {
            "type": "array",
            "items": { "type": "string" }
          },
          "grant_types_supported": {
            "type": "array",
            "items": { "type": "string" }
          },
          "code_challenge_methods_supported": {
            "type": "array",
            "items": { "type": "string" }
          },
          "scopes_supported": {
            "type": "array",
            "items": {
              "enum": ["deploy:read", "deploy:write", "deploy:delete"]
            }
          }
        }
      }
    }
  }
}
