You've already forked agentic-coding-workflow
7d9164d478
Phase F: tools_pm.go — list/get/create/update/close/reopen/assign for projects, workspaces, requirements, issues (16 tools total). Phase G: tools_chat.go — list_recent_messages tool; resources.go — 6 PM resource URI templates (projects, project-detail, requirements, issues, workspaces, workspace-detail). Phase H: frontend admin UI — mcpTokens API client, Pinia store, MCPTokenAdminView with create/revoke/list, router entry, NavBar link. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
76 lines
2.3 KiB
Go
76 lines
2.3 KiB
Go
package mcp
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/google/uuid"
|
|
mcpsdk "github.com/modelcontextprotocol/go-sdk/mcp"
|
|
)
|
|
|
|
// registerChatTools 注册 chat 相关 MCP 工具。
|
|
// MVP 只有一个:list_recent_messages。
|
|
func registerChatTools(srv *mcpsdk.Server, deps ServerDeps) {
|
|
registerListRecentMessages(srv, deps)
|
|
}
|
|
|
|
type listRecentMessagesIn struct {
|
|
ConversationID string `json:"conversation_id" jsonschema:"required,description=UUID of the conversation"`
|
|
BeforeID *int64 `json:"before_id,omitempty" jsonschema:"description=Cursor: return messages with ID < this value"`
|
|
Limit int `json:"limit,omitempty" jsonschema:"description=Max messages to return (default 50, max 200)"`
|
|
}
|
|
type messageSummary struct {
|
|
ID int64 `json:"id"`
|
|
Role string `json:"role"`
|
|
Content string `json:"content"`
|
|
Status string `json:"status"`
|
|
CreatedAt string `json:"created_at"`
|
|
}
|
|
type listRecentMessagesOut struct {
|
|
Messages []messageSummary `json:"messages"`
|
|
}
|
|
|
|
func registerListRecentMessages(srv *mcpsdk.Server, deps ServerDeps) {
|
|
mcpsdk.AddTool(srv,
|
|
&mcpsdk.Tool{Name: "list_recent_messages", Description: "List recent chat messages in a conversation."},
|
|
func(ctx context.Context, _ *mcpsdk.CallToolRequest, in listRecentMessagesIn) (*mcpsdk.CallToolResult, listRecentMessagesOut, error) {
|
|
if err := CheckToolFromCtx(ctx, "list_recent_messages"); err != nil {
|
|
return nil, listRecentMessagesOut{}, err
|
|
}
|
|
c, err := deps.Caller.Resolve(ctx)
|
|
if err != nil {
|
|
return nil, listRecentMessagesOut{}, err
|
|
}
|
|
|
|
convID, err := uuid.Parse(in.ConversationID)
|
|
if err != nil {
|
|
return nil, listRecentMessagesOut{}, fmt.Errorf("invalid conversation_id: %w", err)
|
|
}
|
|
|
|
limit := in.Limit
|
|
if limit <= 0 {
|
|
limit = 50
|
|
}
|
|
if limit > 200 {
|
|
limit = 200
|
|
}
|
|
|
|
msgs, err := deps.Messages.ListMessages(ctx, c.UserID, convID, in.BeforeID, limit)
|
|
if err != nil {
|
|
return nil, listRecentMessagesOut{}, err
|
|
}
|
|
|
|
out := listRecentMessagesOut{Messages: make([]messageSummary, 0, len(msgs))}
|
|
for _, m := range msgs {
|
|
out.Messages = append(out.Messages, messageSummary{
|
|
ID: m.ID,
|
|
Role: string(m.Role),
|
|
Content: m.Content,
|
|
Status: string(m.Status),
|
|
CreatedAt: m.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
|
|
})
|
|
}
|
|
return nil, out, nil
|
|
})
|
|
}
|