From 48166f07cd827a5fbdb8c4be5575aedddabb783c Mon Sep 17 00:00:00 2001 From: Richard Lawrence Date: Mon, 29 Jun 2026 14:26:18 -0500 Subject: [PATCH] feat: reply to comment threads - Added `olcli comments reply [project]` command to CLI - Added `reply_to_comment` tool to MCP server - Updated README.md with new command and tool documentation Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- README.md | 3 +++ src/cli.ts | 24 ++++++++++++++++++++++++ src/mcp.ts | 20 ++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/README.md b/README.md index a244bed..fbe3072 100644 --- a/README.md +++ b/README.md @@ -170,6 +170,7 @@ All commands auto-detect the project when run from a synced directory (contains | `olcli download [project]` | Download a single file | | `olcli comments list [project]` | List comments with source text and file locations (`--status`, `--context`) | | `olcli comments add [project]` | Add a comment to selected text | +| `olcli comments reply [project]` | Reply to a comment thread | | `olcli comments resolve [project]` | Resolve a comment thread | | `olcli comments reopen [project]` | Reopen a resolved comment thread | | `olcli comments delete [project]` | Permanently delete a comment thread | @@ -190,6 +191,7 @@ All commands auto-detect the project when run from a synced directory (contains olcli comments list "My Paper" --status open --context 2 olcli comments list "My Paper" --status resolved --json olcli comments add main.tex "Please clarify this definition" "My Paper" --text "A Skill is" +olcli comments reply 6a1a5fedbf90b811e1000001 "I have updated the definition" "My Paper" olcli comments add main.tex "Check this sentence" "My Paper" --line 42 --column 1 --length 20 --json olcli comments resolve 6a1a5fedbf90b811e1000001 "My Paper" --json olcli comments reopen 6a1a5fedbf90b811e1000001 "My Paper" @@ -520,6 +522,7 @@ import { | `get_entities` | Get a flat list of all files in a project | | `download_file` | Download a specific file by its remote path | | `add_comment` | Add a review comment to a document | +| `reply_to_comment` | Add a reply to an existing comment thread | | `resolve_comment` | Mark a comment thread as resolved | | `delete_entity` | Delete a file or document by path | | `rename_entity` | Rename a file or document | diff --git a/src/cli.ts b/src/cli.ts index 82102e0..da87d37 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -370,6 +370,30 @@ commentsCmd } }); +commentsCmd + .command('reply [project]') + .description('Reply to a comment thread with a message') + .option('--json', 'Output as JSON') + .option('--cookie ', 'Session cookie override') + .action(async (threadId, body, project, options) => { + const spinner = ora('Posting reply...').start(); + try { + const client = await getClient(options.cookie); + const proj = await resolveProject(client, project); + const message = await client.postCommentMessage(proj.id, threadId, body); + if (options.json) { + spinner.stop(); + console.log(JSON.stringify({ replied: true, message }, null, 2)); + return; + } + spinner.succeed(`Replied to ${threadId}`); + setLastProject(proj.id); + } catch (error: any) { + spinner.fail(`Failed: ${error.message}`); + process.exit(1); + } + }); + commentsCmd .command('resolve [project]') .description('Resolve a comment thread') diff --git a/src/mcp.ts b/src/mcp.ts index 1724e4b..7c0e323 100644 --- a/src/mcp.ts +++ b/src/mcp.ts @@ -121,6 +121,26 @@ server.tool( }) ); +// --------------------------------------------------------------------------- +// Tool: reply_to_comment +// --------------------------------------------------------------------------- + +server.tool( + 'reply_to_comment', + 'Add a reply to an existing comment thread on an Overleaf project.', + { + project_id: z.string().describe('The Overleaf project ID'), + thread_id: z.string().describe('The comment thread ID (from list_comments)'), + content: z.string().describe('The reply message text'), + }, + async ({ project_id, thread_id, content }) => + wrapTool(async () => { + const client = await getClient(); + const message = await client.postCommentMessage(project_id, thread_id, content); + return { replied: true, thread_id, message }; + }) +); + // --------------------------------------------------------------------------- // Tool: get_project_info // ---------------------------------------------------------------------------