/** * Profile configuration types * * Why these types: Profiles define which MCP tools are exposed and how they map * to OpenAPI operations. This enables same server to serve different use cases * (admin vs developer vs readonly) without code changes. */ export interface Profile { profile_name: string; profile_id?: string; profile_aliases?: string[]; openapi_spec_path?: string; description?: string; tools: ToolDefinition[]; prompts?: PromptDefinition[]; interceptors?: InterceptorConfig; parameter_aliases?: Record; resource_name?: string; resource_documentation?: string; } export interface ToolDefinition { name: string; description: string; operations?: Record; composite?: boolean; steps?: CompositeStep[]; partial_results?: boolean; parameters: Record; metadata_params?: string[]; response_fields?: Record; send_response_fields_as_param?: boolean; } export interface PromptDefinition { name: string; description?: string; arguments?: PromptArgumentDefinition[]; messages: PromptMessageTemplate[]; } export interface PromptArgumentDefinition { name: string; description?: string; required?: boolean; } export type PromptMessageRole = 'user' | 'assistant'; export interface PromptMessageTemplate { role: PromptMessageRole; content: PromptContentTemplate; } export interface PromptContentTemplate { type: 'text'; text: string; } export type ParameterType = 'string' | 'integer' | 'number' | 'boolean' | 'array' | 'object'; export interface ParameterDefinition { type: ParameterType | ParameterType[]; description: string; required?: boolean; required_for?: string[]; enum?: string[]; minLength?: number; maxLength?: number; pattern?: string; items?: { type: string; }; properties?: Record; default?: unknown; example?: unknown; object_entries_to_array?: { key_field: string; value_field: string; wrap_value_field?: string; }; array_item_to_object?: { key_field: string; }; } export interface CompositeStep { call: string; store_as: string; depends_on?: string[]; } /** * Proxy download operation configuration * * Why: Some APIs return file URLs that require authentication. * LLM cannot fetch these directly, so we proxy the download. */ export interface ProxyDownloadOperation { /** Must be 'proxy_download' */ type: 'proxy_download'; /** OpenAPI operation ID to fetch metadata (e.g., 'get_/issues/{id}/attachments/{attachmentId}') */ metadata_endpoint: string; /** * Optional OpenAPI operation ID for direct download endpoint. * * Why: Some APIs (e.g., GitLab job artifacts) don't expose pre-signed URLs in metadata. * When provided, the proxy will call this endpoint directly instead of extracting a URL. */ download_endpoint?: string; /** JSON path to URL field in metadata response (default: 'url') */ url_field?: string; /** Maximum file size in bytes (default: 10MB = 10485760) */ max_size_bytes?: number; /** Optional environment variable that overrides max_size_bytes (e.g., 'CUSTOM_PROXY_MAX_BYTES') */ max_size_bytes_from_env?: string; /** Timeout for download in milliseconds (default: 30000) */ timeout_ms?: number; /** Optional MIME type whitelist (e.g., ['image/*', 'application/pdf']) */ allowed_mime_types?: string[]; /** * Skip authentication for download URL (default: false) * * Set to true for pre-signed URLs or public download links that don't need auth. * Metadata endpoint still uses normal authentication, only the file download is unauthenticated. * * Example use cases: * - AWS S3 pre-signed URLs (https://bucket.s3.amazonaws.com/file?X-Amz-Signature=...) * - Azure Blob Storage SAS tokens (https://storage.blob.core.windows.net/container/file?sv=...) * - Temporary download URLs with embedded tokens */ skip_auth?: boolean; /** * Optional allowlist of host patterns for cross-origin downloads when skip_auth=true. * * Why: When metadata contains a pre-signed or unauthenticated download URL, following it without * restrictions can enable SSRF. Use this to restrict which hosts the proxy may contact. * * Supported patterns: * - Exact hostname: "cdn.example.com" * - Wildcard subdomain: "*.example.com" (matches "a.example.com", not "example.com") * - Exact IP literal: "203.0.113.10" or "2001:db8::1" */ allowed_hosts?: string[]; /** * Allow downloads to private/loopback/link-local IP literals and localhost when skip_auth=true. * * Default is false to reduce SSRF risk. Set to true only when you explicitly need internal hosts. */ allow_private_network?: boolean; } /** * Extended operation definition supporting proxy_download */ export type OperationDefinition = string | ProxyDownloadOperation; export interface InterceptorConfig { auth?: AuthInterceptor | AuthInterceptor[]; base_url?: BaseUrlConfig; cache?: CacheConfig; rate_limit?: RateLimitConfig; retry?: RetryConfig; array_format?: 'brackets' | 'indices' | 'repeat' | 'comma'; timeout_ms?: number; redirect_auth_policy?: 'same-origin' | 'never'; } export interface CacheConfig { enabled?: boolean; backend?: 'memory' | 'redis'; scope?: 'auto' | 'public' | 'private' | 'session'; ttl_seconds?: number; max_entries?: number; max_memory_bytes?: number; max_memory_bytes_from_env?: string; methods?: ('GET' | 'HEAD')[]; vary_headers?: string[]; } /** * Auth interceptor configuration * * - bearer: Standard HTTP Bearer token (Authorization: Bearer ) * - query: API key in query string (?api_key=) * - custom-header: Custom header name (e.g., X-API-Key: ) * - oauth: OAuth 2.0 Authorization Code Flow with PKCE (HTTP transport only) * * Multi-auth support: * - When multiple auth methods are provided as array, they are tried in order * - priority field determines the order (lower = higher priority) * - First successful authentication is used * * Token validation (optional): * - validation_endpoint: API endpoint to verify token validity (e.g., "/api/v4/user") * - validation_allowed_hosts: optional host allowlist for absolute validation_endpoint URLs * - Validates token during initialization to fail fast with invalid tokens * - Improves UX by rejecting bad tokens immediately, not after first tool call */ export interface AuthInterceptor { type: 'bearer' | 'query' | 'custom-header' | 'oauth'; priority?: number; header_name?: string; query_param?: string; value_from_env?: string; oauth_config?: OAuthConfig; oauth_rate_limit?: { max_requests: number; window_ms: number; }; validation_endpoint?: string; validation_method?: 'GET' | 'HEAD'; validation_timeout_ms?: number; validation_allowed_hosts?: string[]; } /** * OAuth 2.0 configuration * * Supports Authorization Code Flow with PKCE (RFC 7636) * Only available in HTTP transport mode * * Client registration can be: * - Static: pre-registered client_id and client_secret * - Dynamic: RFC 7591 dynamic client registration */ export interface OAuthConfig { /** * OAuth 2.0 issuer URL (RFC 8414) * e.g., "https://www.gitlab.com" * * When provided, authorization_endpoint and token_endpoint are auto-derived: * - Tries fetching /.well-known/oauth-authorization-server * - Falls back to standard paths: /oauth/authorize and /oauth/token * * Can reference environment variables: "${env:OAUTH_ISSUER}" * * Priority: If both issuer and explicit endpoints are provided, explicit endpoints take precedence. */ issuer?: string; /** * OAuth 2.0 authorization endpoint * e.g., "https://www.gitlab.com/oauth/authorize" * * Optional if issuer is provided. * Can reference environment variables: "${env:OAUTH_AUTHORIZATION_URL}" */ authorization_endpoint?: string; /** * OAuth 2.0 token endpoint * e.g., "https://www.gitlab.com/oauth/token" * * Optional if issuer is provided. * Can reference environment variables: "${env:OAUTH_TOKEN_URL}" */ token_endpoint?: string; /** * Pre-registered OAuth client ID (for static client registration) * Optional - if not provided, uses dynamic client registration (RFC 7591) * * Can reference environment variables: "${env:OAUTH_CLIENT_ID}" */ client_id?: string; /** * Pre-registered OAuth client secret (for static client registration) * Optional - only needed for confidential clients * * Can reference environment variables: "${env:OAUTH_CLIENT_SECRET}" */ client_secret?: string; /** * OAuth 2.0 scopes to request * e.g., ["api", "read_user", "write_repository"] * Optional - if not provided, no scopes will be requested (some APIs don't require scopes) */ scopes?: string[]; /** * Redirect URI for OAuth callback * Defaults to: http://{MCP4_HOST}:{MCP4_PORT}/oauth/callback * * Must match URI registered with OAuth provider */ redirect_uri?: string; /** * Optional: Client registration endpoint for dynamic registration (RFC 7591) * e.g., "https://www.gitlab.com/oauth/register" * * If provided and client_id is not set, will attempt dynamic client registration */ registration_endpoint?: string; /** * Optional: Token introspection endpoint (RFC 7662) * e.g., "https://www.gitlab.com/oauth/introspect" * * Used for token validation */ introspection_endpoint?: string; /** * Optional: Token revocation endpoint (RFC 7009) * e.g., "https://www.gitlab.com/oauth/revoke" */ revocation_endpoint?: string; /** * Optional: Allowed redirect hosts for OAuth callbacks * Used to prevent open redirect vulnerabilities * * Supports wildcards: "*.example.com" matches any subdomain * Defaults to ["localhost", "127.0.0.1"] for security * * Can reference MCP4_ALLOWED_ORIGINS environment variable */ allowed_redirect_hosts?: string[]; } export interface BaseUrlConfig { value_from_env: string; default?: string; } export interface RateLimitConfig { max_requests_per_minute: number; overrides?: Record; } export interface RetryConfig { max_attempts: number; backoff_ms: number[]; retry_on_status: number[]; } //# sourceMappingURL=profile.d.ts.map