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
95 lines
3.3 KiB
Go
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",
|
|
}
|
|
}
|