source dump of claude code
at main 604 lines 15 kB view raw
1/** 2 * Classify an MCP tool as a search/read operation for UI collapsing. 3 * Returns { isSearch: false, isRead: false } for tools that should not 4 * collapse (e.g., send_message, create_*, update_*). 5 * 6 * Uses explicit per-tool allowlists for the most common MCP servers. 7 * Tool names are stable across installs (even when the server name varies, 8 * e.g., "slack" vs "claude_ai_Slack"), so matching is keyed on the tool 9 * name alone after normalizing camelCase/kebab-case to snake_case. 10 * Unknown tool names don't collapse (conservative). 11 */ 12 13// prettier-ignore 14const SEARCH_TOOLS = new Set([ 15 // Slack (hosted + @modelcontextprotocol/server-slack) 16 'slack_search_public', 17 'slack_search_public_and_private', 18 'slack_search_channels', 19 'slack_search_users', 20 // GitHub (github/github-mcp-server) 21 'search_code', 22 'search_repositories', 23 'search_issues', 24 'search_pull_requests', 25 'search_orgs', 26 'search_users', 27 // Linear (mcp.linear.app) 28 'search_documentation', 29 // Datadog (mcp.datadoghq.com) 30 'search_logs', 31 'search_spans', 32 'search_rum_events', 33 'search_audit_logs', 34 'search_monitors', 35 'search_monitor_groups', 36 'find_slow_spans', 37 'find_monitors_matching_pattern', 38 // Sentry (getsentry/sentry-mcp) 39 'search_docs', 40 'search_events', 41 'search_issue_events', 42 'find_organizations', 43 'find_teams', 44 'find_projects', 45 'find_releases', 46 'find_dsns', 47 // Notion (mcp.notion.com — kebab-case, normalized) 48 'search', 49 // Gmail (claude.ai hosted) 50 'gmail_search_messages', 51 // Google Drive (claude.ai hosted + @modelcontextprotocol/server-gdrive) 52 'google_drive_search', 53 // Google Calendar (claude.ai hosted) 54 'gcal_find_my_free_time', 55 'gcal_find_meeting_times', 56 'gcal_find_user_emails', 57 // Atlassian/Jira (mcp.atlassian.com — camelCase, normalized) 58 'search_jira_issues_using_jql', 59 'search_confluence_using_cql', 60 'lookup_jira_account_id', 61 // Community Atlassian (sooperset/mcp-atlassian) 62 'confluence_search', 63 'jira_search', 64 'jira_search_fields', 65 // Asana (mcp.asana.com) 66 'asana_search_tasks', 67 'asana_typeahead_search', 68 // Filesystem (@modelcontextprotocol/server-filesystem) 69 'search_files', 70 // Memory (@modelcontextprotocol/server-memory) 71 'search_nodes', 72 // Brave Search 73 'brave_web_search', 74 'brave_local_search', 75 // Git (mcp-server-git) 76 // (git has no search verbs) 77 // Grafana (grafana/mcp-grafana) 78 'search_dashboards', 79 'search_folders', 80 // PagerDuty 81 // (pagerduty reads all use get_/list_, no search verbs) 82 // Supabase 83 'search_docs', 84 // Stripe 85 'search_stripe_resources', 86 'search_stripe_documentation', 87 // PubMed (claude.ai hosted + community) 88 'search_articles', 89 'find_related_articles', 90 'lookup_article_by_citation', 91 'search_papers', 92 'search_pubmed', 93 'search_pubmed_key_words', 94 'search_pubmed_advanced', 95 'pubmed_search', 96 'pubmed_mesh_lookup', 97 // Firecrawl 98 'firecrawl_search', 99 // Exa 100 'web_search_exa', 101 'web_search_advanced_exa', 102 'people_search_exa', 103 'linkedin_search_exa', 104 'deep_search_exa', 105 // Perplexity 106 'perplexity_search', 107 'perplexity_search_web', 108 // Tavily 109 'tavily_search', 110 // Obsidian (MarkusPfundstein) 111 'obsidian_simple_search', 112 'obsidian_complex_search', 113 // MongoDB 114 'find', 115 'search_knowledge', 116 // Neo4j 117 'search_memories', 118 'find_memories_by_name', 119 // Airtable 120 'search_records', 121 // Todoist (Doist — kebab-case, normalized) 122 'find_tasks', 123 'find_tasks_by_date', 124 'find_completed_tasks', 125 'find_projects', 126 'find_sections', 127 'find_comments', 128 'find_project_collaborators', 129 'find_activity', 130 'find_labels', 131 'find_filters', 132 // AWS 133 'search_documentation', 134 'search_catalog', 135 // Terraform 136 'search_modules', 137 'search_providers', 138 'search_policies', 139]) 140 141// prettier-ignore 142const READ_TOOLS = new Set([ 143 // Slack (hosted + @modelcontextprotocol/server-slack) 144 'slack_read_channel', 145 'slack_read_thread', 146 'slack_read_canvas', 147 'slack_read_user_profile', 148 'slack_list_channels', 149 'slack_get_channel_history', 150 'slack_get_thread_replies', 151 'slack_get_users', 152 'slack_get_user_profile', 153 // GitHub (github/github-mcp-server) 154 'get_me', 155 'get_team_members', 156 'get_teams', 157 'get_commit', 158 'get_file_contents', 159 'get_repository_tree', 160 'list_branches', 161 'list_commits', 162 'list_releases', 163 'list_tags', 164 'get_latest_release', 165 'get_release_by_tag', 166 'get_tag', 167 'list_issues', 168 'issue_read', 169 'list_issue_types', 170 'get_label', 171 'list_label', 172 'pull_request_read', 173 'get_gist', 174 'list_gists', 175 'list_notifications', 176 'get_notification_details', 177 'projects_list', 178 'projects_get', 179 'actions_get', 180 'actions_list', 181 'get_job_logs', 182 'get_code_scanning_alert', 183 'list_code_scanning_alerts', 184 'get_dependabot_alert', 185 'list_dependabot_alerts', 186 'get_secret_scanning_alert', 187 'list_secret_scanning_alerts', 188 'get_global_security_advisory', 189 'list_global_security_advisories', 190 'list_org_repository_security_advisories', 191 'list_repository_security_advisories', 192 'get_discussion', 193 'get_discussion_comments', 194 'list_discussion_categories', 195 'list_discussions', 196 'list_starred_repositories', 197 'get_issue', 198 'get_pull_request', 199 'list_pull_requests', 200 'get_pull_request_files', 201 'get_pull_request_status', 202 'get_pull_request_comments', 203 'get_pull_request_reviews', 204 // Linear (mcp.linear.app) 205 'list_comments', 206 'list_cycles', 207 'get_document', 208 'list_documents', 209 'list_issue_statuses', 210 'get_issue_status', 211 'list_my_issues', 212 'list_issue_labels', 213 'list_projects', 214 'get_project', 215 'list_project_labels', 216 'list_teams', 217 'get_team', 218 'list_users', 219 'get_user', 220 // Datadog (mcp.datadoghq.com) 221 'aggregate_logs', 222 'list_spans', 223 'aggregate_spans', 224 'analyze_trace', 225 'trace_critical_path', 226 'query_metrics', 227 'aggregate_rum_events', 228 'list_rum_metrics', 229 'get_rum_metric', 230 'list_monitors', 231 'get_monitor', 232 'check_can_delete_monitor', 233 'validate_monitor', 234 'validate_existing_monitor', 235 'list_dashboards', 236 'get_dashboard', 237 'query_dashboard_widget', 238 'list_notebooks', 239 'get_notebook', 240 'query_notebook_cell', 241 'get_profiling_metrics', 242 'compare_profiling_metrics', 243 // Sentry (getsentry/sentry-mcp) 244 'whoami', 245 'get_issue_details', 246 'get_issue_tag_values', 247 'get_trace_details', 248 'get_event_attachment', 249 'get_doc', 250 'get_sentry_resource', 251 'list_events', 252 'list_issue_events', 253 'get_sentry_issue', 254 // Notion (mcp.notion.com — kebab-case, normalized) 255 'fetch', 256 'get_comments', 257 'get_users', 258 'get_self', 259 // Gmail (claude.ai hosted) 260 'gmail_get_profile', 261 'gmail_read_message', 262 'gmail_read_thread', 263 'gmail_list_drafts', 264 'gmail_list_labels', 265 // Google Drive (claude.ai hosted + @modelcontextprotocol/server-gdrive) 266 'google_drive_fetch', 267 'google_drive_export', 268 // Google Calendar (claude.ai hosted) 269 'gcal_list_calendars', 270 'gcal_list_events', 271 'gcal_get_event', 272 // Atlassian/Jira (mcp.atlassian.com — camelCase, normalized) 273 'atlassian_user_info', 274 'get_accessible_atlassian_resources', 275 'get_visible_jira_projects', 276 'get_jira_project_issue_types_metadata', 277 'get_jira_issue', 278 'get_transitions_for_jira_issue', 279 'get_jira_issue_remote_issue_links', 280 'get_confluence_spaces', 281 'get_confluence_page', 282 'get_pages_in_confluence_space', 283 'get_confluence_page_ancestors', 284 'get_confluence_page_descendants', 285 'get_confluence_page_footer_comments', 286 'get_confluence_page_inline_comments', 287 // Community Atlassian (sooperset/mcp-atlassian) 288 'confluence_get_page', 289 'confluence_get_page_children', 290 'confluence_get_comments', 291 'confluence_get_labels', 292 'jira_get_issue', 293 'jira_get_transitions', 294 'jira_get_worklog', 295 'jira_get_agile_boards', 296 'jira_get_board_issues', 297 'jira_get_sprints_from_board', 298 'jira_get_sprint_issues', 299 'jira_get_link_types', 300 'jira_download_attachments', 301 'jira_batch_get_changelogs', 302 'jira_get_user_profile', 303 'jira_get_project_issues', 304 'jira_get_project_versions', 305 // Asana (mcp.asana.com) 306 'asana_get_attachment', 307 'asana_get_attachments_for_object', 308 'asana_get_goal', 309 'asana_get_goals', 310 'asana_get_parent_goals_for_goal', 311 'asana_get_portfolio', 312 'asana_get_portfolios', 313 'asana_get_items_for_portfolio', 314 'asana_get_project', 315 'asana_get_projects', 316 'asana_get_project_sections', 317 'asana_get_project_status', 318 'asana_get_project_statuses', 319 'asana_get_project_task_counts', 320 'asana_get_projects_for_team', 321 'asana_get_projects_for_workspace', 322 'asana_get_task', 323 'asana_get_tasks', 324 'asana_get_stories_for_task', 325 'asana_get_teams_for_workspace', 326 'asana_get_teams_for_user', 327 'asana_get_team_users', 328 'asana_get_time_period', 329 'asana_get_time_periods', 330 'asana_get_user', 331 'asana_get_workspace_users', 332 'asana_list_workspaces', 333 // Filesystem (@modelcontextprotocol/server-filesystem) 334 'read_file', 335 'read_text_file', 336 'read_media_file', 337 'read_multiple_files', 338 'list_directory', 339 'list_directory_with_sizes', 340 'directory_tree', 341 'get_file_info', 342 'list_allowed_directories', 343 // Memory (@modelcontextprotocol/server-memory) 344 'read_graph', 345 'open_nodes', 346 // Postgres (@modelcontextprotocol/server-postgres) 347 'query', 348 // SQLite (@modelcontextprotocol/server-sqlite) 349 'read_query', 350 'list_tables', 351 'describe_table', 352 // Git (mcp-server-git) 353 'git_status', 354 'git_diff', 355 'git_diff_unstaged', 356 'git_diff_staged', 357 'git_log', 358 'git_show', 359 'git_branch', 360 // Grafana (grafana/mcp-grafana) 361 'list_teams', 362 'list_users_by_org', 363 'get_dashboard_by_uid', 364 'get_dashboard_summary', 365 'get_dashboard_property', 366 'get_dashboard_panel_queries', 367 'run_panel_query', 368 'list_datasources', 369 'get_datasource', 370 'get_query_examples', 371 'query_prometheus', 372 'query_prometheus_histogram', 373 'list_prometheus_metric_metadata', 374 'list_prometheus_metric_names', 375 'list_prometheus_label_names', 376 'list_prometheus_label_values', 377 'query_loki_logs', 378 'query_loki_stats', 379 'query_loki_patterns', 380 'list_loki_label_names', 381 'list_loki_label_values', 382 'list_incidents', 383 'get_incident', 384 'list_sift_investigations', 385 'get_sift_investigation', 386 'get_sift_analysis', 387 'list_oncall_schedules', 388 'get_oncall_shift', 389 'get_current_oncall_users', 390 'list_oncall_teams', 391 'list_oncall_users', 392 'list_alert_groups', 393 'get_alert_group', 394 'get_annotations', 395 'get_annotation_tags', 396 'get_panel_image', 397 // PagerDuty (PagerDuty/pagerduty-mcp-server) 398 'list_incidents', 399 'get_incident', 400 'get_outlier_incident', 401 'get_past_incidents', 402 'get_related_incidents', 403 'list_incident_notes', 404 'list_incident_workflows', 405 'get_incident_workflow', 406 'list_services', 407 'get_service', 408 'list_team_members', 409 'get_user_data', 410 'list_schedules', 411 'get_schedule', 412 'list_schedule_users', 413 'list_oncalls', 414 'list_log_entries', 415 'get_log_entry', 416 'list_escalation_policies', 417 'get_escalation_policy', 418 'list_event_orchestrations', 419 'get_event_orchestration', 420 'list_status_pages', 421 'get_status_page_post', 422 'list_alerts_from_incident', 423 'get_alert_from_incident', 424 'list_change_events', 425 'get_change_event', 426 // Supabase (supabase-community/supabase-mcp) 427 'list_organizations', 428 'get_organization', 429 'get_cost', 430 'list_extensions', 431 'list_migrations', 432 'get_logs', 433 'get_advisors', 434 'get_project_url', 435 'get_publishable_keys', 436 'generate_typescript_types', 437 'list_edge_functions', 438 'get_edge_function', 439 'list_storage_buckets', 440 'get_storage_config', 441 // Stripe (stripe/agent-toolkit) 442 'get_stripe_account_info', 443 'retrieve_balance', 444 'list_customers', 445 'list_products', 446 'list_prices', 447 'list_invoices', 448 'list_payment_intents', 449 'list_subscriptions', 450 'list_coupons', 451 'list_disputes', 452 'fetch_stripe_resources', 453 // PubMed (claude.ai hosted + community) 454 'get_article_metadata', 455 'get_full_text_article', 456 'convert_article_ids', 457 'get_copyright_status', 458 'download_paper', 459 'list_papers', 460 'read_paper', 461 'get_paper_fulltext', 462 'get_pubmed_article_metadata', 463 'download_pubmed_pdf', 464 'pubmed_fetch', 465 'pubmed_pmc_fetch', 466 'pubmed_spell', 467 'pubmed_cite', 468 'pubmed_related', 469 // BigQuery (claude.ai hosted + community) 470 'bigquery_query', 471 'bigquery_schema', 472 'list_dataset_ids', 473 'list_table_ids', 474 'get_dataset_info', 475 'get_table_info', 476 // Firecrawl 477 'firecrawl_scrape', 478 'firecrawl_map', 479 'firecrawl_crawl', 480 'firecrawl_check_crawl_status', 481 'firecrawl_extract', 482 // Exa 483 'get_code_context_exa', 484 'company_research_exa', 485 'crawling_exa', 486 'deep_researcher_check', 487 // Perplexity 488 'perplexity_ask', 489 'perplexity_research', 490 'perplexity_reason', 491 // Tavily 492 'tavily_extract', 493 'tavily_crawl', 494 'tavily_map', 495 'tavily_research', 496 // Obsidian (MarkusPfundstein) 497 'obsidian_list_files_in_vault', 498 'obsidian_list_files_in_dir', 499 'obsidian_get_file_contents', 500 'obsidian_batch_get_file_contents', 501 'obsidian_get_periodic_note', 502 'obsidian_get_recent_periodic_notes', 503 'obsidian_get_recent_changes', 504 // Figma (GLips/Figma-Context-MCP) 505 'get_figma_data', 506 'download_figma_images', 507 // Playwright (microsoft/playwright-mcp) 508 'browser_console_messages', 509 'browser_network_requests', 510 'browser_take_screenshot', 511 'browser_snapshot', 512 'browser_get_config', 513 'browser_route_list', 514 'browser_cookie_list', 515 'browser_cookie_get', 516 'browser_localstorage_list', 517 'browser_localstorage_get', 518 'browser_sessionstorage_list', 519 'browser_sessionstorage_get', 520 'browser_storage_state', 521 // Puppeteer (@modelcontextprotocol/server-puppeteer) 522 'puppeteer_screenshot', 523 // MongoDB 524 'list_databases', 525 'list_collections', 526 'collection_indexes', 527 'collection_schema', 528 'collection_storage_size', 529 'db_stats', 530 'explain', 531 'mongodb_logs', 532 'aggregate', 533 'count', 534 'export', 535 // Neo4j 536 'get_neo4j_schema', 537 'read_neo4j_cypher', 538 'list_instances', 539 'get_instance_details', 540 'get_instance_by_name', 541 // Elasticsearch (elastic) 542 'list_indices', 543 'get_mappings', 544 'esql', 545 'get_shards', 546 // Airtable 547 'list_records', 548 'list_bases', 549 'get_record', 550 // Todoist (Doist — kebab-case, normalized) 551 'get_productivity_stats', 552 'get_overview', 553 'fetch_object', 554 'user_info', 555 'list_workspaces', 556 'view_attachment', 557 // AWS (awslabs/mcp) 558 'get_available_services', 559 'read_documentation', 560 'read_sections', 561 'recommend', 562 'analyze_log_group', 563 'analyze_metric', 564 'describe_log_groups', 565 'get_active_alarms', 566 'get_alarm_history', 567 'get_metric_data', 568 'get_metric_metadata', 569 // Kubernetes 570 'kubectl_get', 571 'kubectl_describe', 572 'kubectl_logs', 573 'kubectl_context', 574 'explain_resource', 575 'list_api_resources', 576 'namespaces_list', 577 'nodes_log', 578 'nodes_top', 579 'pods_get', 580 'pods_list', 581 'pods_list_in_namespace', 582 'pods_log', 583 'pods_top', 584 'resources_get', 585 'resources_list', 586]) 587 588function normalize(name: string): string { 589 return name 590 .replace(/([a-z])([A-Z])/g, '$1_$2') 591 .replace(/-/g, '_') 592 .toLowerCase() 593} 594 595export function classifyMcpToolForCollapse( 596 _serverName: string, 597 toolName: string, 598): { isSearch: boolean; isRead: boolean } { 599 const normalized = normalize(toolName) 600 return { 601 isSearch: SEARCH_TOOLS.has(normalized), 602 isRead: READ_TOOLS.has(normalized), 603 } 604}