Spaces:
Runtime error
Runtime error
File size: 4,615 Bytes
cd8bd0a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | /**
* MCP Authorization Scopes — Defines permission scopes for each MCP tool.
*
* Each tool requires specific scopes to execute. API keys can be configured
* with a subset of scopes to limit tool access (least-privilege).
*/
// ============ Scope Definitions ============
/** All available MCP scopes */
export const MCP_SCOPE_LIST = [
"read:health",
"read:combos",
"write:combos",
"read:quota",
"read:usage",
"read:models",
"execute:completions",
"execute:search",
"write:budget",
"write:resilience",
"pricing:write",
"read:cache",
"write:cache",
"read:compression",
"write:compression",
"read:proxies",
] as const;
export type McpScope = (typeof MCP_SCOPE_LIST)[number];
// ============ Tool → Scope Mapping ============
/** Maps each MCP tool to its required scopes */
export const MCP_TOOL_SCOPES: Record<string, readonly McpScope[]> = {
// Phase 1: Essential Tools
omniroute_get_health: ["read:health"],
omniroute_list_combos: ["read:combos"],
omniroute_get_combo_metrics: ["read:combos"],
omniroute_switch_combo: ["write:combos"],
omniroute_check_quota: ["read:quota"],
omniroute_route_request: ["execute:completions"],
omniroute_web_search: ["execute:search"],
omniroute_web_fetch: ["execute:search"],
omniroute_cost_report: ["read:usage"],
omniroute_list_models_catalog: ["read:models"],
// Phase 2: Advanced Tools
omniroute_simulate_route: ["read:health", "read:combos"],
omniroute_set_budget_guard: ["write:budget"],
omniroute_set_resilience_profile: ["write:resilience"],
omniroute_test_combo: ["execute:completions", "read:combos"],
omniroute_get_provider_metrics: ["read:health"],
omniroute_best_combo_for_task: ["read:combos", "read:health"],
omniroute_explain_route: ["read:health", "read:usage"],
omniroute_get_session_snapshot: ["read:usage"],
omniroute_db_health_check: ["read:health", "write:resilience"],
omniroute_sync_pricing: ["pricing:write"],
omniroute_cache_stats: ["read:cache"],
omniroute_cache_flush: ["write:cache"],
omniroute_compression_status: ["read:compression"],
omniroute_compression_configure: ["write:compression"],
omniroute_set_compression_engine: ["write:compression"],
omniroute_list_compression_combos: ["read:compression"],
omniroute_compression_combo_stats: ["read:compression"],
omniroute_oneproxy_fetch: ["read:proxies"],
omniroute_oneproxy_rotate: ["read:proxies"],
omniroute_oneproxy_stats: ["read:proxies"],
// Web-session pool observability (read) + lifecycle (write)
omniroute_pool_status: ["read:health"],
omniroute_pool_sessions: ["read:health"],
omniroute_pool_health: ["read:health"],
omniroute_pool_reset: ["write:resilience"],
omniroute_pool_warm: ["write:resilience"],
// Stealth browser pool observability (#3368 PR7)
omniroute_browser_pool_status: ["read:health"],
} as const;
// ============ Scope Groups ============
/** Preset scope bundles for common use cases */
export const MCP_SCOPE_PRESETS = {
/** Read-only access to all health, combo, quota, and usage data */
readonly: [
"read:health",
"read:combos",
"read:quota",
"read:usage",
"read:models",
"read:cache",
"read:compression",
] as const satisfies readonly McpScope[],
/** Full access including writes and execution */
full: [...MCP_SCOPE_LIST] as McpScope[],
/** Monitoring only — health and metrics */
monitor: [
"read:health",
"read:quota",
"read:usage",
"read:cache",
"read:compression",
] as const satisfies readonly McpScope[],
/** Agent — can execute completions and read state */
agent: [
"read:health",
"read:combos",
"read:quota",
"read:usage",
"read:models",
"read:cache",
"read:compression",
"execute:completions",
"execute:search",
] as const satisfies readonly McpScope[],
} as const;
// ============ Helpers ============
/**
* Check if a set of granted scopes satisfies the required scopes for a tool.
*/
export function hasRequiredScopes(grantedScopes: readonly string[], toolName: string): boolean {
const required = MCP_TOOL_SCOPES[toolName];
if (!required) return false;
const granted = new Set(grantedScopes);
return required.every((scope) => granted.has(scope));
}
/**
* Get the list of missing scopes for a tool given granted scopes.
*/
export function getMissingScopes(grantedScopes: readonly string[], toolName: string): string[] {
const required = MCP_TOOL_SCOPES[toolName];
if (!required) return [];
const granted = new Set(grantedScopes);
return required.filter((scope) => !granted.has(scope));
}
|