Files
wehub-resource-sync a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:42 +08:00

193 lines
7.4 KiB
Go

package mcp
// defaultToolScopes is the canonical scope for every Gortex MCP tool
//
// The wire-format slice carries this same map onto the schema (`scope`
// field on each tool definition); this server-side copy lets the
// dispatcher validate `repo` per-call without re-deriving it. Both
// must agree — feature-owner's reconcile step at merge time confirms
// the schema and this map have the same entry for every tool.
//
// Classification rules:
//
// - scope: repo — tools that operate against ONE project's index.
// Most per-symbol / per-file query and edit tools fall here.
// - scope: workspace — tools with no per-repo target; report on or
// mutate the workspace as a unit. Examples: list_repos,
// workspace_info, get_active_project, set_active_project.
// - scope: fan-out — tools that legitimately span several indexes
// in one call. The current surface has only one such tool today —
// `audit_agent_config` walks every repo's CLAUDE.md / AGENTS.md /
// editor configs and reports cross-repo. Cross-cutting analysis
// tools that produce a workspace-level summary (`analyze`,
// `contracts`) may ALSO be classified fan-out in a future ADR
// follow-up; iteration 1 keeps them at scope: repo because their
// existing per-call `repo` parameter already produces a single
// focused result and migration to fan-out is a UX change worth a
// separate review.
//
// Note: `analyze` now accepts the uniform repo / project / workspace /
// scope overrides (resolved via resolveScope, applied as a RepoAllow in
// the scoped-node accessors and the analyzeNodeVisible Tier-2 filter),
// clamped to the session workspace. The narrowing reaches its
// graph-node kinds (dead_code, hotspots, cycles, health_score, todos,
// ownership, impact, …); edge-walk / file-scan / git-mining kinds stay
// workspace-bound but are not repo-narrowed in v1. The ScopeRepo wire-
// schema classification below is orthogonal to that narrowing and is
// unchanged.
var defaultToolScopes = map[string]ToolScope{
// --- Workspace-shaped tools ----------------------------------
// "What can I ask about?" — bootstrap surface so an agent can
// discover member repos before issuing any scope: repo call.
"list_repos": ScopeWorkspace,
"workspace_info": ScopeWorkspace,
"get_active_project": ScopeWorkspace,
"set_active_project": ScopeWorkspace,
"track_repository": ScopeWorkspace,
"untrack_repository": ScopeWorkspace,
// --- Fan-out tools -------------------------------------------
// audit_agent_config inherently scans every repo's agent config
// files; explicit `["*"]` makes that breadth visible in logs.
"audit_agent_config": ScopeFanOut,
// --- Per-repo tools ------------------------------------------
// Index management against one repo.
"index_repository": ScopeRepo,
"reindex_repository": ScopeRepo,
// Symbol-level query surface.
"get_symbol": ScopeRepo,
"get_symbol_source": ScopeRepo,
"get_symbol_history": ScopeRepo,
"search_symbols": ScopeRepo,
"winnow_symbols": ScopeRepo,
"batch_symbols": ScopeRepo,
"find_usages": ScopeRepo,
"find_implementations": ScopeRepo,
"find_overrides": ScopeRepo,
"get_class_hierarchy": ScopeRepo,
"get_diagnostics": ScopeRepo,
"get_code_actions": ScopeRepo,
"apply_code_action": ScopeRepo,
"fix_all_in_file": ScopeRepo,
"find_import_path": ScopeRepo,
"get_call_chain": ScopeRepo,
"get_callers": ScopeRepo,
"get_dependencies": ScopeRepo,
"get_dependents": ScopeRepo,
"get_cluster": ScopeRepo,
"get_communities": ScopeRepo,
"get_processes": ScopeRepo,
"get_recent_changes": ScopeRepo,
"get_untested_symbols": ScopeRepo,
"suggest_queries": ScopeRepo,
"search_text": ScopeRepo,
"find_files": ScopeRepo,
// File / repo-level summaries.
"get_file_summary": ScopeRepo,
"get_editing_context": ScopeRepo,
"get_repo_outline": ScopeRepo,
"graph_stats": ScopeRepo,
"index_health": ScopeRepo,
// Editing / code generation.
"edit_symbol": ScopeRepo,
"edit_file": ScopeRepo,
"write_file": ScopeRepo,
"rename_symbol": ScopeRepo,
"scaffold": ScopeRepo,
"suggest_pattern": ScopeRepo,
"batch_edit": ScopeRepo,
"move_symbol": ScopeRepo,
"inline_symbol": ScopeRepo,
// Planning / impact / change support.
"smart_context": ScopeRepo,
"prefetch_context": ScopeRepo,
"export_context": ScopeRepo,
"plan_turn": ScopeRepo,
"explain_change_impact": ScopeRepo,
"verify_change": ScopeRepo,
"detect_changes": ScopeRepo,
"diff_context": ScopeRepo,
"sibling_diff_context": ScopeRepo,
"get_edit_plan": ScopeRepo,
"get_test_targets": ScopeRepo,
"check_guards": ScopeRepo,
"feedback": ScopeRepo,
// Analysis. Historically takes an optional `repo`; classified
// scope: repo to keep behavior unchanged. A follow-up may upgrade
// to fan-out once the UX is reviewed.
"analyze": ScopeRepo,
"contracts": ScopeRepo,
// CPG-lite dataflow primitives. Both walk the active graph by
// node ID / name pattern; like analyze + contracts, they take
// per-call scope hints today and can upgrade to fan-out once
// cross-repo dataflow joins land.
"flow_between": ScopeRepo,
"taint_paths": ScopeRepo,
"trace_path": ScopeRepo,
// Per-function control-flow graphs: built from one symbol's
// source in the active repo.
"get_cfg": ScopeRepo,
}
var toolIntent = map[string]ToolIntent{
// Locate: find definitions/files/text near the session's home repo by default.
"search_symbols": IntentLocate,
"search_text": IntentLocate,
"find_files": IntentLocate,
// Reach: traversal/call-graph tools need the workspace to answer cross-repo use.
"find_usages": IntentReach,
"get_callers": IntentReach,
"get_call_chain": IntentReach,
"get_dependencies": IntentReach,
"get_dependents": IntentReach,
"find_implementations": IntentReach,
"find_overrides": IntentReach,
"get_class_hierarchy": IntentReach,
"get_cluster": IntentReach,
"walk_graph": IntentReach,
"context_closure": IntentReach,
"contracts": IntentReach,
// Analyze: rollups stay at workspace breadth unless explicitly narrowed.
"analyze": IntentAnalyze,
"review": IntentAnalyze,
"sast": IntentAnalyze,
"hotspots": IntentAnalyze,
"dead_code": IntentAnalyze,
"cycles": IntentAnalyze,
"health_score": IntentAnalyze,
"impact": IntentAnalyze,
"connectivity_health": IntentAnalyze,
}
func toolIntentForName(name string) ToolIntent {
if intent, ok := toolIntent[name]; ok {
return intent
}
return IntentAnalyze
}
// applyDefaultToolScopes registers the canonical scope for every
// known tool on this Server. Called once during NewServer after the
// register*Tools sweep so the registry mirrors the registered MCP
// tool surface.
//
// Tools that aren't in the map are simply not registered — the
// dispatcher treats them as unscoped (legacy single-repo behavior),
// which preserves byte-for-byte backwards compatibility for any
// future tool added before its scope is decided.
func (s *Server) applyDefaultToolScopes() {
for name, scope := range defaultToolScopes {
s.RegisterToolScope(name, scope)
}
}