mcp.WithDescription("List memos visible to the caller. Authenticated users see their own memos plus public and protected memos; unauthenticated callers see only public memos."),
readOnlyToolOptions("List memos","List memos visible to the caller. Authenticated users see their own memos plus public and protected memos; unauthenticated callers see only public memos.",
mcp.WithNumber("page_size",mcp.Description("Maximum memos to return (1–100, default 20)")),
mcp.WithNumber("page_size",mcp.Description("Maximum memos to return (1–100, default 20)")),
mcp.WithNumber("page",mcp.Description("Zero-based page index for pagination (default 0)")),
mcp.WithNumber("page",mcp.Description("Zero-based page index for pagination (default 0)")),
mcp.WithString("state",
mcp.WithString("state",
...
@@ -224,24 +188,30 @@ func (s *MCPService) registerMemoTools(mcpSrv *mcpserver.MCPServer) {
...
@@ -224,24 +188,30 @@ func (s *MCPService) registerMemoTools(mcpSrv *mcpserver.MCPServer) {
),
),
mcp.WithBoolean("order_by_pinned",mcp.Description("When true, pinned memos appear first (default false)")),
mcp.WithBoolean("order_by_pinned",mcp.Description("When true, pinned memos appear first (default false)")),
mcp.WithString("filter",mcp.Description(`Optional CEL filter (supported subset of standard CEL syntax), e.g. content.contains("keyword") or tags.exists(t, t == "work")`)),
mcp.WithString("filter",mcp.Description(`Optional CEL filter (supported subset of standard CEL syntax), e.g. content.contains("keyword") or tags.exists(t, t == "work")`)),
mcp.WithOutputSchema[memoListJSON](),
)...,
),s.handleListMemos)
),s.handleListMemos)
mcpSrv.AddTool(mcp.NewTool("get_memo",
mcpSrv.AddTool(mcp.NewTool("get_memo",
mcp.WithDescription("Get a single memo by resource name. Public memos are accessible without authentication."),
readOnlyToolOptions("Get memo","Get a single memo by resource name. Public memos are accessible without authentication.",
mcp.WithString("name",mcp.Required(),mcp.Description(`Memo resource name, e.g. "memos/abc123"`)),
mcp.WithString("name",mcp.Required(),mcp.Description(`Memo resource name, e.g. "memos/abc123"`)),
mcp.WithOutputSchema[memoJSON](),
)...,
),s.handleGetMemo)
),s.handleGetMemo)
mcpSrv.AddTool(mcp.NewTool("create_memo",
mcpSrv.AddTool(mcp.NewTool("create_memo",
mcp.WithDescription("Create a new memo. Requires authentication."),
createToolOptions("Create memo","Create a new memo. Requires authentication.",false,
mcp.WithString("content",mcp.Required(),mcp.Description("Memo content in Markdown. Use #tag syntax for tagging.")),
mcp.WithString("content",mcp.Required(),mcp.Description("Memo content in Markdown. Use #tag syntax for tagging.")),
mcp.WithString("visibility",
mcp.WithString("visibility",
mcp.Enum("PRIVATE","PROTECTED","PUBLIC"),
mcp.Enum("PRIVATE","PROTECTED","PUBLIC"),
mcp.Description("Visibility (default: PRIVATE)"),
mcp.Description("Visibility (default: PRIVATE)"),
),
),
mcp.WithOutputSchema[memoJSON](),
)...,
),s.handleCreateMemo)
),s.handleCreateMemo)
mcpSrv.AddTool(mcp.NewTool("update_memo",
mcpSrv.AddTool(mcp.NewTool("update_memo",
mcp.WithDescription("Update a memo's content, visibility, pin state, or archive state. Requires authentication and ownership. Omit any field to leave it unchanged."),
updateToolOptions("Update memo","Update a memo's content, visibility, pin state, or archive state. Requires authentication and ownership. Omit any field to leave it unchanged.",
mcp.WithString("name",mcp.Required(),mcp.Description(`Memo resource name, e.g. "memos/abc123"`)),
mcp.WithString("name",mcp.Required(),mcp.Description(`Memo resource name, e.g. "memos/abc123"`)),
@@ -253,27 +223,35 @@ func (s *MCPService) registerMemoTools(mcpSrv *mcpserver.MCPServer) {
...
@@ -253,27 +223,35 @@ func (s *MCPService) registerMemoTools(mcpSrv *mcpserver.MCPServer) {
mcp.Enum("NORMAL","ARCHIVED"),
mcp.Enum("NORMAL","ARCHIVED"),
mcp.Description("Set to ARCHIVED to archive, NORMAL to restore"),
mcp.Description("Set to ARCHIVED to archive, NORMAL to restore"),
),
),
mcp.WithOutputSchema[memoJSON](),
)...,
),s.handleUpdateMemo)
),s.handleUpdateMemo)
mcpSrv.AddTool(mcp.NewTool("delete_memo",
mcpSrv.AddTool(mcp.NewTool("delete_memo",
mcp.WithDescription("Permanently delete a memo. Requires authentication and ownership."),
updateToolOptions("Delete memo","Permanently delete a memo. Requires authentication and ownership.",
mcp.WithString("name",mcp.Required(),mcp.Description(`Memo resource name, e.g. "memos/abc123"`)),
mcp.WithString("name",mcp.Required(),mcp.Description(`Memo resource name, e.g. "memos/abc123"`)),
mcp.WithOutputSchema[deletedJSON](),
)...,
),s.handleDeleteMemo)
),s.handleDeleteMemo)
mcpSrv.AddTool(mcp.NewTool("search_memos",
mcpSrv.AddTool(mcp.NewTool("search_memos",
mcp.WithDescription("Search memo content. Authenticated users search their own and visible memos; unauthenticated callers search public memos only."),
readOnlyToolOptions("Search memos","Search memo content. Authenticated users search their own and visible memos; unauthenticated callers search public memos only.",
mcp.WithString("query",mcp.Required(),mcp.Description("Text to search for in memo content")),
mcp.WithString("query",mcp.Required(),mcp.Description("Text to search for in memo content")),
)...,
),s.handleSearchMemos)
),s.handleSearchMemos)
mcpSrv.AddTool(mcp.NewTool("list_memo_comments",
mcpSrv.AddTool(mcp.NewTool("list_memo_comments",
mcp.WithDescription("List comments on a memo. Visibility rules for comments match those of the parent memo."),
readOnlyToolOptions("List memo comments","List comments on a memo. Visibility rules for comments match those of the parent memo.",
mcp.WithString("name",mcp.Required(),mcp.Description(`Memo resource name, e.g. "memos/abc123"`)),
mcp.WithString("name",mcp.Required(),mcp.Description(`Memo resource name, e.g. "memos/abc123"`)),
)...,
),s.handleListMemoComments)
),s.handleListMemoComments)
mcpSrv.AddTool(mcp.NewTool("create_memo_comment",
mcpSrv.AddTool(mcp.NewTool("create_memo_comment",
mcp.WithDescription("Add a comment to a memo. The comment inherits the parent memo's visibility. Requires authentication."),
createToolOptions("Create memo comment","Add a comment to a memo. The comment inherits the parent memo's visibility. Requires authentication.",false,
mcp.WithString("name",mcp.Required(),mcp.Description(`Memo resource name to comment on, e.g. "memos/abc123"`)),
mcp.WithString("name",mcp.Required(),mcp.Description(`Memo resource name to comment on, e.g. "memos/abc123"`)),
mcp.WithString("content",mcp.Required(),mcp.Description("Comment content in Markdown")),
mcp.WithString("content",mcp.Required(),mcp.Description("Comment content in Markdown")),
mcp.WithDescription("List all reactions on a memo. Returns reaction type and creator for each reaction."),
readOnlyToolOptions("List reactions","List all reactions on a memo. Returns reaction type and creator for each reaction.",
mcp.WithString("name",mcp.Required(),mcp.Description(`Memo resource name, e.g. "memos/abc123"`)),
mcp.WithString("name",mcp.Required(),mcp.Description(`Memo resource name, e.g. "memos/abc123"`)),
)...,
),s.handleListReactions)
),s.handleListReactions)
mcpSrv.AddTool(mcp.NewTool("upsert_reaction",
mcpSrv.AddTool(mcp.NewTool("upsert_reaction",
mcp.WithDescription("Add a reaction (emoji) to a memo. If the same reaction already exists from the same user, this is a no-op. Requires authentication."),
createToolOptions("Upsert reaction","Add a reaction (emoji) to a memo. If the same reaction already exists from the same user, this is a no-op. Requires authentication.",true,
mcp.WithString("name",mcp.Required(),mcp.Description(`Memo resource name, e.g. "memos/abc123"`)),
mcp.WithString("name",mcp.Required(),mcp.Description(`Memo resource name, e.g. "memos/abc123"`)),
mcp.WithString("reaction_type",mcp.Required(),mcp.Description(`Reaction emoji, e.g. "👍", "❤️", "🎉"`)),
mcp.WithString("reaction_type",mcp.Required(),mcp.Description(`Reaction emoji, e.g. "👍", "❤️", "🎉"`)),
mcp.WithOutputSchema[reactionJSON](),
)...,
),s.handleUpsertReaction)
),s.handleUpsertReaction)
mcpSrv.AddTool(mcp.NewTool("delete_reaction",
mcpSrv.AddTool(mcp.NewTool("delete_reaction",
mcp.WithDescription("Remove a reaction by its ID. Requires authentication and ownership of the reaction."),
updateToolOptions("Delete reaction","Remove a reaction by its ID. Requires authentication and ownership of the reaction.",
mcp.WithNumber("id",mcp.Required(),mcp.Description("Reaction ID to delete")),
mcp.WithNumber("id",mcp.Required(),mcp.Description("Reaction ID to delete")),
mcp.WithDescription("Create a reference relation between two memos. Requires authentication. For comments, use create_memo_comment instead."),
createToolOptions("Create memo relation","Create a reference relation between two memos. Requires authentication. For comments, use create_memo_comment instead.",true,
mcp.WithString("name",mcp.Required(),mcp.Description(`Source memo resource name, e.g. "memos/abc123"`)),
mcp.WithString("name",mcp.Required(),mcp.Description(`Source memo resource name, e.g. "memos/abc123"`)),
mcp.WithString("related_memo",mcp.Required(),mcp.Description(`Target memo resource name, e.g. "memos/def456"`)),
mcp.WithString("related_memo",mcp.Required(),mcp.Description(`Target memo resource name, e.g. "memos/def456"`)),
mcp.WithDescription("List all tags with their memo counts. Authenticated users see tags from their own and visible memos; unauthenticated callers see tags from public memos only. Results are sorted by count descending, then alphabetically."),
readOnlyToolOptions("List tags","List all tags with their memo counts. Authenticated users see tags from their own and visible memos; unauthenticated callers see tags from public memos only. Results are sorted by count descending, then alphabetically.")...,