|
|
@@ -2,17 +2,33 @@ package data
|
|
|
|
|
|
import (
|
|
|
"context"
|
|
|
+ "encoding/json"
|
|
|
|
|
|
"github.com/mark3labs/mcp-go/mcp"
|
|
|
|
|
|
"fwh-toolbox-server/cmd/mcp/tools/helper"
|
|
|
)
|
|
|
|
|
|
+// planeV2RawResult 将 Plane V2 API 返回的原始 JSON bytes 转为 MCP 结果。
|
|
|
+// 结果较大时自动落盘到本地文件(/tmp/fwh-toolbox-agent/results/),
|
|
|
+// 返回 localPath + 预览,避免大数据占用 LLM 上下文。
|
|
|
+func planeV2RawResult(data []byte, err error, action string) (*mcp.CallToolResult, error) {
|
|
|
+ if err != nil {
|
|
|
+ return helper.ServiceError(action, err), nil
|
|
|
+ }
|
|
|
+ // 解析为 any 再格式化输出;解析失败则按原始文本走落盘判断
|
|
|
+ var parsed any
|
|
|
+ if jsonErr := json.Unmarshal(data, &parsed); jsonErr != nil {
|
|
|
+ return helper.BytesResultOrFile(data, "plane_v2_"+action), nil
|
|
|
+ }
|
|
|
+ return helper.JSONResultOrFile(parsed, "plane_v2_"+action), nil
|
|
|
+}
|
|
|
+
|
|
|
// === Workspace Handlers ===
|
|
|
|
|
|
func handlePlaneV2ListWorkspaces(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
|
|
data, err := planeV2Svc.ListWorkspaces()
|
|
|
- return planeRawResult(data, err, "列出工作空间")
|
|
|
+ return planeV2RawResult(data, err, "列出工作空间")
|
|
|
}
|
|
|
|
|
|
func handlePlaneV2GetWorkspace(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
|
|
@@ -21,7 +37,7 @@ func handlePlaneV2GetWorkspace(ctx context.Context, req mcp.CallToolRequest) (*m
|
|
|
return helper.ParamError("workspace_slug"), nil
|
|
|
}
|
|
|
data, apiErr := planeV2Svc.GetWorkspace(slug)
|
|
|
- return planeRawResult(data, apiErr, "获取工作空间详情")
|
|
|
+ return planeV2RawResult(data, apiErr, "获取工作空间详情")
|
|
|
}
|
|
|
|
|
|
// === Project Handlers ===
|
|
|
@@ -32,7 +48,7 @@ func handlePlaneV2ListProjects(ctx context.Context, req mcp.CallToolRequest) (*m
|
|
|
return helper.ParamError("workspace_slug"), nil
|
|
|
}
|
|
|
data, apiErr := planeV2Svc.ListProjects(slug)
|
|
|
- return planeRawResult(data, apiErr, "列出项目")
|
|
|
+ return planeV2RawResult(data, apiErr, "列出项目")
|
|
|
}
|
|
|
|
|
|
func handlePlaneV2GetProject(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
|
|
@@ -42,7 +58,7 @@ func handlePlaneV2GetProject(ctx context.Context, req mcp.CallToolRequest) (*mcp
|
|
|
return helper.ParamError("project_id"), nil
|
|
|
}
|
|
|
data, apiErr := planeV2Svc.GetProject(slug, projectId)
|
|
|
- return planeRawResult(data, apiErr, "获取项目详情")
|
|
|
+ return planeV2RawResult(data, apiErr, "获取项目详情")
|
|
|
}
|
|
|
|
|
|
// === Issue Handlers ===
|
|
|
@@ -51,7 +67,7 @@ func handlePlaneV2ListIssues(ctx context.Context, req mcp.CallToolRequest) (*mcp
|
|
|
slug, _ := req.RequireString("workspace_slug")
|
|
|
projectId, _ := req.RequireString("project_id")
|
|
|
data, err := planeV2Svc.ListIssues(slug, projectId)
|
|
|
- return planeRawResult(data, err, "列出工作项")
|
|
|
+ return planeV2RawResult(data, err, "列出工作项")
|
|
|
}
|
|
|
|
|
|
func handlePlaneV2GetIssue(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
|
|
@@ -62,7 +78,7 @@ func handlePlaneV2GetIssue(ctx context.Context, req mcp.CallToolRequest) (*mcp.C
|
|
|
return helper.ParamError("issue_id"), nil
|
|
|
}
|
|
|
data, apiErr := planeV2Svc.GetIssue(slug, projectId, issueId)
|
|
|
- return planeRawResult(data, apiErr, "获取工作项详情")
|
|
|
+ return planeV2RawResult(data, apiErr, "获取工作项详情")
|
|
|
}
|
|
|
|
|
|
func handlePlaneV2GetSubIssues(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
|
|
@@ -73,7 +89,7 @@ func handlePlaneV2GetSubIssues(ctx context.Context, req mcp.CallToolRequest) (*m
|
|
|
return helper.ParamError("issue_id"), nil
|
|
|
}
|
|
|
data, apiErr := planeV2Svc.GetSubIssues(slug, projectId, issueId)
|
|
|
- return planeRawResult(data, apiErr, "获取子工作项")
|
|
|
+ return planeV2RawResult(data, apiErr, "获取子工作项")
|
|
|
}
|
|
|
|
|
|
func handlePlaneV2GetIssueActivity(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
|
|
@@ -84,7 +100,7 @@ func handlePlaneV2GetIssueActivity(ctx context.Context, req mcp.CallToolRequest)
|
|
|
return helper.ParamError("issue_id"), nil
|
|
|
}
|
|
|
data, apiErr := planeV2Svc.GetIssueActivity(slug, projectId, issueId)
|
|
|
- return planeRawResult(data, apiErr, "获取工作项活动历史")
|
|
|
+ return planeV2RawResult(data, apiErr, "获取工作项活动历史")
|
|
|
}
|
|
|
|
|
|
// === Intake Handlers ===
|
|
|
@@ -94,7 +110,7 @@ func handlePlaneV2ListIntakeIssues(ctx context.Context, req mcp.CallToolRequest)
|
|
|
projectId, _ := req.RequireString("project_id")
|
|
|
status := req.GetString("status", "")
|
|
|
data, err := planeV2Svc.ListIntakeIssues(slug, projectId, status)
|
|
|
- return planeRawResult(data, err, "列出收件箱工作项")
|
|
|
+ return planeV2RawResult(data, err, "列出收件箱工作项")
|
|
|
}
|
|
|
|
|
|
func handlePlaneV2GetIntakeIssue(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
|
|
@@ -105,7 +121,7 @@ func handlePlaneV2GetIntakeIssue(ctx context.Context, req mcp.CallToolRequest) (
|
|
|
return helper.ParamError("issue_id"), nil
|
|
|
}
|
|
|
data, apiErr := planeV2Svc.GetIntakeIssue(slug, projectId, issueId)
|
|
|
- return planeRawResult(data, apiErr, "获取收件箱工作项详情")
|
|
|
+ return planeV2RawResult(data, apiErr, "获取收件箱工作项详情")
|
|
|
}
|
|
|
|
|
|
// === Cycle Handlers ===
|
|
|
@@ -114,7 +130,7 @@ func handlePlaneV2ListCycles(ctx context.Context, req mcp.CallToolRequest) (*mcp
|
|
|
slug, _ := req.RequireString("workspace_slug")
|
|
|
projectId, _ := req.RequireString("project_id")
|
|
|
data, err := planeV2Svc.ListCycles(slug, projectId)
|
|
|
- return planeRawResult(data, err, "列出周期")
|
|
|
+ return planeV2RawResult(data, err, "列出周期")
|
|
|
}
|
|
|
|
|
|
func handlePlaneV2GetCycle(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
|
|
@@ -125,7 +141,7 @@ func handlePlaneV2GetCycle(ctx context.Context, req mcp.CallToolRequest) (*mcp.C
|
|
|
return helper.ParamError("cycle_id"), nil
|
|
|
}
|
|
|
data, apiErr := planeV2Svc.GetCycle(slug, projectId, cycleId)
|
|
|
- return planeRawResult(data, apiErr, "获取周期详情")
|
|
|
+ return planeV2RawResult(data, apiErr, "获取周期详情")
|
|
|
}
|
|
|
|
|
|
// === Module Handlers ===
|
|
|
@@ -134,7 +150,7 @@ func handlePlaneV2ListModules(ctx context.Context, req mcp.CallToolRequest) (*mc
|
|
|
slug, _ := req.RequireString("workspace_slug")
|
|
|
projectId, _ := req.RequireString("project_id")
|
|
|
data, err := planeV2Svc.ListModules(slug, projectId)
|
|
|
- return planeRawResult(data, err, "列出模块")
|
|
|
+ return planeV2RawResult(data, err, "列出模块")
|
|
|
}
|
|
|
|
|
|
func handlePlaneV2GetModule(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
|
|
@@ -145,7 +161,7 @@ func handlePlaneV2GetModule(ctx context.Context, req mcp.CallToolRequest) (*mcp.
|
|
|
return helper.ParamError("module_id"), nil
|
|
|
}
|
|
|
data, apiErr := planeV2Svc.GetModule(slug, projectId, moduleId)
|
|
|
- return planeRawResult(data, apiErr, "获取模块详情")
|
|
|
+ return planeV2RawResult(data, apiErr, "获取模块详情")
|
|
|
}
|
|
|
|
|
|
// === Label Handlers ===
|
|
|
@@ -154,7 +170,7 @@ func handlePlaneV2ListLabels(ctx context.Context, req mcp.CallToolRequest) (*mcp
|
|
|
slug, _ := req.RequireString("workspace_slug")
|
|
|
projectId, _ := req.RequireString("project_id")
|
|
|
data, err := planeV2Svc.ListLabels(slug, projectId)
|
|
|
- return planeRawResult(data, err, "列出标签")
|
|
|
+ return planeV2RawResult(data, err, "列出标签")
|
|
|
}
|
|
|
|
|
|
// === State Handlers ===
|
|
|
@@ -163,7 +179,7 @@ func handlePlaneV2ListStates(ctx context.Context, req mcp.CallToolRequest) (*mcp
|
|
|
slug, _ := req.RequireString("workspace_slug")
|
|
|
projectId, _ := req.RequireString("project_id")
|
|
|
data, err := planeV2Svc.ListStates(slug, projectId)
|
|
|
- return planeRawResult(data, err, "列出状态")
|
|
|
+ return planeV2RawResult(data, err, "列出状态")
|
|
|
}
|
|
|
|
|
|
// === Page Handlers ===
|
|
|
@@ -172,7 +188,7 @@ func handlePlaneV2ListPages(ctx context.Context, req mcp.CallToolRequest) (*mcp.
|
|
|
slug, _ := req.RequireString("workspace_slug")
|
|
|
projectId, _ := req.RequireString("project_id")
|
|
|
data, err := planeV2Svc.ListPages(slug, projectId)
|
|
|
- return planeRawResult(data, err, "列出页面")
|
|
|
+ return planeV2RawResult(data, err, "列出页面")
|
|
|
}
|
|
|
|
|
|
func handlePlaneV2GetPage(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
|
|
@@ -183,7 +199,7 @@ func handlePlaneV2GetPage(ctx context.Context, req mcp.CallToolRequest) (*mcp.Ca
|
|
|
return helper.ParamError("page_id"), nil
|
|
|
}
|
|
|
data, apiErr := planeV2Svc.GetPage(slug, projectId, pageId)
|
|
|
- return planeRawResult(data, apiErr, "获取页面详情")
|
|
|
+ return planeV2RawResult(data, apiErr, "获取页面详情")
|
|
|
}
|
|
|
|
|
|
func handlePlaneV2GetPageDescription(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
|
|
@@ -194,7 +210,7 @@ func handlePlaneV2GetPageDescription(ctx context.Context, req mcp.CallToolReques
|
|
|
return helper.ParamError("page_id"), nil
|
|
|
}
|
|
|
data, apiErr := planeV2Svc.GetPageDescription(slug, projectId, pageId)
|
|
|
- return planeRawResult(data, apiErr, "获取页面描述内容")
|
|
|
+ return planeV2RawResult(data, apiErr, "获取页面描述内容")
|
|
|
}
|
|
|
|
|
|
// === Member Handlers ===
|
|
|
@@ -205,14 +221,14 @@ func handlePlaneV2ListWorkspaceMembers(ctx context.Context, req mcp.CallToolRequ
|
|
|
return helper.ParamError("workspace_slug"), nil
|
|
|
}
|
|
|
data, apiErr := planeV2Svc.ListWorkspaceMembers(slug)
|
|
|
- return planeRawResult(data, apiErr, "列出工作空间成员")
|
|
|
+ return planeV2RawResult(data, apiErr, "列出工作空间成员")
|
|
|
}
|
|
|
|
|
|
func handlePlaneV2ListProjectMembers(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
|
|
slug, _ := req.RequireString("workspace_slug")
|
|
|
projectId, _ := req.RequireString("project_id")
|
|
|
data, err := planeV2Svc.ListProjectMembers(slug, projectId)
|
|
|
- return planeRawResult(data, err, "列出项目成员")
|
|
|
+ return planeV2RawResult(data, err, "列出项目成员")
|
|
|
}
|
|
|
|
|
|
// === Sticky Handlers ===
|
|
|
@@ -223,5 +239,5 @@ func handlePlaneV2ListStickies(ctx context.Context, req mcp.CallToolRequest) (*m
|
|
|
return helper.ParamError("workspace_slug"), nil
|
|
|
}
|
|
|
data, apiErr := planeV2Svc.ListStickies(slug)
|
|
|
- return planeRawResult(data, apiErr, "列出便签")
|
|
|
+ return planeV2RawResult(data, apiErr, "列出便签")
|
|
|
}
|