Documentation
¶
Overview ¶
Porter Stemmer — inlined from github.com/reiver/go-porterstemmer (MIT License). Implements the Porter stemming algorithm for English word normalization. Used by suggestToolsForIntent to match inflected verb forms to keywords.
Original: Martin Porter, 1980. Go implementation: Charles Iliya Krempeaux. Inlined to avoid an external dependency for a single function call.
Package mcp implements the Model Context Protocol server for Synapses. Agents (Claude Code, Cursor, etc.) connect to this server over stdio and call the registered tools to query the code graph.
Index ¶
- Variables
- func ApproveRequest(token string) error
- func EmbedAllMemories(ctx context.Context, embedder embed.Embedder, st *store.Store, ...)
- func FormatWarning(matches []InjectionMatch) string
- func SessionIDFromContext(ctx context.Context) string
- func StripInternalPaths(msg string) string
- func WithSessionID(ctx context.Context, sessionID string) context.Context
- type ChangeSource
- type EffectivenessReport
- type ErrUnknownTool
- type GraphBFSResult
- type GraphTraversalInfo
- type InjectionCategory
- type InjectionMatch
- type InjectionScanner
- type LedgerAlert
- type NodeEmbedderSetter
- type PackageWork
- type PendingApproval
- type ProjectStoreProvider
- type ProposedChange
- type ScanMode
- type Server
- func (s *Server) BackgroundQueueStats() (depth int, drops int64)
- func (s *Server) ClearSessionHashes(sessionID string)
- func (s *Server) ClearSynapseSession(mcpSessionID string)
- func (s *Server) Close()
- func (s *Server) DispatchTool(ctx context.Context, name string, args map[string]interface{}) (*mcp.CallToolResult, error)
- func (s *Server) EmbedToolCatalog(ctx context.Context, embedder embed.Embedder)
- func (s *Server) InvalidatePacketCache()
- func (s *Server) InvalidatePacketCacheForFile(changedFile string)
- func (s *Server) MCPServer() *server.MCPServer
- func (s *Server) ServeStdio() error
- func (s *Server) SetBrainClient(bc *brain.Client)
- func (s *Server) SetChangeSource(cs ChangeSource)
- func (s *Server) SetEmbedClient(ec *embed.Client)
- func (s *Server) SetFederationResolver(fr *federation.Resolver)
- func (s *Server) SetMemoryEmbedder(e embed.Embedder)
- func (s *Server) SetProjectID(id string)
- func (s *Server) SetProjectPath(path string)
- func (s *Server) SetProjectRegistry(pr ProjectStoreProvider)
- func (s *Server) SetPromptTemplates(templates []skills.PromptTemplate)
- func (s *Server) SetPulseClient(pc *pulse.Client)
- func (s *Server) SetTechStack(ts []scout.TechStackEntry)
- func (s *Server) SetUpdateChecker(fn func() string)
- func (s *Server) SetWebCache(wc *webcache.Cache)
- func (s *Server) StartBackground()
- func (s *Server) SuggestToolsForIntent(intent string) []ToolSuggestion
- type ToolSuggestion
- type TraversalPath
- type WatcherHealthChecker
Constants ¶
This section is empty.
Variables ¶
var Version = "dev"
Version is the server version advertised to MCP clients. Set from main.go via ldflags-injected version before creating the server.
Functions ¶
func ApproveRequest ¶
ApproveRequest marks the approval with the given token as approved on disk. The token is read from disk by `synapses approve` — it is never passed through agents.
func EmbedAllMemories ¶
func EmbedAllMemories(ctx context.Context, embedder embed.Embedder, st *store.Store, pc *pulse.Client)
EmbedAllMemories generates embeddings for all un-embedded memories in the background. Rate-limited to ~2 embeddings/second for builtin mode to avoid CPU contention. Called at startup to lazy-migrate legacy memories.
Model-change migration: before scanning for un-embedded memories, all embeddings from a previous model are marked stale. This handles the MiniLM → nomic upgrade path: old embeddings are in a different vector space and must be regenerated. The rate limiter ensures this doesn't saturate CPU (nomic is ~12s/embed on CPU; 1000 memories ≈ 1h8m at pool/3).
pc may be nil (pulse disabled) — fire-and-forget EmbeddingEvent on completion. (P2-6)
func FormatWarning ¶
func FormatWarning(matches []InjectionMatch) string
FormatWarning returns a human-readable warning string for the response.
func SessionIDFromContext ¶
SessionIDFromContext retrieves the session ID injected by WithSessionID. Returns "" when no session ID was injected (stdio path, tests).
func StripInternalPaths ¶
StripInternalPaths removes absolute filesystem paths from error messages to prevent leaking internal server paths to AI agents via MCP tool results. Replaces patterns like "/Users/foo/.synapses/data/graph.db" with "<internal>".
Types ¶
type ChangeSource ¶
type ChangeSource interface {
RecentChanges(windowMinutes int) []watcher.ChangeEvent
}
ChangeSource is implemented by types that maintain a recent file-change log. Typically this is *watcher.Watcher, wired in cmdStart via SetChangeSource.
type EffectivenessReport ¶
type EffectivenessReport struct {
// ContextHitRate is the fraction of context deliveries served from cache.
ContextHitRate float64 `json:"context_hit_rate"`
// TaskCompletionRate is 1 - tool_call_error_rate (proxy: successful calls / total calls).
// Nil when no tool-call data is available for this session (not 0% — unknown).
TaskCompletionRate *float64 `json:"task_completion_rate,omitempty"`
// ToolCalls is the total number of MCP tool calls in this session.
ToolCalls int `json:"tool_calls"`
// TotalDeliveries is the total number of context deliveries in this session.
TotalDeliveries int `json:"total_deliveries"`
// FirstFetchRight is the number of deliveries that required no correction re-fetch.
FirstFetchRight int `json:"first_fetch_right"`
// TokensSaved is the estimated tokens saved vs full-file grep (baseline - response).
// Omitted from JSON when zero so consumers can distinguish "no savings" from "no deliveries".
TokensSaved int `json:"tokens_saved,omitempty"`
// KnowledgeGrowth is the number of memories created or updated during this session.
KnowledgeGrowth int `json:"knowledge_growth"`
// DurationMs is the session wall-clock duration in milliseconds.
DurationMs int64 `json:"duration_ms"`
// Prev7d is the 7-day historical average across all previous sessions (omitted when no history).
Prev7d *prev7dSummary `json:"prev_7d,omitempty"`
// Message is the human-readable effectiveness summary.
Message string `json:"message"`
}
EffectivenessReport summarises session quality and compares to recent history (Sprint 15 #5).
type ErrUnknownTool ¶
type ErrUnknownTool struct {
Name string
}
ErrUnknownTool is returned by DispatchTool when the tool name is not registered.
func (*ErrUnknownTool) Error ¶
func (e *ErrUnknownTool) Error() string
type GraphBFSResult ¶
type GraphBFSResult struct {
// Nodes: reachable node IDs, excluding seeds themselves.
Nodes []string
// ParentMap: maps each discovered node to the edge that found it.
// Used to reconstruct traversal paths (anchor → seed walk).
ParentMap map[string]graphParentEntry
// SeedSet: original seed node IDs (for terminating path reconstruction).
SeedSet map[string]bool
// ActivationMap: spreading activation score for each reachable node (0.0–1.0).
// Seeds are also present with activation 1.0.
// Non-seed nodes receive activation proportional to edge type weight and
// parent fan-out. Nodes reachable via multiple paths hold the maximum score.
// Used to rank memories anchored to high-activation nodes higher in RRF.
ActivationMap map[string]float64
}
GraphBFSResult is the output of a BFS traversal from seed nodes.
type GraphTraversalInfo ¶
type GraphTraversalInfo struct {
Depth int `json:"depth"`
AnchorCount int `json:"anchor_count"` // query-matching seed entities
VisitedNodes int `json:"visited_nodes"` // graph nodes explored by BFS
Paths []TraversalPath `json:"paths,omitempty"`
Note string `json:"note"`
VectorSearchMs float64 `json:"vector_search_ms,omitempty"` // embedding query latency
}
GraphTraversalInfo describes the graph channel's multi-hop traversal for a recall() call. Surfaced in the response when the graph channel was active and found results. VectorSearchMs is always set when the semantic channel ran, regardless of whether the graph channel produced results.
type InjectionCategory ¶
type InjectionCategory string
InjectionCategory classifies detected injection patterns.
const ( CategoryRoleOverride InjectionCategory = "role_override" CategoryDelimiterInjection InjectionCategory = "delimiter_injection" CategoryPromptExtraction InjectionCategory = "prompt_extraction" CategoryExfiltration InjectionCategory = "exfiltration_signal" CategoryInstructionOverride InjectionCategory = "instruction_override" )
Injection detection categories.
type InjectionMatch ¶
type InjectionMatch struct {
Category InjectionCategory `json:"category"`
Pattern string `json:"pattern"` // human-readable pattern name
Matched string `json:"matched"` // the text that matched (truncated to 120 chars)
Severity string `json:"severity"` // "high" or "medium"
}
InjectionMatch describes a single detected injection pattern.
type InjectionScanner ¶
type InjectionScanner struct {
// contains filtered or unexported fields
}
InjectionScanner detects prompt injection patterns in text content. All patterns are pre-compiled at construction time for zero-allocation scanning.
func NewInjectionScanner ¶
func NewInjectionScanner(mode ScanMode) *InjectionScanner
NewInjectionScanner creates a scanner with pre-compiled patterns. mode controls the response behavior (warn/truncate/reject).
func (*InjectionScanner) Mode ¶
func (s *InjectionScanner) Mode() ScanMode
Mode returns the scanner's configured mode.
func (*InjectionScanner) Scan ¶
func (s *InjectionScanner) Scan(text string) []InjectionMatch
Scan checks text for injection patterns and returns all matches. Returns nil if no patterns are detected.
func (*InjectionScanner) StripMatches ¶
func (s *InjectionScanner) StripMatches(text string) string
StripMatches removes all matched regions from text, returning sanitized content. Used when mode is ScanModeTruncate.
type LedgerAlert ¶
type LedgerAlert struct {
SessionID string `json:"session"`
AgentID string `json:"agent_id,omitempty"`
Intent string `json:"intent,omitempty"`
OverlapType string `json:"overlap_type"` // "file", "entity", or "entity_neighbor"
Overlap []string `json:"overlap"`
LastActive string `json:"last_active"`
}
LedgerAlert is a cross-session overlap notification injected into tool responses.
type NodeEmbedderSetter ¶
NodeEmbedderSetter is an optional interface that ChangeSource implementations may satisfy to accept a node embedder for Tier 1 embedding-based entity resolution. Implemented by *watcher.Watcher; checked via type assertion in SetMemoryEmbedder.
type PackageWork ¶
type PackageWork struct {
Package string `json:"package"`
Files []string `json:"files"`
Entities []string `json:"entities,omitempty"`
}
PackageWork is one entry in the per-package work summary produced at end_session. Grouped by package directory so agents can see at a glance which packages were touched and which specific entities were examined there.
type PendingApproval ¶
type PendingApproval struct {
Token string
Operation string
Details string
AgentID string
ExpiresAt time.Time
FilePath string
}
PendingApproval is the public view of a pending approval, surfaced by the CLI.
func ListPendingApprovals ¶
func ListPendingApprovals() ([]PendingApproval, error)
ListPendingApprovals returns all non-expired, unapproved approvals from disk. Used by the `synapses approve` CLI command.
type ProjectStoreProvider ¶
type ProjectStoreProvider interface {
// ListProjects returns human-readable names of all registered projects.
ListProjects() []string
// GetStore returns the store for the named project, or nil if not found.
// The name is the directory basename (e.g. "backend" for /Users/x/code/backend).
GetStore(name string) *store.Store
}
ProjectStoreProvider gives access to a sibling project's store for cross-project queries. Implemented by the daemon's project registry; nil in single-project (stdio) mode.
type ProposedChange ¶
type ProposedChange struct {
File string `json:"file"`
AddsCallTo string `json:"adds_call_to,omitempty"`
RemovesCallTo string `json:"removes_call_to,omitempty"`
}
ProposedChange is a single entry in a validate_plan request.
type ScanMode ¶
type ScanMode string
ScanMode controls the scanner's response when injection patterns are detected.
const ( // ScanModeWarn logs the detection and annotates the response, but allows storage. ScanModeWarn ScanMode = "warn" // ScanModeTruncate strips matched content before storage. ScanModeTruncate ScanMode = "truncate" // ScanModeReject returns an error and refuses to store the content. ScanModeReject ScanMode = "reject" )
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server holds the MCP server and the dependencies that tool handlers need.
func New ¶
New creates a Server wired to the given graph, config, and optional store. The store is required for Agent Task Memory tools (create_plan, get_pending_tasks, etc.). Pass nil for st if running in a context without persistence (e.g. tests). All tools are registered during construction.
func NewKnowledge ¶
NewKnowledge creates a Server in knowledge mode — memory, events, tasks, and messages only, no code graph. Used for non-code domains (marketing, ops, QA).
func (*Server) BackgroundQueueStats ¶
BackgroundQueueStats returns the current queue depth and total drop count for health endpoint reporting (BUG-020).
func (*Server) ClearSessionHashes ¶
ClearSessionHashes removes all cached hashes for a session. Must be called when a session disconnects to prevent unbounded memory growth in long-running daemons with many short-lived connections.
func (*Server) ClearSynapseSession ¶
ClearSynapseSession removes the session mapping for an MCP connection. Should be called when a connection closes (daemon) or end_session fires. Safe to call with an empty or unknown session ID.
func (*Server) Close ¶
func (s *Server) Close()
Close signals all background goroutines to stop and waits up to 5 seconds for graceful completion. Shutdown sequence:
- Reject new work (shutdownMu write lock ensures no concurrent goBackground sends)
- Signal long-running loops via stopCh
- Close bgQueue — workers drain remaining items then exit their range loop
- Wait with timeout for all tracked goroutines
Safe to call multiple times — subsequent calls are no-ops.
func (*Server) DispatchTool ¶
func (s *Server) DispatchTool(ctx context.Context, name string, args map[string]interface{}) (*mcp.CallToolResult, error)
DispatchTool calls a registered tool handler directly by name. Used by the REST API (POST /v1/tools/{name}) to bypass the JSON-RPC layer. Returns (nil, ErrUnknownTool) when name is not registered. The caller is responsible for injecting the session ID into ctx if needed.
func (*Server) EmbedToolCatalog ¶
EmbedToolCatalog pre-computes normalized vector embeddings for all entries in toolCatalog. Each tool is embedded as "Description keywords…" so that cosine similarity captures both the functional description and intent tags.
Called as a background goroutine from SetMemoryEmbedder. Safe to call concurrently — results are committed atomically under toolEmbedsMu. Aborts on any embedding error to avoid a partial index, which would silently degrade ranking (partial embeddings produce misleading similarity scores).
func (*Server) InvalidatePacketCache ¶
func (s *Server) InvalidatePacketCache()
InvalidatePacketCache clears the entire context-packet cache. Satisfies the watcher.PacketCacheInvalidator interface; delegates to InvalidatePacketCacheForFile with an empty path so resource notifications and brain warming are also triggered.
func (*Server) InvalidatePacketCacheForFile ¶
InvalidatePacketCacheForFile clears the in-memory packet cache, sends MCP resource-updated notifications (currently a no-op, see notifyResourceChanged), and proactively warms the brain cache for entities in the changed file.
Call this from the file watcher instead of (or in addition to) the plain InvalidatePacketCache to activate brain pre-warming.
func (*Server) MCPServer ¶
MCPServer returns the underlying mcp-go MCPServer instance. Used by the daemon to serve MCP sessions over Unix socket connections instead of stdio.
func (*Server) ServeStdio ¶
ServeStdio starts the MCP server on stdin/stdout. This call blocks until the client disconnects or the process receives a signal.
func (*Server) SetBrainClient ¶
SetBrainClient wires a *brain.Client into the server so that get_context returns enriched Context Packets and violations include LLM explanations.
func (*Server) SetChangeSource ¶
func (s *Server) SetChangeSource(cs ChangeSource)
SetChangeSource wires a change event source (typically the file watcher) so get_working_state can report recent file activity to agents.
func (*Server) SetEmbedClient ¶
SetEmbedClient wires an embedding client so handleSemanticSearch can perform vector similarity search in addition to FTS5 BM25 ranking. Pass nil to disable vector search (falls back to FTS5-only).
func (*Server) SetFederationResolver ¶
func (s *Server) SetFederationResolver(fr *federation.Resolver)
SetFederationResolver wires a federation.Resolver into the server for cross-project dependency tracking and drift detection. When set, session_init includes federation health and drift alerts, prepare_context enriches responses with cross-project dependency data. Pass nil to disable federation features.
func (*Server) SetMemoryEmbedder ¶
SetMemoryEmbedder wires an embedder for generating memory embeddings on remember() writes and for vector search in recall(). Pass nil to disable memory embeddings (FTS5-only recall). Also wires the embedder into the store's semantic dedup: when Jaccard similarity is inconclusive, the store uses the embedder to compare new content against existing memory embeddings.
func (*Server) SetProjectID ¶
SetProjectID sets the stable project identifier used when building context packets. Also propagates the ID to loop_guard and rate_limiter for guard event attribution.
func (*Server) SetProjectPath ¶
SetProjectPath stores the absolute project root path so that lookup_docs can parse go.mod for version-pinned package documentation.
func (*Server) SetProjectRegistry ¶
func (s *Server) SetProjectRegistry(pr ProjectStoreProvider)
SetProjectRegistry wires a cross-project store provider so that recall, get_events, get_messages, and get_agents can query sibling projects.
func (*Server) SetPromptTemplates ¶
func (s *Server) SetPromptTemplates(templates []skills.PromptTemplate)
SetPromptTemplates wires loaded prompt templates into the server. Must be called before the server starts serving requests. In practice, called from cmdStartDirect and cmdStartDaemon after loading prompts from builtin, user (~/.synapses/prompts/), and project (.synapses/prompts/) directories.
func (*Server) SetPulseClient ¶
SetPulseClient wires a *pulse.Client into the server so that every tool call emits telemetry to the synapses-pulse analytics sidecar. Also propagates the pulse client to loop_guard and rate_limiter so they can emit guard events (P3-2, P3-3).
func (*Server) SetTechStack ¶
func (s *Server) SetTechStack(ts []scout.TechStackEntry)
SetTechStack stores the detected tech stack entries so that get_project_identity can surface them as tech_stack. Called from cmdStart after autosubscribe detection completes.
func (*Server) SetUpdateChecker ¶
SetUpdateChecker sets the function that returns the pending update version.
func (*Server) SetWebCache ¶
SetWebCache wires a *webcache.Cache into the server so that lookup_docs can serve version-pinned package documentation and URL caching.
func (*Server) StartBackground ¶
func (s *Server) StartBackground()
StartBackground launches background maintenance goroutines and the bounded worker pool that processes fire-and-forget handler work. Call Close() to stop them and wait for graceful completion. Idempotent — safe to call multiple times.
IMPORTANT: must be called before any handler executes. All production paths (stdio, daemon full-mode, daemon knowledge-mode) call this immediately after New(). goBackground() enqueues work into the buffered channel even before StartBackground runs, so a brief gap is tolerable — items accumulate in the buffer and are consumed once workers start. However, if StartBackground is never called, queued items are silently lost on Close().
func (*Server) SuggestToolsForIntent ¶
func (s *Server) SuggestToolsForIntent(intent string) []ToolSuggestion
SuggestToolsForIntent returns tool suggestions based on the agent's declared intent. Does not modify server state — pure query.
type ToolSuggestion ¶
type ToolSuggestion struct {
Tool string `json:"tool"`
Reason string `json:"reason"`
Example string `json:"example"`
}
ToolSuggestion is returned in session_init's suggested_tools section. It recommends a tool the agent may want to use based on their declared intent.
type TraversalPath ¶
type TraversalPath struct {
MemoryID string `json:"memory_id"`
// MemorySnippet is the first ~80 runes of memory content, for quick preview.
MemorySnippet string `json:"memory_snippet"`
// Path shows the directed structural path from query-matching entity to memory anchor.
// →[EDGE]→ means the left node calls/imports/implements the right node.
// ←[EDGE]- means the right node calls/imports/implements the left node.
// Example: "AuthService →[CALLS]→ TokenValidator" (AuthService calls TokenValidator)
// Example: "AuthService ←[CALLS]- TokenManager" (TokenManager calls AuthService)
Path string `json:"path"`
Hops int `json:"hops"`
}
TraversalPath describes how a specific memory was reached via graph traversal.
type WatcherHealthChecker ¶
type WatcherHealthChecker interface {
IsAlive() bool
}
WatcherHealthChecker is an optional interface that ChangeSource implementations may satisfy to report whether the file-watching event loop is still alive.
Source Files
¶
- approval.go
- benchmark_tools.go
- brain_tools.go
- context_signals.go
- coord_tools.go
- digest.go
- episode_tools.go
- explain.go
- handlers_context.go
- handlers_graph.go
- handlers_merged.go
- handlers_query_graph.go
- handlers_session.go
- handlers_util.go
- handlers_validation.go
- history_tools.go
- injection_scanner.go
- intents.go
- loop_guard.go
- memory_embed.go
- porterstemmer.go
- prompt_tools.go
- pulse_tools.go
- quality_tools.go
- rate_limiter.go
- recall_engine.go
- repomap.go
- resources.go
- scout_tools.go
- server.go
- session_memory.go
- suggestions.go
- task_tools.go
- weight_refinement.go
- work_ledger.go