Documentation
¶
Overview ¶
Package mcp provides MCP-specific authentication and authorization.
CRITICAL DESIGN CONSTRAINT: This implementation is 100% STATELESS. - JWT tokens only - all auth info comes from the token itself - No sessions - no server-side session storage - No stored API keys - X-API-Key header accepts JWT tokens - No cookies for auth - Bearer header only
Security Model:
- Every MCP request contains a JWT in the Authorization header
- JWT signature is validated using HMAC-SHA256
- Roles and permissions are extracted from JWT claims
- Rate limits are per-request throttling (NOT session state)
- Audit logs are fire-and-forget (NOT session tracking)
Role Hierarchy:
- super_admin: Full access, all tools, user management, audit access
- org_admin: Organization-level admin, most tools, can manage org users
- org_developer: Read/write access, most tools except admin
- org_viewer: Read-only access, recall/discover/tasks only
- llm_agent: Automated access, all graph tools, rate limited
- service_account: System integration, specific tool access
Compliance:
- GDPR Art.32: Security of processing (stateless JWT)
- HIPAA §164.312: Access controls (RBAC from JWT claims)
- SOC 2 CC6.1: Logical access controls (role-based permissions)
- FISMA AC-2: Account management (audit logging)
Package mcp provides a native Go MCP (Model Context Protocol) server for NornicDB.
This package implements an LLM-native MCP tool surface, designed specifically for LLM inference patterns, discovery, and usage. The goal is to provide a dramatically improved tool surface for LLM consumption.
Key Design Principles:
- Verb-Noun Naming: Clear action verbs + specific nouns (store, recall, discover, link)
- Single Responsibility: Each tool does ONE thing well (Unix philosophy)
- Minimal Required Parameters: 1-2 required params, rest are smart defaults
- Composable & Orthogonal: Tools chain naturally, no overlapping concerns
- Rich, Actionable Responses: Return IDs, next-step hints, relationship counts
- Progressive Disclosure: Common case is simple, advanced features available
Tool Surface (6 Tools):
- store: Store knowledge/memory as a node in the graph
- recall: Retrieve knowledge by ID or criteria
- discover: Semantic search by meaning (vector embeddings)
- link: Create relationships between nodes
- task: Create/manage individual tasks
- tasks: Query/list multiple tasks
Note: File indexing (index/unindex) is handled by the application layer. NornicDB is the storage/embedding layer - it receives already-processed content.
Example Usage (standalone, usually MCP is integrated into main server on port 7474):
db, _ := nornicdb.Open("./data", nil)
server := mcp.NewServer(db, nil)
// For integration with main NornicDB server, use RegisterRoutes() instead
// For standalone testing:
if err := server.Start(":7474"); err != nil {
log.Fatal(err)
}
MCP Protocol:
The server implements the MCP JSON-RPC protocol:
- initialize: Initialize connection and exchange capabilities
- tools/list: List available tools
- tools/call: Execute a tool
- notifications: Handle server notifications
Package mcp provides tool definitions for the NornicDB MCP server.
Index ¶
- Constants
- Variables
- func AllTools() []string
- func CanUseTool(role MCPRole, tool string) bool
- func ContextWithDatabase(ctx context.Context, dbName string) context.Context
- func DatabaseFromContext(ctx context.Context) string
- func DefaultFloatIfZero(f, defaultVal float64) float64
- func DefaultIfEmpty(s, defaultVal string) string
- func DefaultIntIfZero(i, defaultVal int) int
- func ExtractResourceType(tool string, args map[string]interface{}) string
- func HasPermission(role MCPRole, perm MCPPermission) bool
- func InferOperation(tool string, args map[string]interface{}) string
- func IsValidNodeType(t string) bool
- func IsValidRelation(r string) bool
- func IsValidTaskPriority(p string) bool
- func IsValidTaskStatus(s string) bool
- func IsValidTool(name string) bool
- type AuditLogger
- type AuditSink
- type AuthConfig
- type AuthContext
- type AuthMiddleware
- func (m *AuthMiddleware) CheckToolAccess(ctx context.Context, tool string) error
- func (m *AuthMiddleware) LogToolCall(ctx context.Context, tool string, operation string, resourceType string, ...)
- func (m *AuthMiddleware) Middleware(next http.Handler) http.Handler
- func (m *AuthMiddleware) SetAuditLogger(logger *AuditLogger)
- type CallToolRequest
- type CallToolResponse
- type ClientInfo
- type ConsoleSink
- type Content
- type Dependency
- type DiscoverParams
- type DiscoverResult
- type Edge
- type Embedder
- type InitRequest
- type InitResponse
- type LinkParams
- type LinkResult
- type ListToolsRequest
- type ListToolsResponse
- type MCPAuditEvent
- type MCPPermission
- type MCPRole
- type Node
- type RateLimit
- type RateLimiter
- type RecallParams
- type RecallResult
- type RelatedNode
- type SearchResult
- type Server
- func (s *Server) CallTool(ctx context.Context, name string, arguments map[string]interface{}) (interface{}, error)
- func (s *Server) DefaultDatabaseName() string
- func (s *Server) RegisterRoutes(mux *http.ServeMux)
- func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (s *Server) SetDatabaseScopedExecutor(fn func(dbName string) (exec *cypher.StorageExecutor, ...))
- func (s *Server) SetDatabaseScopedStorage(fn func(dbName string) (storage.Engine, error))
- func (s *Server) SetEmbedder(e Embedder)
- func (s *Server) Start(addr string) error
- func (s *Server) Stop(ctx context.Context) error
- func (s *Server) ToolDefinitions() []Tool
- type ServerConfig
- type ServerInfo
- type StoreParams
- type StoreResult
- type Suggestion
- type TaskParams
- type TaskResult
- type TaskRow
- type TaskStatRow
- type TaskStats
- type TasksParams
- type TasksResult
- type Tool
- type ToolHandler
Constants ¶
const ( ToolStore = "store" ToolRecall = "recall" ToolDiscover = "discover" ToolLink = "link" ToolTask = "task" ToolTasks = "tasks" )
ToolName constants for type-safe tool references
Variables ¶
var ( // ValidTaskStatuses for task status validation ValidTaskStatuses = []string{ "pending", "active", "completed", "blocked", } // ValidTaskPriorities for task priority validation ValidTaskPriorities = []string{ "low", "medium", "high", "critical", } )
var DefaultRateLimits = map[MCPRole]RateLimit{ RoleSuperAdmin: {RequestsPerMinute: 1000, RequestsPerHour: 50000, BurstSize: 100}, RoleOrgAdmin: {RequestsPerMinute: 500, RequestsPerHour: 25000, BurstSize: 50}, RoleOrgDeveloper: {RequestsPerMinute: 200, RequestsPerHour: 10000, BurstSize: 30}, RoleOrgViewer: {RequestsPerMinute: 100, RequestsPerHour: 5000, BurstSize: 20}, RoleLLMAgent: {RequestsPerMinute: 500, RequestsPerHour: 30000, BurstSize: 50}, RoleServiceAccount: {RequestsPerMinute: 300, RequestsPerHour: 15000, BurstSize: 40}, }
DefaultRateLimits returns default rate limits per role.
var MCPRolePermissions = map[MCPRole][]MCPPermission{ RoleSuperAdmin: { PermissionStore, PermissionRecall, PermissionDiscover, PermissionLink, PermissionTask, PermissionTasks, PermissionAdmin, PermissionAudit, }, RoleOrgAdmin: { PermissionStore, PermissionRecall, PermissionDiscover, PermissionLink, PermissionTask, PermissionTasks, PermissionAdmin, }, RoleOrgDeveloper: { PermissionStore, PermissionRecall, PermissionDiscover, PermissionLink, PermissionTask, PermissionTasks, }, RoleOrgViewer: { PermissionRecall, PermissionDiscover, PermissionTasks, }, RoleLLMAgent: { PermissionStore, PermissionRecall, PermissionDiscover, PermissionLink, PermissionTask, PermissionTasks, }, RoleServiceAccount: { PermissionStore, PermissionRecall, PermissionDiscover, PermissionLink, }, }
MCPRolePermissions maps each MCP role to its allowed permissions. Note: index/unindex permissions removed - file indexing is handled by the application layer.
var ToolPermissions = map[string]MCPPermission{ ToolStore: PermissionStore, ToolRecall: PermissionRecall, ToolDiscover: PermissionDiscover, ToolLink: PermissionLink, ToolTask: PermissionTask, ToolTasks: PermissionTasks, }
ToolPermissions maps each MCP tool to its required permission.
Functions ¶
func CanUseTool ¶
CanUseTool checks if a role can use a specific MCP tool.
func ContextWithDatabase ¶
ContextWithDatabase returns a context that carries the database name for MCP tool execution. When the agentic loop calls MCP tools in process, the handler should set this so store/recall/link run against the request's database (e.g. lifecycle.database.DefaultDatabaseName()).
func DatabaseFromContext ¶
DatabaseFromContext returns the database name from the context, or empty if not set.
func DefaultFloatIfZero ¶
DefaultFloatIfZero returns default value if f is zero
func DefaultIfEmpty ¶
DefaultIfEmpty returns default value if s is empty
func DefaultIntIfZero ¶
DefaultIntIfZero returns default value if i is zero
func ExtractResourceType ¶
ExtractResourceType determines the resource type from arguments
func HasPermission ¶
func HasPermission(role MCPRole, perm MCPPermission) bool
HasPermission checks if a role has a specific permission.
func InferOperation ¶
InferOperation determines the CRUD operation from tool and arguments
func IsValidNodeType ¶
IsValidNodeType checks if node type is a valid identifier (abstract: any Cypher-safe label).
func IsValidRelation ¶
IsValidRelation checks if relation type is a valid identifier (abstract: any Cypher-safe relationship type).
func IsValidTaskPriority ¶
IsValidTaskPriority checks if task priority is valid
func IsValidTaskStatus ¶
IsValidTaskStatus checks if task status is valid
Types ¶
type AuditLogger ¶
type AuditLogger struct {
// contains filtered or unexported fields
}
AuditLogger manages multi-sink audit logging.
func (*AuditLogger) AddSink ¶
func (a *AuditLogger) AddSink(sink AuditSink)
AddSink adds an audit sink.
func (*AuditLogger) Flush ¶ added in v1.1.9
func (a *AuditLogger) Flush()
Flush blocks until every audit event handed to Log so far has been delivered to its sink. Safe to call concurrently with Log; in that case it waits for events submitted strictly before the Flush call.
Intended for graceful shutdown and deterministic test assertions — production hot paths should continue to use Log and let the sinks drain in the background.
func (*AuditLogger) Log ¶
func (a *AuditLogger) Log(event MCPAuditEvent)
Log logs an event to all sinks asynchronously (fire-and-forget).
Each in-flight sink invocation is tracked by an internal WaitGroup so that callers (or tests) can call Flush to deterministically observe the resulting writes. Without Flush, Log retains its original fire-and-forget semantics — callers that did not call Flush before this change still observe identical behavior.
type AuditSink ¶
type AuditSink interface {
Log(event MCPAuditEvent) error
}
AuditSink defines an interface for audit log destinations.
type AuthConfig ¶
type AuthConfig struct {
// RequireAuth enables authentication (default: true)
RequireAuth bool
// AllowAnonymous allows unauthenticated read-only access
AllowAnonymous bool
// SecurityEnabled enables/disables security (false = development mode)
SecurityEnabled bool
// AuditEnabled enables audit logging
AuditEnabled bool
// RateLimitEnabled enables rate limiting
RateLimitEnabled bool
}
AuthConfig holds authentication configuration.
func DefaultAuthConfig ¶
func DefaultAuthConfig() AuthConfig
DefaultAuthConfig returns default auth configuration.
type AuthContext ¶
type AuthContext struct {
UserID string
Username string
Email string
Roles []MCPRole
OrgID string
Workspace string
Claims *auth.JWTClaims // Uses existing auth package claims
Timestamp time.Time
}
AuthContext holds authentication context for a request. This is populated FROM JWT CLAIMS ONLY - nothing is stored server-side.
func GetAuthContext ¶
func GetAuthContext(ctx context.Context) (*AuthContext, bool)
GetAuthContext retrieves the auth context from request context.
type AuthMiddleware ¶
type AuthMiddleware struct {
// contains filtered or unexported fields
}
AuthMiddleware provides MCP authentication and authorization. This is 100% STATELESS - all auth info comes from JWT claims. Uses the existing auth.Authenticator for JWT validation.
func NewAuthMiddleware ¶
func NewAuthMiddleware(authenticator *auth.Authenticator, config AuthConfig) *AuthMiddleware
NewAuthMiddleware creates a new auth middleware using the existing auth.Authenticator. The authenticator handles JWT validation and provides the SecurityEnabled flag.
func (*AuthMiddleware) CheckToolAccess ¶
func (m *AuthMiddleware) CheckToolAccess(ctx context.Context, tool string) error
CheckToolAccess verifies if the current user can use a tool. Uses ONLY data from JWT claims.
func (*AuthMiddleware) LogToolCall ¶
func (m *AuthMiddleware) LogToolCall(ctx context.Context, tool string, operation string, resourceType string, resourceID string, success bool, errMsg string, duration time.Duration, metadata map[string]interface{})
LogToolCall logs a tool call for audit (fire-and-forget).
func (*AuthMiddleware) Middleware ¶
func (m *AuthMiddleware) Middleware(next http.Handler) http.Handler
Middleware returns an HTTP middleware that authenticates requests. This is 100% STATELESS - validates JWT signature, extracts claims.
func (*AuthMiddleware) SetAuditLogger ¶
func (m *AuthMiddleware) SetAuditLogger(logger *AuditLogger)
SetAuditLogger sets the audit logger.
type CallToolRequest ¶
type CallToolRequest struct {
Name string `json:"name"`
Arguments map[string]interface{} `json:"arguments"`
}
CallToolRequest executes a tool
type CallToolResponse ¶
type CallToolResponse struct {
Content []Content `json:"content"`
IsError bool `json:"isError,omitempty"`
}
CallToolResponse returns tool execution result
type ClientInfo ¶
ClientInfo contains client metadata
type ConsoleSink ¶
type ConsoleSink struct{}
ConsoleSink is an audit sink that logs to console.
func (*ConsoleSink) Log ¶
func (c *ConsoleSink) Log(event MCPAuditEvent) error
Log implements AuditSink.
type Content ¶
type Content struct {
Type string `json:"type"` // "text" or "resource"
Text string `json:"text,omitempty"`
}
Content represents tool response content
type Dependency ¶
type Dependency struct {
From string `json:"from"`
To string `json:"to"`
Type string `json:"type"`
}
Dependency represents a task dependency
type DiscoverParams ¶
type DiscoverParams struct {
Query string `json:"query"` // Required
Type []string `json:"type,omitempty"` // Optional, filter by types
Limit int `json:"limit,omitempty"` // Optional, default: 10
MinSimilarity float64 `json:"min_similarity,omitempty"` // Optional, normalized relevance threshold (default: 0)
Depth int `json:"depth,omitempty"` // Optional, default: 1, range: 1-3
Database string `json:"database,omitempty"` // Optional, default: configured default database
}
DiscoverParams - Input for discover tool
type DiscoverResult ¶
type DiscoverResult struct {
Results []SearchResult `json:"results"`
Method string `json:"method"` // "vector" or "keyword"
Total int `json:"total"`
Suggestions []string `json:"suggestions,omitempty"`
}
DiscoverResult - Output from discover tool
type Edge ¶
type Edge struct {
ID string `json:"id"`
From string `json:"from"`
To string `json:"to"`
Type string `json:"type"`
Strength float64 `json:"strength,omitempty"`
Properties map[string]interface{} `json:"properties,omitempty"`
Created time.Time `json:"created,omitempty"`
}
Edge represents a graph edge/relationship
type Embedder ¶
type Embedder interface {
Embed(ctx context.Context, text string) ([]float32, error)
EmbedBatch(ctx context.Context, texts []string) ([][]float32, error)
ChunkText(text string, maxTokens, overlap int) ([]string, error)
Model() string
Dimensions() int
}
Embedder interface for generating embeddings (abstracts Ollama/OpenAI).
type InitRequest ¶
type InitRequest struct {
ProtocolVersion string `json:"protocolVersion"`
Capabilities map[string]interface{} `json:"capabilities"`
ClientInfo ClientInfo `json:"clientInfo"`
}
InitRequest is the MCP initialize request
type InitResponse ¶
type InitResponse struct {
ProtocolVersion string `json:"protocolVersion"`
Capabilities map[string]interface{} `json:"capabilities"`
ServerInfo ServerInfo `json:"serverInfo"`
}
InitResponse is the MCP initialize response
type LinkParams ¶
type LinkParams struct {
From string `json:"from"` // Required
To string `json:"to"` // Required
Relation string `json:"relation"` // Required
Strength float64 `json:"strength,omitempty"` // Optional, default: 1.0
Metadata map[string]interface{} `json:"metadata,omitempty"` // Optional
Database string `json:"database,omitempty"` // Optional, default: configured default database
}
LinkParams - Input for link tool
type LinkResult ¶
type LinkResult struct {
EdgeID string `json:"edge_id"`
From Node `json:"from"`
To Node `json:"to"`
Suggested []Edge `json:"suggested,omitempty"`
Receipt interface{} `json:"receipt,omitempty"`
}
LinkResult - Output from link tool
type ListToolsResponse ¶
type ListToolsResponse struct {
Tools []Tool `json:"tools"`
}
ListToolsResponse returns available tools
type MCPAuditEvent ¶
type MCPAuditEvent struct {
Timestamp time.Time `json:"timestamp"`
RequestID string `json:"request_id"`
UserID string `json:"user_id"`
Username string `json:"username,omitempty"`
Role string `json:"role"`
OrgID string `json:"org_id,omitempty"`
Tool string `json:"tool"`
Operation string `json:"operation"`
ResourceType string `json:"resource_type,omitempty"`
ResourceID string `json:"resource_id,omitempty"`
IPAddress string `json:"ip_address,omitempty"`
UserAgent string `json:"user_agent,omitempty"`
Success bool `json:"success"`
ErrorMessage string `json:"error_message,omitempty"`
Duration time.Duration `json:"duration"`
Metadata map[string]interface{} `json:"metadata,omitempty"`
}
MCPAuditEvent represents an MCP-specific audit event.
type MCPPermission ¶
type MCPPermission string
MCPPermission represents a permission for MCP operations.
const ( // PermissionStore allows storing new memories PermissionStore MCPPermission = "store" // PermissionRecall allows retrieving memories PermissionRecall MCPPermission = "recall" // PermissionDiscover allows semantic search PermissionDiscover MCPPermission = "discover" // PermissionLink allows creating relationships PermissionLink MCPPermission = "link" // PermissionTask allows task management PermissionTask MCPPermission = "task" // PermissionTasks allows listing tasks PermissionTasks MCPPermission = "tasks" // PermissionAdmin allows admin operations PermissionAdmin MCPPermission = "admin" // PermissionAudit allows viewing audit logs PermissionAudit MCPPermission = "audit" )
func AllMCPPermissions ¶
func AllMCPPermissions() []MCPPermission
AllMCPPermissions returns all available MCP permissions.
type MCPRole ¶
type MCPRole string
MCPRole represents an MCP-specific role with tool access permissions.
const ( // RoleSuperAdmin has full system access including user management and audit RoleSuperAdmin MCPRole = "super_admin" // RoleOrgAdmin has organization-level admin access RoleOrgAdmin MCPRole = "org_admin" // RoleOrgDeveloper has read/write access to graph data RoleOrgDeveloper MCPRole = "org_developer" // RoleOrgViewer has read-only access RoleOrgViewer MCPRole = "org_viewer" // RoleLLMAgent is for automated LLM/agent access with higher rate limits RoleLLMAgent MCPRole = "llm_agent" // RoleServiceAccount is for system integrations RoleServiceAccount MCPRole = "service_account" )
func RoleFromString ¶
RoleFromString converts a string to an MCPRole.
type Node ¶
type Node struct {
ID string `json:"id"`
Type string `json:"type"`
Title string `json:"title,omitempty"`
Content string `json:"content,omitempty"`
Tags []string `json:"tags,omitempty"`
Properties map[string]interface{} `json:"properties,omitempty"`
Created time.Time `json:"created,omitempty"`
Updated time.Time `json:"updated,omitempty"`
}
Node represents a graph node
type RateLimiter ¶
type RateLimiter struct {
// contains filtered or unexported fields
}
RateLimiter provides per-user rate limiting using in-memory counters. This is NOT session state - it's per-request throttling to prevent abuse.
func (*RateLimiter) Allow ¶
func (r *RateLimiter) Allow(userID string, role MCPRole) (bool, error)
Allow checks if a request is allowed and increments counters.
func (*RateLimiter) GetStats ¶
func (r *RateLimiter) GetStats(userID string) map[string]interface{}
GetStats returns rate limit statistics for a user.
func (*RateLimiter) SetLimits ¶
func (r *RateLimiter) SetLimits(role MCPRole, limit RateLimit)
SetLimits sets custom rate limits for a role.
type RecallParams ¶
type RecallParams struct {
ID string `json:"id,omitempty"` // Optional, if provided ignores other filters
Type []string `json:"type,omitempty"` // Optional, filter by types
Tags []string `json:"tags,omitempty"` // Optional, filter by tags
Since time.Time `json:"since,omitempty"` // Optional, filter by creation time
Limit int `json:"limit,omitempty"` // Optional, default: 10
Database string `json:"database,omitempty"` // Optional, default: configured default database
}
RecallParams - Input for recall tool
type RecallResult ¶
type RecallResult struct {
Nodes []Node `json:"nodes"`
Count int `json:"count"`
Related []Node `json:"related,omitempty"`
}
RecallResult - Output from recall tool
type RelatedNode ¶
type RelatedNode struct {
ID string `json:"id"`
Type string `json:"type"`
Title string `json:"title,omitempty"`
Distance int `json:"distance"` // Hops from the source node (1 = direct, 2 = two hops, etc.)
Relationship string `json:"relationship"` // Relationship type that connects to this node
Direction string `json:"direction,omitempty"` // "outgoing", "incoming", or "both"
Path []string `json:"path,omitempty"` // Node IDs in the path (for depth > 1)
}
RelatedNode represents a node connected to a search result via relationships. Provides context about how nodes are connected in the knowledge graph.
type SearchResult ¶
type SearchResult struct {
ID string `json:"id"`
Type string `json:"type"`
Title string `json:"title"`
ContentPreview string `json:"content_preview,omitempty"`
Similarity float64 `json:"similarity"`
Properties map[string]interface{} `json:"properties,omitempty"`
// Related nodes discovered via graph traversal (only populated when depth > 1)
Related []RelatedNode `json:"related,omitempty"`
}
SearchResult represents a search result node
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server implements the MCP protocol for NornicDB.
func NewServer ¶
func NewServer(db *nornicdb.DB, config *ServerConfig) *Server
NewServer creates a new MCP server with the given database.
func (*Server) CallTool ¶
func (s *Server) CallTool(ctx context.Context, name string, arguments map[string]interface{}) (interface{}, error)
CallTool runs an MCP tool by name with the given arguments in memory. Use this to execute MCP tools (store, recall, discover, link, task, tasks) without HTTP. If ctx contains a database name (ContextWithDatabase), tools run against that database when DatabaseScopedExecutor is configured.
func (*Server) DefaultDatabaseName ¶
DefaultDatabaseName returns the configured default database name for this server. This is derived from the DB's namespaced storage (which is configured during DB open).
func (*Server) RegisterRoutes ¶
RegisterRoutes registers MCP handlers on an existing http.ServeMux. Use this to integrate MCP tools into an existing server (e.g., port 7474).
Routes registered:
- POST /mcp - Main JSON-RPC endpoint
- POST /mcp/initialize - Initialize MCP connection
- GET/POST /mcp/tools/list - List available tools
- POST /mcp/tools/call - Execute a tool
- GET /mcp/health - MCP health check
func (*Server) ServeHTTP ¶
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP implements http.Handler for routing MCP requests. Use this when integrating with a server that wraps handlers (e.g., for auth middleware).
func (*Server) SetDatabaseScopedExecutor ¶
func (s *Server) SetDatabaseScopedExecutor(fn func(dbName string) (exec *cypher.StorageExecutor, getNode func(context.Context, string) (*nornicdb.Node, error), err error))
SetDatabaseScopedExecutor sets the optional per-database executor and node getter. Call this after the server is created when multi-database support is available (e.g. from the HTTP server).
func (*Server) SetDatabaseScopedStorage ¶
SetDatabaseScopedStorage sets the optional per-database storage resolver. Call this after the server is created when multi-database support is available (e.g. from the HTTP server).
func (*Server) SetEmbedder ¶
SetEmbedder sets the embedding service.
func (*Server) Start ¶
Start begins listening for HTTP connections on a SEPARATE server. For integration with the main NornicDB server on port 7474, use RegisterRoutes() instead.
func (*Server) ToolDefinitions ¶
ToolDefinitions returns the MCP tool definitions for this server instance. The `database` parameter schema will reflect the configured default database name.
type ServerConfig ¶
type ServerConfig struct {
// Address to bind to (default: "localhost")
Address string `yaml:"address"`
// Port to listen on (default: 7474, same as NornicDB HTTP API)
Port int `yaml:"port"`
// ReadTimeout for requests
ReadTimeout time.Duration `yaml:"read_timeout"`
// WriteTimeout for responses
WriteTimeout time.Duration `yaml:"write_timeout"`
// MaxRequestSize in bytes (default: 10MB)
MaxRequestSize int64 `yaml:"max_request_size"`
// EnableCORS for cross-origin requests
EnableCORS bool `yaml:"enable_cors"`
// EmbeddingEnabled controls whether embeddings are generated
EmbeddingEnabled bool `yaml:"embedding_enabled"`
// EmbeddingModel is the model name (for error messages)
EmbeddingModel string `yaml:"embedding_model"`
// EmbeddingDimensions is the expected vector dimensions (for validation)
EmbeddingDimensions int `yaml:"embedding_dimensions"`
// Embedder is the embedding service (set externally if needed)
Embedder Embedder `yaml:"-"`
// DatabaseScopedExecutor returns an executor and node getter for the given database name.
// When set, MCP tool calls that include a database in context (e.g. from the agentic loop)
// use this to run store/recall/link/task against the request's database instead of the default.
// If nil or the context has no database, the server uses its single db.
DatabaseScopedExecutor func(dbName string) (exec *cypher.StorageExecutor, getNode func(context.Context, string) (*nornicdb.Node, error), err error)
// DatabaseScopedStorage returns a storage engine scoped to dbName.
// When set, tools that need direct storage access (e.g. discover/search) can operate
// on the request's database without relying on a single default DB instance.
DatabaseScopedStorage func(dbName string) (storage.Engine, error)
// DefaultNodeLabel is the label used when the store tool is called without
// explicit labels or type. Defaults to "Memory" for backward compatibility.
// Configured via NORNICDB_DEFAULT_NODE_LABEL env var or config.Memory.DefaultNodeLabel.
DefaultNodeLabel string
}
ServerConfig holds MCP server configuration.
func DefaultServerConfig ¶
func DefaultServerConfig() *ServerConfig
DefaultServerConfig returns sensible defaults for the MCP server.
type ServerInfo ¶
ServerInfo contains server metadata
type StoreParams ¶
type StoreParams struct {
Content string `json:"content"` // Required
Type string `json:"type,omitempty"` // Optional, default: "memory"
Title string `json:"title,omitempty"` // Optional, auto-generated if empty
Tags []string `json:"tags,omitempty"` // Optional
Metadata map[string]interface{} `json:"metadata,omitempty"` // Optional, will be flattened
}
StoreParams - Input for store tool
type StoreResult ¶
type StoreResult struct {
ID string `json:"id"`
Title string `json:"title"`
Embedded bool `json:"embedded"`
Suggestions []Suggestion `json:"suggestions,omitempty"`
Receipt interface{} `json:"receipt,omitempty"`
}
StoreResult - Output from store tool
type Suggestion ¶
type Suggestion struct {
ID string `json:"id"`
Title string `json:"title"`
Type string `json:"type"`
Similarity float64 `json:"similarity"`
}
Suggestion represents a suggested related node
type TaskParams ¶
type TaskParams struct {
ID string `json:"id,omitempty"` // Optional, for update/complete
Title string `json:"title,omitempty"` // Required for create
Description string `json:"description,omitempty"` // Optional
Status string `json:"status,omitempty"` // Optional: pending|active|completed|blocked
Priority string `json:"priority,omitempty"` // Optional: low|medium|high|critical
DependsOn []string `json:"depends_on,omitempty"` // Optional, task IDs
Assign string `json:"assign,omitempty"` // Optional, agent/person
Database string `json:"database,omitempty"` // Optional, default: configured default database
}
TaskParams - Input for task tool
type TaskResult ¶
type TaskResult struct {
Task Node `json:"task"`
Blockers []Node `json:"blockers,omitempty"`
Subtasks []Node `json:"subtasks,omitempty"`
NextAction string `json:"next_action,omitempty"`
Receipt interface{} `json:"receipt,omitempty"`
}
TaskResult - Output from task tool
type TaskRow ¶
type TaskRow struct {
ID string `cypher:"id" json:"id"`
Title string `cypher:"title" json:"title"`
Description string `cypher:"description" json:"description"`
Status string `cypher:"status" json:"status"`
Priority string `cypher:"priority" json:"priority"`
AssignedTo string `cypher:"assigned_to" json:"assigned_to"`
}
handleTasks implements the tasks tool - queries multiple tasks. TaskRow is a typed struct for task query results.
type TaskStatRow ¶
type TaskStatRow struct {
Status string `cypher:"status" json:"status"`
Priority string `cypher:"priority" json:"priority"`
Count int64 `cypher:"count" json:"count"`
}
TaskStatRow is a typed struct for task statistics.
type TaskStats ¶
type TaskStats struct {
Total int `json:"total"`
ByStatus map[string]int `json:"by_status"`
ByPriority map[string]int `json:"by_priority"`
}
TaskStats contains task statistics
type TasksParams ¶
type TasksParams struct {
Status []string `json:"status,omitempty"` // Optional, filter by status
Priority []string `json:"priority,omitempty"` // Optional, filter by priority
AssignedTo string `json:"assigned_to,omitempty"` // Optional, filter by assignee
UnblockedOnly bool `json:"unblocked_only,omitempty"` // Optional, default: false
Limit int `json:"limit,omitempty"` // Optional, default: 20
Database string `json:"database,omitempty"` // Optional, default: configured default database
}
TasksParams - Input for tasks tool
type TasksResult ¶
type TasksResult struct {
Tasks []Node `json:"tasks"`
Stats TaskStats `json:"stats"`
DependencyGraph []Dependency `json:"dependency_graph,omitempty"`
Recommended []Node `json:"recommended,omitempty"`
}
TasksResult - Output from tasks tool
type Tool ¶
type Tool struct {
Name string `json:"name"`
Description string `json:"description"`
InputSchema json.RawMessage `json:"inputSchema"`
}
Tool represents an MCP tool definition
func GetToolDefinitions ¶
func GetToolDefinitions() []Tool
GetToolDefinitions returns all 6 MCP tool definitions with JSON schemas. These tools are designed for LLM-native usage with: - Verb-noun naming (clear intent) - Minimal required parameters - Smart defaults - Rich, actionable responses
Note: File indexing (index/unindex) is handled by the application layer. NornicDB is the storage/embedding layer - it receives already-processed content.
func GetToolDefinitionsWithDefaultDatabase ¶
GetToolDefinitionsWithDefaultDatabase returns all MCP tool definitions using the provided default database name in the shared `database` parameter schema.