{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "profile_name": {
      "type": "string",
      "description": "Unique identifier for this profile",
      "examples": [
        "gitlab-developer",
        "github-readonly",
        "custom-api"
      ]
    },
    "profile_id": {
      "type": "string",
      "description": "Short ID used for selecting a profile via MCP4_PROFILE or --profile",
      "examples": [
        "gitlab",
        "semgrep",
        "youtrack"
      ]
    },
    "profile_aliases": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Alternate IDs that can be used to select this profile via MCP4_PROFILE or --profile",
      "examples": [
        [
          "gitlab-developer",
          "gitlab-default"
        ]
      ]
    },
    "openapi_spec_path": {
      "type": "string",
      "description": "OpenAPI spec path used when launching by profile without MCP4_OPENAPI_SPEC_PATH",
      "examples": [
        "./openapi.yaml",
        "../specs/openapi.json"
      ]
    },
    "description": {
      "type": "string",
      "description": "Human-readable description of what this profile provides"
    },
    "tools": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/Tool"
      },
      "description": "List of MCP tools defined in this profile"
    },
    "prompts": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/PromptDefinition"
      }
    },
    "interceptors": {
      "$ref": "#/definitions/Interceptors"
    },
    "parameter_aliases": {
      "$ref": "#/definitions/Record%3Cstring%2Cstring%5B%5D%3E",
      "description": "Map parameter names to their aliases (e.g., 'id' -> ['project_id', 'group_id'])",
      "examples": [
        {
          "id": [
            "project_id",
            "group_id",
            "resource_id"
          ]
        }
      ]
    },
    "resource_name": {
      "type": "string",
      "description": "OAuth 2.0 Protected Resource name (overrides OpenAPI info.title). Defaults to 'MCP Server' if not specified.",
      "examples": [
        "GitLab Production API",
        "GitHub Enterprise API"
      ]
    },
    "resource_documentation": {
      "type": "string",
      "description": "OAuth 2.0 Protected Resource documentation URL (overrides OpenAPI externalDocs.url). Omitted if not specified.",
      "examples": [
        "https://docs.gitlab.com/ee/api/",
        "https://docs.github.com/rest"
      ]
    }
  },
  "required": [
    "profile_name",
    "tools"
  ],
  "description": "Configuration schema for MCP from OpenAPI tool profiles",
  "definitions": {
    "Tool": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "Tool name (must be unique, lowercase with underscores)",
          "examples": [
            "manage_project_badges",
            "get_merge_request_with_details"
          ]
        },
        "description": {
          "type": "string",
          "description": "Clear description of what this tool does (shown to LLM)"
        },
        "operations": {
          "$ref": "#/definitions/Record%3Cstring%2COperationDefinition%3E",
          "description": "Map action names to OpenAPI operationIds or proxy download operations",
          "examples": [
            {
              "list": "getApiV4ProjectsIdBadges",
              "get": "getApiV4ProjectsIdBadgesBadgeId",
              "create": "postApiV4ProjectsIdBadges",
              "download_attachment": {
                "type": "proxy_download",
                "metadata_endpoint": "getApiV4ProjectsIdMergeRequestsMrIidNotesNoteId",
                "url_field": "attachment.url"
              }
            }
          ]
        },
        "composite": {
          "type": "boolean",
          "description": "If true, this tool chains multiple API calls",
          "default": false
        },
        "steps": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/CompositeStep"
          },
          "description": "Steps for composite tool execution"
        },
        "partial_results": {
          "type": "boolean",
          "description": "If true, return partial results even if some steps fail (composite only)",
          "default": false
        },
        "parameters": {
          "$ref": "#/definitions/Record%3Cstring%2CParameterDefinition%3E",
          "description": "Input parameters for this tool"
        },
        "metadata_params": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Parameter names that are metadata (not sent in API request body)",
          "examples": [
            [
              "action",
              "resource_type"
            ]
          ]
        },
        "response_fields": {
          "$ref": "#/definitions/Record%3Cstring%2Cstring%5B%5D%3E",
          "description": "Define which fields to include in response for each action (reduces verbosity)",
          "examples": [
            {
              "list": [
                "id",
                "name",
                "path",
                "web_url"
              ],
              "get": [
                "id",
                "name",
                "description",
                "web_url",
                "created_at"
              ]
            }
          ]
        },
        "send_response_fields_as_param": {
          "type": "boolean",
          "description": "If true, send response_fields as 'fields' query parameter (e.g. for YouTrack)",
          "default": false
        }
      },
      "required": [
        "name",
        "description",
        "parameters"
      ],
      "oneOf": [
        {
          "required": [
            "operations"
          ],
          "properties": {
            "operations": {
              "type": "object",
              "additionalProperties": {
                "oneOf": [
                  {
                    "type": "string",
                    "description": "OpenAPI operation ID"
                  },
                  {
                    "$ref": "#/definitions/ProxyDownloadOperation"
                  }
                ]
              }
            }
          }
        },
        {
          "required": [
            "steps",
            "composite"
          ],
          "properties": {
            "composite": {
              "const": true
            },
            "steps": {
              "type": "array"
            }
          }
        }
      ]
    },
    "Record<string,OperationDefinition>": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/definitions/OperationDefinition"
      }
    },
    "OperationDefinition": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "$ref": "#/definitions/ProxyDownloadOperation"
        }
      ],
      "description": "Extended operation definition supporting proxy_download"
    },
    "ProxyDownloadOperation": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "const": "proxy_download",
          "description": "Must be 'proxy_download'"
        },
        "metadata_endpoint": {
          "type": "string",
          "description": "OpenAPI operation ID to fetch metadata (e.g., 'get_/issues/{id}/attachments/{attachmentId}')"
        },
        "download_endpoint": {
          "type": "string",
          "description": "OpenAPI operation ID for direct download endpoint when metadata does not expose a URL"
        },
        "url_field": {
          "type": "string",
          "description": "JSON path to URL field in metadata response",
          "default": "url"
        },
        "max_size_bytes": {
          "type": "number",
          "description": "Maximum file size in bytes",
          "default": 10485760
        },
        "max_size_bytes_from_env": {
          "type": "string",
          "description": "Environment variable that overrides max_size_bytes when set"
        },
        "timeout_ms": {
          "type": "number",
          "description": "Timeout for download in milliseconds",
          "default": 30000
        },
        "allowed_mime_types": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Optional MIME type whitelist (e.g., ['image/*', 'application/pdf'])"
        },
        "skip_auth": {
          "type": "boolean",
          "description": "Skip authentication for download URL (default: false). Set to true for pre-signed URLs.",
          "default": false
        },
        "allowed_hosts": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Optional allowlist of host patterns for cross-origin downloads when skip_auth=true (e.g., [\"cdn.example.com\", \"*.example.com\"])"
        },
        "allow_private_network": {
          "type": "boolean",
          "description": "SSRF safety switch: when skip_auth=true, controls whether proxy_download may fetch from localhost and private/loopback/link-local IPs (including hostnames that resolve to them) (default: false)",
          "default": false
        }
      },
      "required": [
        "type",
        "metadata_endpoint"
      ],
      "description": "Proxy download operation configuration\n\nWhy: Some APIs return file URLs that require authentication. LLM cannot fetch these directly, so we proxy the download."
    },
    "CompositeStep": {
      "type": "object",
      "properties": {
        "call": {
          "type": "string",
          "description": "OpenAPI operationId to call",
          "examples": [
            "getApiV4ProjectsIdMergeRequestsMergeRequestIid"
          ]
        },
        "store_as": {
          "type": "string",
          "description": "JSON path where to store result (e.g., 'merge_request', 'merge_request.comments')",
          "examples": [
            "merge_request",
            "merge_request.comments",
            "user.profile"
          ]
        },
        "depends_on": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      },
      "required": [
        "call",
        "store_as"
      ]
    },
    "Record<string,ParameterDefinition>": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/definitions/Parameter"
      }
    },
    "Parameter": {
      "type": "object",
      "properties": {
        "type": {
          "anyOf": [
            {
              "$ref": "#/definitions/ParameterType"
            },
            {
              "type": "array",
              "items": {
                "$ref": "#/definitions/ParameterType"
              }
            }
          ],
          "description": "Parameter data type",
          "oneOf": [
            {
              "type": "string",
              "enum": [
                "string",
                "integer",
                "number",
                "boolean",
                "array",
                "object"
              ]
            },
            {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "string",
                  "integer",
                  "number",
                  "boolean",
                  "array",
                  "object"
                ]
              },
              "minItems": 1
            }
          ]
        },
        "description": {
          "type": "string",
          "description": "Clear description of this parameter (shown to LLM)"
        },
        "required": {
          "type": "boolean",
          "description": "Is this parameter always required?",
          "default": false
        },
        "required_for": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "List of actions this parameter is required for",
          "examples": [
            [
              "create",
              "update"
            ]
          ]
        },
        "enum": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "List of allowed values"
        },
        "minLength": {
          "type": "number",
          "description": "Minimum length for string parameters"
        },
        "maxLength": {
          "type": "number",
          "description": "Maximum length for string parameters"
        },
        "pattern": {
          "type": "string",
          "description": "Regex pattern for string parameters"
        },
        "items": {
          "type": "object",
          "properties": {
            "type": {
              "type": "string"
            }
          },
          "required": [
            "type"
          ],
          "description": "Item type for array parameters"
        },
        "properties": {
          "$ref": "#/definitions/Record%3Cstring%2Cunknown%3E",
          "description": "Properties schema for object parameters (empty {} = free-form object)"
        },
        "default": {
          "description": "Default value if not provided"
        },
        "example": {
          "description": "Example value for documentation"
        },
        "object_entries_to_array": {
          "type": "object",
          "properties": {
            "key_field": {
              "type": "string",
              "description": "Field name to store the object key"
            },
            "value_field": {
              "type": "string",
              "description": "Field name to store the object value"
            },
            "wrap_value_field": {
              "type": "string",
              "description": "Optional wrapper field name for non-object values"
            }
          },
          "required": [
            "key_field",
            "value_field"
          ],
          "description": "Convert an object map into an array of objects using key/value fields"
        },
        "array_item_to_object": {
          "type": "object",
          "properties": {
            "key_field": {
              "type": "string",
              "description": "Field name to store the array item value"
            }
          },
          "required": [
            "key_field"
          ],
          "description": "Convert primitive array items into objects using the provided field"
        }
      },
      "required": [
        "type",
        "description"
      ]
    },
    "ParameterType": {
      "type": "string",
      "enum": [
        "string",
        "integer",
        "number",
        "boolean",
        "array",
        "object"
      ]
    },
    "Record<string,unknown>": {
      "type": "object",
      "additionalProperties": {}
    },
    "Record<string,string[]>": {
      "type": "object",
      "additionalProperties": {
        "type": "array",
        "items": {
          "type": "string"
        }
      }
    },
    "PromptDefinition": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "description": {
          "type": "string"
        },
        "arguments": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/PromptArgumentDefinition"
          }
        },
        "messages": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/PromptMessageTemplate"
          }
        }
      },
      "required": [
        "name",
        "messages"
      ]
    },
    "PromptArgumentDefinition": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "description": {
          "type": "string"
        },
        "required": {
          "type": "boolean"
        }
      },
      "required": [
        "name"
      ]
    },
    "PromptMessageTemplate": {
      "type": "object",
      "properties": {
        "role": {
          "$ref": "#/definitions/PromptMessageRole"
        },
        "content": {
          "$ref": "#/definitions/PromptContentTemplate"
        }
      },
      "required": [
        "role",
        "content"
      ]
    },
    "PromptMessageRole": {
      "type": "string",
      "enum": [
        "assistant",
        "user"
      ]
    },
    "PromptContentTemplate": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "const": "text"
        },
        "text": {
          "type": "string"
        }
      },
      "required": [
        "type",
        "text"
      ]
    },
    "Interceptors": {
      "type": "object",
      "properties": {
        "auth": {
          "anyOf": [
            {
              "$ref": "#/definitions/Auth"
            },
            {
              "type": "array",
              "items": {
                "$ref": "#/definitions/Auth"
              }
            }
          ],
          "oneOf": [
            {
              "$ref": "#/definitions/Auth"
            },
            {
              "type": "array",
              "items": {
                "$ref": "#/definitions/Auth"
              },
              "minItems": 1,
              "description": "Multiple authentication methods (tried in order of priority)"
            }
          ]
        },
        "base_url": {
          "$ref": "#/definitions/BaseUrl"
        },
        "cache": {
          "$ref": "#/definitions/CacheConfig"
        },
        "rate_limit": {
          "$ref": "#/definitions/RateLimit"
        },
        "retry": {
          "$ref": "#/definitions/Retry"
        },
        "array_format": {
          "type": "string",
          "enum": [
            "brackets",
            "indices",
            "repeat",
            "comma"
          ],
          "description": "How to serialize array query parameters",
          "default": "repeat",
          "examples": [
            "brackets"
          ]
        },
        "timeout_ms": {
          "type": "number",
          "description": "Request timeout in milliseconds"
        },
        "redirect_auth_policy": {
          "type": "string",
          "enum": [
            "never",
            "same-origin"
          ],
          "default": "same-origin"
        }
      },
      "description": "HTTP interceptor configuration (auth, rate limiting, retry)"
    },
    "Auth": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "bearer",
            "query",
            "custom-header",
            "oauth"
          ],
          "description": "Authentication type"
        },
        "priority": {
          "type": "number",
          "description": "Priority for multi-auth (lower = higher priority). Default: 0. Used when multiple auth methods are configured.",
          "default": 0,
          "examples": [
            0,
            1,
            2
          ]
        },
        "header_name": {
          "type": "string",
          "description": "Custom header name (required for custom-header type)",
          "examples": [
            "X-API-Key",
            "X-Auth-Token"
          ]
        },
        "query_param": {
          "type": "string",
          "description": "Query parameter name (required for query type)",
          "examples": [
            "api_key",
            "token"
          ]
        },
        "value_from_env": {
          "type": "string",
          "description": "Environment variable name containing the auth token (required for bearer, query, custom-header)",
          "examples": [
            "MCP4_API_TOKEN",
            "GITLAB_TOKEN"
          ]
        },
        "oauth_config": {
          "$ref": "#/definitions/OAuthConfig",
          "description": "OAuth 2.0 configuration\n\nSupports Authorization Code Flow with PKCE (RFC 7636)\nOnly available in HTTP transport mode\n\nClient registration can be:\n- Static: pre-registered client_id and client_secret\n- Dynamic: RFC 7591 dynamic client registration"
        },
        "oauth_rate_limit": {
          "type": "object",
          "properties": {
            "max_requests": {
              "type": "number",
              "description": "Maximum number of OAuth requests allowed per window",
              "examples": [
                10,
                20,
                50
              ]
            },
            "window_ms": {
              "type": "number",
              "description": "Rate limit window in milliseconds",
              "examples": [
                900000,
                1800000,
                3600000
              ]
            }
          },
          "required": [
            "max_requests",
            "window_ms"
          ],
          "description": "OAuth rate limiting configuration. Overrides default OAuth rate limits (10 requests per 15 minutes)."
        },
        "validation_endpoint": {
          "type": "string"
        },
        "validation_method": {
          "type": "string",
          "enum": [
            "GET",
            "HEAD"
          ]
        },
        "validation_timeout_ms": {
          "type": "number"
        },
        "validation_allowed_hosts": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      },
      "required": [
        "type"
      ],
      "description": "Auth interceptor configuration\n\n- bearer: Standard HTTP Bearer token (Authorization: Bearer <token>)\n- query: API key in query string (?api_key=<token>)\n- custom-header: Custom header name (e.g., X-API-Key: <token>)\n- oauth: OAuth 2.0 Authorization Code Flow with PKCE (HTTP transport only)\n\nMulti-auth support:\n- When multiple auth methods are provided as array, they are tried in order\n- priority field determines the order (lower = higher priority)\n- First successful authentication is used\n\nToken validation (optional):\n- validation_endpoint: API endpoint to verify token validity (e.g., \"/api/v4/user\")\n- Validates token during initialization to fail fast with invalid tokens\n- Improves UX by rejecting bad tokens immediately, not after first tool call",
      "allOf": [
        {
          "if": {
            "properties": {
              "type": {
                "enum": [
                  "bearer",
                  "query",
                  "custom-header"
                ]
              }
            }
          },
          "then": {
            "required": [
              "value_from_env"
            ],
            "properties": {
              "value_from_env": {
                "type": "string"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "custom-header"
              }
            }
          },
          "then": {
            "required": [
              "header_name"
            ],
            "properties": {
              "header_name": {
                "type": "string"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "query"
              }
            }
          },
          "then": {
            "required": [
              "query_param"
            ],
            "properties": {
              "query_param": {
                "type": "string"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "oauth"
              }
            }
          },
          "then": {
            "required": [
              "oauth_config"
            ],
            "properties": {
              "oauth_config": {
                "$ref": "#/definitions/OAuthConfig"
              },
              "oauth_rate_limit": {
                "type": "object",
                "description": "OAuth rate limiting configuration. Overrides default OAuth rate limits (10 requests per 15 minutes).",
                "properties": {
                  "max_requests": {
                    "type": "number",
                    "description": "Maximum number of OAuth requests allowed per window",
                    "minimum": 1
                  },
                  "window_ms": {
                    "type": "number",
                    "description": "Rate limit window in milliseconds",
                    "minimum": 1000
                  }
                },
                "required": [
                  "max_requests",
                  "window_ms"
                ]
              }
            }
          }
        }
      ]
    },
    "OAuthConfig": {
      "type": "object",
      "properties": {
        "issuer": {
          "type": "string",
          "description": "OAuth 2.0 issuer URL (RFC 8414). When provided, authorization_endpoint and token_endpoint are auto-derived via /.well-known/oauth-authorization-server or standard paths. Supports ${env:VAR} syntax.",
          "examples": [
            "https://gitlab.example.com",
            "${env:MCP4_OAUTH_ISSUER}"
          ]
        },
        "authorization_endpoint": {
          "type": "string",
          "description": "OAuth 2.0 authorization endpoint. Optional if issuer is provided. Supports ${env:VAR} syntax.",
          "examples": [
            "https://gitlab.example.com/oauth/authorize",
            "${env:OAUTH_AUTHORIZATION_URL}"
          ]
        },
        "token_endpoint": {
          "type": "string",
          "description": "OAuth 2.0 token endpoint. Optional if issuer is provided. Supports ${env:VAR} syntax.",
          "examples": [
            "https://gitlab.example.com/oauth/token",
            "${env:OAUTH_TOKEN_URL}"
          ]
        },
        "client_id": {
          "type": "string",
          "description": "Pre-registered OAuth client ID (supports ${env:VAR} syntax). Optional for dynamic registration.",
          "examples": [
            "${env:MCP4_OAUTH_CLIENT_ID}"
          ]
        },
        "client_secret": {
          "type": "string",
          "description": "Pre-registered OAuth client secret (supports ${env:VAR} syntax). Optional for public clients.",
          "examples": [
            "${env:MCP4_OAUTH_CLIENT_SECRET}"
          ]
        },
        "scopes": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "OAuth 2.0 scopes to request. Optional - if not provided, no scopes will be requested (some APIs don't require scopes)",
          "examples": [
            [
              "api",
              "read_user"
            ],
            [
              "read_repository",
              "write_repository"
            ]
          ]
        },
        "redirect_uri": {
          "type": "string",
          "description": "OAuth callback URI. Defaults to http://{MCP4_HOST}:{MCP4_PORT}/oauth/callback",
          "examples": [
            "https://<your-mcp-server-host>/oauth/callback"
          ]
        },
        "registration_endpoint": {
          "type": "string",
          "description": "Client registration endpoint for dynamic registration (RFC 7591)",
          "examples": [
            "https://gitlab.example.com/oauth/register"
          ]
        },
        "introspection_endpoint": {
          "type": "string",
          "description": "Token introspection endpoint (RFC 7662)",
          "examples": [
            "https://gitlab.example.com/oauth/introspect"
          ]
        },
        "revocation_endpoint": {
          "type": "string",
          "description": "Token revocation endpoint (RFC 7009)",
          "examples": [
            "https://gitlab.example.com/oauth/revoke"
          ]
        },
        "allowed_redirect_hosts": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Optional: Allowed redirect hosts for OAuth callbacks\nUsed to prevent open redirect vulnerabilities\n\nSupports wildcards: \"*.example.com\" matches any subdomain\nDefaults to [\"localhost\", \"127.0.0.1\"] for security\n\nCan reference MCP4_ALLOWED_ORIGINS environment variable"
        }
      },
      "description": "OAuth 2.0 configuration. Must provide EITHER 'issuer' (endpoints auto-derived) OR both 'authorization_endpoint' and 'token_endpoint' (explicit)."
    },
    "BaseUrl": {
      "type": "object",
      "properties": {
        "value_from_env": {
          "type": "string",
          "description": "Environment variable name containing the base URL",
          "examples": [
            "MCP4_API_BASE_URL"
          ]
        },
        "default": {
          "type": "string",
          "description": "Default base URL if environment variable is not set",
          "examples": [
            "https://www.gitlab.com/api/v4"
          ]
        }
      },
      "required": [
        "value_from_env"
      ]
    },
    "CacheConfig": {
      "type": "object",
      "properties": {
        "enabled": {
          "type": "boolean"
        },
        "backend": {
          "type": "string",
          "enum": [
            "memory",
            "redis"
          ]
        },
        "scope": {
          "type": "string",
          "enum": [
            "auto",
            "public",
            "private",
            "session"
          ]
        },
        "ttl_seconds": {
          "type": "number"
        },
        "max_entries": {
          "type": "number"
        },
        "max_memory_bytes": {
          "type": "number"
        },
        "max_memory_bytes_from_env": {
          "type": "string"
        },
        "methods": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "GET",
              "HEAD"
            ]
          }
        },
        "vary_headers": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      }
    },
    "RateLimit": {
      "type": "object",
      "properties": {
        "max_requests_per_minute": {
          "type": "number",
          "description": "Maximum number of requests per minute (token bucket algorithm)",
          "examples": [
            600,
            60,
            30
          ]
        },
        "overrides": {
          "$ref": "#/definitions/Record%3Cstring%2Cstructure-1535101595-12347-12383-1535101595-12332-12384-1535101595-12318-12385-1535101595-12247-12387-1535101595-0-12527%3E"
        }
      },
      "required": [
        "max_requests_per_minute"
      ]
    },
    "Record<string,structure-1535101595-12347-12383-1535101595-12332-12384-1535101595-12318-12385-1535101595-12247-12387-1535101595-0-12527>": {
      "type": "object",
      "additionalProperties": {
        "type": "object",
        "properties": {
          "max_requests_per_minute": {
            "type": "number"
          }
        },
        "required": [
          "max_requests_per_minute"
        ]
      }
    },
    "Retry": {
      "type": "object",
      "properties": {
        "max_attempts": {
          "type": "number",
          "description": "Maximum number of retry attempts",
          "examples": [
            3
          ]
        },
        "backoff_ms": {
          "type": "array",
          "items": {
            "type": "number"
          },
          "description": "Backoff delays in milliseconds (one per attempt)",
          "examples": [
            [
              1000,
              2000,
              4000
            ]
          ]
        },
        "retry_on_status": {
          "type": "array",
          "items": {
            "type": "number"
          },
          "description": "HTTP status codes that trigger retry",
          "examples": [
            [
              429,
              502,
              503,
              504
            ]
          ]
        }
      },
      "required": [
        "max_attempts",
        "backoff_ms",
        "retry_on_status"
      ]
    },
    "Record<string,structure-1535101595-12096-12132-1535101595-12081-12133-1535101595-12067-12134-1535101595-11996-12136-1535101595-0-12276>": {
      "type": "object",
      "additionalProperties": {
        "type": "object",
        "properties": {
          "max_requests_per_minute": {
            "type": "number"
          }
        },
        "required": [
          "max_requests_per_minute"
        ]
      }
    },
    "Record<string,structure-1535101595-11762-11798-1535101595-11747-11799-1535101595-11733-11800-1535101595-11662-11802-1535101595-0-11942>": {
      "type": "object",
      "additionalProperties": {
        "type": "object",
        "properties": {
          "max_requests_per_minute": {
            "type": "number"
          }
        },
        "required": [
          "max_requests_per_minute"
        ]
      }
    },
    "Record<string,{max_requests_per_minute:number;}>": {
      "type": "object"
    }
  },
  "$id": "https://github.com/davidruzicka/mcp4openapi/profile-schema.json",
  "title": "MCP Profile"
}
