Files
tao-memory-mcp/mcp_tools.go
2026-03-14 16:16:32 +08:00

472 lines
13 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package main
import (
"strconv"
)
// Tool 定义了 MCP 工具的元数据和执行逻辑
type Tool struct {
Name string
Description string
InputSchema map[string]interface{}
Handler func(args map[string]interface{}) (string, error)
}
// ToolRegistry 存储所有已注册的工具
var ToolRegistry = make(map[string]Tool)
func (s *TaoServer) RegisterTools() {
// 1) query_memory
ToolRegistry["query_memory"] = Tool{
Name: "query_memory",
Description: "在知识海洋中进行全文检索(默认 exactcausal 时可传 related_terms 作为关联词数组;默认不搜索归档区,需 include_archive=true 才会搜索 _Archive",
InputSchema: map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"q": map[string]interface{}{"type": "string", "description": "关键词"},
"mode": map[string]interface{}{"type": "string", "enum": []string{"exact", "causal"}, "default": "exact"},
"related_terms": map[string]interface{}{"type": "array", "items": map[string]interface{}{"type": "string"}, "description": "关联词数组(仅 mode=causal"},
"include_archive": map[string]interface{}{"type": "boolean", "default": false},
},
"required": []string{"q"},
},
Handler: func(args map[string]interface{}) (string, error) {
q, _ := args["q"].(string)
includeArchive := false
if v, ok := args["include_archive"]; ok {
if b, ok := v.(bool); ok {
includeArchive = b
}
}
mode := "exact"
if v, ok := args["mode"].(string); ok && v != "" {
mode = v
}
related := []string{}
if v, ok := args["related_terms"]; ok {
if arr, ok := v.([]interface{}); ok {
for _, t := range arr {
if s, ok := t.(string); ok && s != "" {
related = append(related, s)
}
}
}
}
results, _ := s.SearchMemoryAdvanced(q, related, mode == "causal", includeArchive)
return stringsJoin(results, "\n\n"), nil
},
}
// 2) get_week_data
ToolRegistry["get_week_data"] = Tool{
Name: "get_week_data",
Description: "获取指定周的所有原始素材用于炼化",
InputSchema: map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"weekOffset": map[string]interface{}{"type": "integer", "default": 0},
},
},
Handler: func(args map[string]interface{}) (string, error) {
offset := 0
if val, ok := args["weekOffset"]; ok {
switch t := val.(type) {
case float64:
offset = int(t)
case int:
offset = t
case string:
if n, err := strconv.Atoi(t); err == nil {
offset = n
}
}
}
return s.GetWeekData(offset)
},
}
// 3) record_summary
ToolRegistry["record_summary"] = Tool{
Name: "record_summary",
Description: "将炼化后的周精华存入 Week_Summary.md若缺失炼丹笔记结构将自动套用模板",
InputSchema: map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"content": map[string]interface{}{"type": "string"},
"weekOffset": map[string]interface{}{"type": "integer", "default": 0},
},
"required": []string{"content"},
},
Handler: func(args map[string]interface{}) (string, error) {
content, _ := args["content"].(string)
offset := 0
if val, ok := args["weekOffset"]; ok {
switch t := val.(type) {
case float64:
offset = int(t)
case int:
offset = t
case string:
if n, err := strconv.Atoi(t); err == nil {
offset = n
}
}
}
content = s.ApplyWeeklyTemplateIfMissing(content, offset)
return s.RecordSummary(content, offset)
},
}
// 4) capture_idea
ToolRegistry["capture_idea"] = Tool{
Name: "capture_idea",
Description: "捕获瞬时灵感/知识片段,自动归档并可附标签",
InputSchema: map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"content": map[string]interface{}{"type": "string", "description": "灵感内容"},
"tags": map[string]interface{}{"type": "array", "items": map[string]interface{}{"type": "string"}, "description": "可选标签"},
},
"required": []string{"content"},
},
Handler: func(args map[string]interface{}) (string, error) {
content, _ := args["content"].(string)
tags := []string{}
if v, ok := args["tags"]; ok {
if arr, ok := v.([]interface{}); ok {
for _, t := range arr {
if s, ok := t.(string); ok && s != "" {
tags = append(tags, s)
}
}
}
}
return s.CaptureIdea(content, tags)
},
}
// 5) get_month_data
ToolRegistry["get_month_data"] = Tool{
Name: "get_month_data",
Description: "获取指定月份的周总结素材",
InputSchema: map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"monthOffset": map[string]interface{}{"type": "integer", "default": 0},
},
},
Handler: func(args map[string]interface{}) (string, error) {
offset := 0
if val, ok := args["monthOffset"]; ok {
switch t := val.(type) {
case float64:
offset = int(t)
case int:
offset = t
case string:
if n, err := strconv.Atoi(t); err == nil {
offset = n
}
}
}
return s.GetMonthData(offset)
},
}
// 6) record_month_summary
ToolRegistry["record_month_summary"] = Tool{
Name: "record_month_summary",
Description: "写入月总结 Month_Summary.md",
InputSchema: map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"content": map[string]interface{}{"type": "string"},
"monthOffset": map[string]interface{}{"type": "integer", "default": 0},
},
"required": []string{"content"},
},
Handler: func(args map[string]interface{}) (string, error) {
content, _ := args["content"].(string)
offset := 0
if val, ok := args["monthOffset"]; ok {
switch t := val.(type) {
case float64:
offset = int(t)
case int:
offset = t
case string:
if n, err := strconv.Atoi(t); err == nil {
offset = n
}
}
}
return s.RecordMonthSummary(content, offset)
},
}
// 7) get_quarter_data
ToolRegistry["get_quarter_data"] = Tool{
Name: "get_quarter_data",
Description: "获取指定季度的月总结素材",
InputSchema: map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"quarterOffset": map[string]interface{}{"type": "integer", "default": 0},
},
},
Handler: func(args map[string]interface{}) (string, error) {
offset := 0
if val, ok := args["quarterOffset"]; ok {
switch t := val.(type) {
case float64:
offset = int(t)
case int:
offset = t
case string:
if n, err := strconv.Atoi(t); err == nil {
offset = n
}
}
}
return s.GetQuarterData(offset)
},
}
// 8) record_quarter_summary
ToolRegistry["record_quarter_summary"] = Tool{
Name: "record_quarter_summary",
Description: "写入季总结 Quarter_Summary.md",
InputSchema: map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"content": map[string]interface{}{"type": "string"},
"quarterOffset": map[string]interface{}{"type": "integer", "default": 0},
},
"required": []string{"content"},
},
Handler: func(args map[string]interface{}) (string, error) {
content, _ := args["content"].(string)
offset := 0
if val, ok := args["quarterOffset"]; ok {
switch t := val.(type) {
case float64:
offset = int(t)
case int:
offset = t
case string:
if n, err := strconv.Atoi(t); err == nil {
offset = n
}
}
}
return s.RecordQuarterSummary(content, offset)
},
}
// 9) get_semiannual_data
ToolRegistry["get_semiannual_data"] = Tool{
Name: "get_semiannual_data",
Description: "获取指定半年的季度总结素材",
InputSchema: map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"halfOffset": map[string]interface{}{"type": "integer", "default": 0},
},
},
Handler: func(args map[string]interface{}) (string, error) {
offset := 0
if val, ok := args["halfOffset"]; ok {
switch t := val.(type) {
case float64:
offset = int(t)
case int:
offset = t
case string:
if n, err := strconv.Atoi(t); err == nil {
offset = n
}
}
}
return s.GetSemiannualData(offset)
},
}
// 10) record_semiannual_summary
ToolRegistry["record_semiannual_summary"] = Tool{
Name: "record_semiannual_summary",
Description: "写入半年总结 Semiannual_Summary.md",
InputSchema: map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"content": map[string]interface{}{"type": "string"},
"halfOffset": map[string]interface{}{"type": "integer", "default": 0},
},
"required": []string{"content"},
},
Handler: func(args map[string]interface{}) (string, error) {
content, _ := args["content"].(string)
offset := 0
if val, ok := args["halfOffset"]; ok {
switch t := val.(type) {
case float64:
offset = int(t)
case int:
offset = t
case string:
if n, err := strconv.Atoi(t); err == nil {
offset = n
}
}
}
return s.RecordSemiannualSummary(content, offset)
},
}
// 11) get_year_data
ToolRegistry["get_year_data"] = Tool{
Name: "get_year_data",
Description: "获取指定年度的半年总结素材",
InputSchema: map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"yearOffset": map[string]interface{}{"type": "integer", "default": 0},
},
},
Handler: func(args map[string]interface{}) (string, error) {
offset := 0
if val, ok := args["yearOffset"]; ok {
switch t := val.(type) {
case float64:
offset = int(t)
case int:
offset = t
case string:
if n, err := strconv.Atoi(t); err == nil {
offset = n
}
}
}
return s.GetYearData(offset)
},
}
// 12) record_year_summary
ToolRegistry["record_year_summary"] = Tool{
Name: "record_year_summary",
Description: "写入年度总结 Year_Summary.md",
InputSchema: map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"content": map[string]interface{}{"type": "string"},
"yearOffset": map[string]interface{}{"type": "integer", "default": 0},
},
"required": []string{"content"},
},
Handler: func(args map[string]interface{}) (string, error) {
content, _ := args["content"].(string)
offset := 0
if val, ok := args["yearOffset"]; ok {
switch t := val.(type) {
case float64:
offset = int(t)
case int:
offset = t
case string:
if n, err := strconv.Atoi(t); err == nil {
offset = n
}
}
}
return s.RecordYearSummary(content, offset)
},
}
// 13) housekeep_memory
ToolRegistry["housekeep_memory"] = Tool{
Name: "housekeep_memory",
Description: "归档指定月份的原始记录(需月总结完成)",
InputSchema: map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"target_month": map[string]interface{}{"type": "string", "description": "YYYY-MM"},
},
"required": []string{"target_month"},
},
Handler: func(args map[string]interface{}) (string, error) {
target, _ := args["target_month"].(string)
return s.HousekeepMemory(target)
},
}
// 14) inspect_and_propose
ToolRegistry["inspect_and_propose"] = Tool{
Name: "inspect_and_propose",
Description: "检视 tao_mcp_go 与灵感库,生成补丁建议清单(不自动应用)",
InputSchema: map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"repo_path": map[string]interface{}{"type": "string", "description": "仓库路径(可选,默认 tao_mcp_go"},
},
},
Handler: func(args map[string]interface{}) (string, error) {
repo, _ := args["repo_path"].(string)
return s.InspectAndPropose(repo)
},
}
// 15) record_daily
ToolRegistry["record_daily"] = Tool{
Name: "record_daily",
Description: "写入当日记忆流(日记/对话碎片)",
InputSchema: map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"content": map[string]interface{}{"type": "string"},
"karma": map[string]interface{}{"type": "integer", "default": 1},
},
"required": []string{"content"},
},
Handler: func(args map[string]interface{}) (string, error) {
content, _ := args["content"].(string)
karma := 1
if v, ok := args["karma"]; ok {
switch t := v.(type) {
case float64:
karma = int(t)
case int:
karma = t
case string:
if n, err := strconv.Atoi(t); err == nil {
karma = n
}
}
}
return s.RecordDaily(content, karma)
},
}
}
func buildToolList() []map[string]interface{} {
var toolList []map[string]interface{}
for _, t := range ToolRegistry {
toolList = append(toolList, map[string]interface{}{
"name": t.Name,
"description": t.Description,
"inputSchema": t.InputSchema,
})
}
return toolList
}
func stringsJoin(items []string, sep string) string {
if len(items) == 0 {
return ""
}
out := items[0]
for i := 1; i < len(items); i++ {
out = out + sep + items[i]
}
return out
}