feat: tao-mcp-go core features

This commit is contained in:
OpenClaw Agent
2026-03-14 16:09:09 +08:00
parent ebaf325222
commit a9c26fae45
7 changed files with 1604 additions and 0 deletions

471
mcp_tools.go Normal file
View File

@@ -0,0 +1,471 @@
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
}