feat(learnings): add store and MCP tool layer
Some checks failed
CI / build-and-test (push) Failing after -32m34s
CI / build-and-test (pull_request) Failing after -32m27s

This commit is contained in:
2026-04-22 14:00:12 +02:00
parent c4d260d971
commit 3e832eea98
6 changed files with 490 additions and 0 deletions

View File

@@ -40,6 +40,7 @@ type ToolSet struct {
Skills *tools.SkillsTool
ChatHistory *tools.ChatHistoryTool
Describe *tools.DescribeTool
Learnings *tools.LearningsTool
}
// Handlers groups the HTTP handlers produced for an MCP server instance.
@@ -83,6 +84,7 @@ func NewHandlers(cfg config.MCPConfig, logger *slog.Logger, toolSet ToolSet, onS
registerSystemTools,
registerThoughtTools,
registerProjectTools,
registerLearningTools,
registerFileTools,
registerMaintenanceTools,
registerSkillTools,
@@ -249,6 +251,28 @@ func registerProjectTools(server *mcp.Server, logger *slog.Logger, toolSet ToolS
return nil
}
func registerLearningTools(server *mcp.Server, logger *slog.Logger, toolSet ToolSet) error {
if err := addTool(server, logger, &mcp.Tool{
Name: "add_learning",
Description: "Create a curated learning record distinct from raw thoughts.",
}, toolSet.Learnings.Add); err != nil {
return err
}
if err := addTool(server, logger, &mcp.Tool{
Name: "get_learning",
Description: "Retrieve a structured learning by id.",
}, toolSet.Learnings.Get); err != nil {
return err
}
if err := addTool(server, logger, &mcp.Tool{
Name: "list_learnings",
Description: "List structured learnings with optional project, status, priority, tag, and text filters.",
}, toolSet.Learnings.List); err != nil {
return err
}
return nil
}
func registerFileTools(server *mcp.Server, logger *slog.Logger, toolSet ToolSet) error {
server.AddResourceTemplate(&mcp.ResourceTemplate{
Name: "stored_file",
@@ -477,6 +501,11 @@ func BuildToolCatalog() []tools.ToolEntry {
{Name: "get_active_project", Description: "Return the active project for the current MCP session. If your client does not preserve MCP sessions, pass project explicitly to project-scoped tools instead of relying on this.", Category: "projects"},
{Name: "get_project_context", Description: "Get recent and semantic context for a project. Uses the explicit project when provided, otherwise the active MCP session project. Falls back to full-text search when no embeddings exist.", Category: "projects"},
// learnings
{Name: "add_learning", Description: "Create a curated learning record distinct from raw thoughts.", Category: "projects"},
{Name: "get_learning", Description: "Retrieve a structured learning by id.", Category: "projects"},
{Name: "list_learnings", Description: "List structured learnings with optional project, category, area, status, priority, tag, and text filters.", Category: "projects"},
// files
{Name: "upload_file", Description: "Stage a file and get an amcs://files/{id} resource URI. Use content_path (absolute server-side path, no size limit) for large or binary files, or content_base64 (≤10 MB) for small files. Pass thought_id/project to link immediately, or omit and pass the URI to save_file later.", Category: "files"},
{Name: "save_file", Description: "Store a file and optionally link it to a thought. Use content_base64 (≤10 MB) for small files, or content_uri (amcs://files/{id} from a prior upload_file) for previously staged files. For files larger than 10 MB, use upload_file with content_path first. If the goal is to retain the artifact, store the file directly instead of reading or summarising it first.", Category: "files"},

View File

@@ -29,6 +29,7 @@ func TestNewListsAllRegisteredTools(t *testing.T) {
want := []string{
"add_guardrail",
"add_learning",
"add_maintenance_task",
"add_project_guardrail",
"add_project_skill",
@@ -43,6 +44,7 @@ func TestNewListsAllRegisteredTools(t *testing.T) {
"describe_tools",
"get_active_project",
"get_chat_history",
"get_learning",
"get_project_context",
"get_thought",
"get_upcoming_maintenance",
@@ -51,6 +53,7 @@ func TestNewListsAllRegisteredTools(t *testing.T) {
"list_chat_histories",
"list_files",
"list_guardrails",
"list_learnings",
"list_project_guardrails",
"list_project_skills",
"list_projects",