mcp

package
v1.2.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 20, 2026 License: MIT Imports: 17 Imported by: 0

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

View Source
const (
	ToolStore    = "store"
	ToolRecall   = "recall"
	ToolDiscover = "discover"
	ToolLink     = "link"
	ToolTask     = "task"
	ToolTasks    = "tasks"
)

ToolName constants for type-safe tool references

Variables

View Source
var (
	// ValidTaskStatuses for task status validation
	ValidTaskStatuses = []string{
		"pending", "active", "completed", "blocked",
	}

	// ValidTaskPriorities for task priority validation
	ValidTaskPriorities = []string{
		"low", "medium", "high", "critical",
	}
)
View Source
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.

MCPRolePermissions maps each MCP role to its allowed permissions. Note: index/unindex permissions removed - file indexing is handled by the application layer.

View Source
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 AllTools

func AllTools() []string

AllTools returns all tool names

func CanUseTool

func CanUseTool(role MCPRole, tool string) bool

CanUseTool checks if a role can use a specific MCP tool.

func ContextWithDatabase

func ContextWithDatabase(ctx context.Context, dbName string) context.Context

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

func DatabaseFromContext(ctx context.Context) string

DatabaseFromContext returns the database name from the context, or empty if not set.

func DefaultFloatIfZero

func DefaultFloatIfZero(f, defaultVal float64) float64

DefaultFloatIfZero returns default value if f is zero

func DefaultIfEmpty

func DefaultIfEmpty(s, defaultVal string) string

DefaultIfEmpty returns default value if s is empty

func DefaultIntIfZero

func DefaultIntIfZero(i, defaultVal int) int

DefaultIntIfZero returns default value if i is zero

func ExtractResourceType

func ExtractResourceType(tool string, args map[string]interface{}) string

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

func InferOperation(tool string, args map[string]interface{}) string

InferOperation determines the CRUD operation from tool and arguments

func IsValidNodeType

func IsValidNodeType(t string) bool

IsValidNodeType checks if node type is a valid identifier (abstract: any Cypher-safe label).

func IsValidRelation

func IsValidRelation(r string) bool

IsValidRelation checks if relation type is a valid identifier (abstract: any Cypher-safe relationship type).

func IsValidTaskPriority

func IsValidTaskPriority(p string) bool

IsValidTaskPriority checks if task priority is valid

func IsValidTaskStatus

func IsValidTaskStatus(s string) bool

IsValidTaskStatus checks if task status is valid

func IsValidTool

func IsValidTool(name string) bool

IsValidTool checks if a tool name is valid

Types

type AuditLogger

type AuditLogger struct {
	// contains filtered or unexported fields
}

AuditLogger manages multi-sink audit logging.

func NewAuditLogger

func NewAuditLogger() *AuditLogger

NewAuditLogger creates a new audit logger.

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

type ClientInfo struct {
	Name    string `json:"name"`
	Version string `json:"version"`
}

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 ListToolsRequest

type ListToolsRequest struct{}

ListToolsRequest requests available tools

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

func RoleFromString(s string) (MCPRole, error)

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 RateLimit

type RateLimit struct {
	RequestsPerMinute int
	RequestsPerHour   int
	BurstSize         int
}

RateLimit defines rate limit configuration.

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 NewRateLimiter

func NewRateLimiter() *RateLimiter

NewRateLimiter creates a new rate limiter.

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

func (s *Server) DefaultDatabaseName() string

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

func (s *Server) RegisterRoutes(mux *http.ServeMux)

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

func (s *Server) SetDatabaseScopedStorage(fn func(dbName string) (storage.Engine, error))

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

func (s *Server) SetEmbedder(e Embedder)

SetEmbedder sets the embedding service.

func (*Server) Start

func (s *Server) Start(addr string) error

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) Stop

func (s *Server) Stop(ctx context.Context) error

Stop gracefully shuts down the server.

func (*Server) ToolDefinitions

func (s *Server) ToolDefinitions() []Tool

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

type ServerInfo struct {
	Name    string `json:"name"`
	Version string `json:"version"`
}

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

func GetToolDefinitionsWithDefaultDatabase(defaultDatabase string) []Tool

GetToolDefinitionsWithDefaultDatabase returns all MCP tool definitions using the provided default database name in the shared `database` parameter schema.

type ToolHandler

type ToolHandler func(ctx context.Context, args map[string]interface{}) (interface{}, error)

ToolHandler is a function that handles a tool call

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL