Files
zzet--gortex/internal/mcp/resources_bootstrap.go
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

95 lines
3.3 KiB
Go

package mcp
import (
"context"
"github.com/mark3labs/mcp-go/mcp"
)
// registerBootstrapResources surfaces the bootstrap-state tools as
// MCP resources. Every session reads these at startup; resources are
// the right shape because they take no arguments, are URI-addressable,
// and can push `notifications/resources/updated` after each graph
// re-warm so agents stop polling.
//
// The corresponding tools (`graph_stats`, `index_health`,
// `workspace_info`, `list_repos`, `get_active_project`) stay
// registered. Client support for resources is patchier than tools —
// keeping the tool form alive avoids regressing those clients.
func (s *Server) registerBootstrapResources() {
s.mcpServer.AddResource(
mcp.NewResource(
"gortex://index-health",
"Index Health",
mcp.WithResourceDescription("Health score, parse failures, stale files, language coverage. Read at session start to confirm the index is current. Same payload as the `index_health` tool."),
mcp.WithMIMEType("application/json"),
),
s.handleResourceIndexHealth,
)
s.mcpServer.AddResource(
mcp.NewResource(
"gortex://workspace",
"Workspace Info",
mcp.WithResourceDescription("Bind mode, root directory, marker contents, the auto-discovered member set, and any unknown marker keys. Same payload as the `workspace_info` tool."),
mcp.WithMIMEType("application/json"),
),
s.handleResourceWorkspace,
)
s.mcpServer.AddResource(
mcp.NewResource(
"gortex://repos",
"Workspace Repos",
mcp.WithResourceDescription("Every project in the active workspace — the legal `repo` values for any scope: repo or scope: fan-out tool call. Same payload as the `list_repos` tool."),
mcp.WithMIMEType("application/json"),
),
s.handleResourceRepos,
)
s.mcpServer.AddResource(
mcp.NewResource(
"gortex://active-project",
"Active Project",
mcp.WithResourceDescription("Current active project name and its repo list. Same payload as the `get_active_project` tool."),
mcp.WithMIMEType("application/json"),
),
s.handleResourceActiveProject,
)
}
func (s *Server) handleResourceIndexHealth(_ context.Context, req mcp.ReadResourceRequest) ([]mcp.ResourceContents, error) {
payload := s.buildIndexHealthPayload()
if payload == nil {
payload = map[string]any{
"error": "no indexer available",
}
}
return jsonResource(req.Params.URI, payload)
}
func (s *Server) handleResourceWorkspace(ctx context.Context, req mcp.ReadResourceRequest) ([]mcp.ResourceContents, error) {
return jsonResource(req.Params.URI, s.buildWorkspaceInfoPayload(ctx))
}
func (s *Server) handleResourceRepos(ctx context.Context, req mcp.ReadResourceRequest) ([]mcp.ResourceContents, error) {
return jsonResource(req.Params.URI, s.buildListReposPayload(ctx))
}
func (s *Server) handleResourceActiveProject(ctx context.Context, req mcp.ReadResourceRequest) ([]mcp.ResourceContents, error) {
return jsonResource(req.Params.URI, s.buildActiveProjectPayload(ctx))
}
// bootstrapResourceURIs lists the resources whose payloads change when
// the graph is re-warmed. The resource broadcaster pushes a
// `notifications/resources/updated` for each on re-warm completion.
func bootstrapResourceURIs() []string {
return []string{
"gortex://stats",
"gortex://index-health",
"gortex://workspace",
"gortex://repos",
"gortex://active-project",
}
}