@aloth/olcli 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -438,6 +438,192 @@ olcli output bbl -o main.bbl
438
438
  olcli zip -o arxiv-submission.zip
439
439
  ```
440
440
 
441
+ ## Programmatic Usage (Library API)
442
+
443
+ `@aloth/olcli` exposes `OverleafClient` and all public interfaces as a proper library so you can use it in your own scripts, tools, and AI agents.
444
+
445
+ ### Install
446
+
447
+ ```bash
448
+ npm install @aloth/olcli
449
+ ```
450
+
451
+ ### Basic example
452
+
453
+ ```ts
454
+ import { OverleafClient } from '@aloth/olcli';
455
+
456
+ // Create a client from an Overleaf session cookie
457
+ const client = await OverleafClient.fromSessionCookie(cookie);
458
+
459
+ // List all projects
460
+ const projects = await client.listProjects();
461
+ console.log(projects);
462
+
463
+ // Get detailed info (file tree) for a project
464
+ const info = await client.getProjectInfo(projectId);
465
+
466
+ // Download project as a zip buffer
467
+ const zipBuf = await client.downloadProject(projectId);
468
+
469
+ // Compile and download PDF
470
+ const pdfBuf = await client.downloadPdf(projectId);
471
+
472
+ // Upload a file
473
+ import { readFileSync } from 'node:fs';
474
+ await client.uploadFile(projectId, null, 'main.tex', readFileSync('main.tex'));
475
+
476
+ // List review comments
477
+ const comments = await client.listComments(projectId, { status: 'open' });
478
+ ```
479
+
480
+ ### Available exports
481
+
482
+ ```ts
483
+ import {
484
+ // Core client
485
+ OverleafClient,
486
+
487
+ // Types / interfaces
488
+ Project, ProjectInfo, FolderEntry, DocEntry, FileEntry,
489
+ CommentMessage, ProjectComment, CommentContext, CommentStatus,
490
+ ListCommentsOptions, AddCommentOptions, Credentials,
491
+
492
+ // Configuration utilities
493
+ getBaseUrl, setBaseUrl, getSessionCookie, setSessionCookie,
494
+ getSessionCookieName, setSessionCookieName, getCsrf, setCsrf,
495
+ getLastProject, setLastProject, clearConfig, getConfigPath, saveOlAuth,
496
+
497
+ // Ignore utilities
498
+ DEFAULT_IGNORE_PATTERNS, loadIgnore, shouldIgnore, buildTexSiblingSet,
499
+ IgnoreContext, LoadIgnoreOptions,
500
+ } from '@aloth/olcli';
501
+ ```
502
+
503
+ ---
504
+
505
+ ## MCP Server
506
+
507
+ `@aloth/olcli` ships an [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server so AI assistants like **Claude Desktop**, **Cursor**, and **Windsurf** can interact with your Overleaf projects directly.
508
+
509
+ ### MCP tools
510
+
511
+ | Tool | Description |
512
+ |------|-------------|
513
+ | `list_projects` | List all Overleaf projects |
514
+ | `get_project_info` | Get file tree and metadata for a project |
515
+ | `pull_project` | Download and extract a project to a local directory |
516
+ | `push_file` | Upload a local file to a project |
517
+ | `compile` | Compile a project and get the PDF URL |
518
+ | `download_pdf` | Compile a project and save the PDF locally |
519
+ | `list_comments` | List review comments (filter: all / open / resolved) |
520
+ | `get_entities` | Get a flat list of all files in a project |
521
+ | `download_file` | Download a specific file by its remote path |
522
+ | `add_comment` | Add a review comment to a document |
523
+ | `resolve_comment` | Mark a comment thread as resolved |
524
+ | `delete_entity` | Delete a file or document by path |
525
+ | `rename_entity` | Rename a file or document |
526
+ | `compile_with_outputs` | Compile and return all output files (PDF, BBL, logs…) |
527
+
528
+ ### Authentication
529
+
530
+ The MCP server reads your session cookie in this order:
531
+
532
+ 1. **`OVERLEAF_SESSION` environment variable** — set in your MCP config (recommended)
533
+ 2. **`.olauth` file in cwd** — written by `olcli auth`
534
+ 3. **Stored config** — written by `olcli auth`
535
+
536
+ ### Claude Desktop
537
+
538
+ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
539
+
540
+ ```json
541
+ {
542
+ "mcpServers": {
543
+ "overleaf": {
544
+ "command": "npx",
545
+ "args": ["-y", "@aloth/olcli-mcp"],
546
+ "env": {
547
+ "OVERLEAF_SESSION": "<your-overleaf-session-cookie>"
548
+ }
549
+ }
550
+ }
551
+ }
552
+ ```
553
+
554
+ Or if you have olcli installed globally (`npm install -g @aloth/olcli`):
555
+
556
+ ```json
557
+ {
558
+ "mcpServers": {
559
+ "overleaf": {
560
+ "command": "olcli-mcp",
561
+ "env": {
562
+ "OVERLEAF_SESSION": "<your-overleaf-session-cookie>"
563
+ }
564
+ }
565
+ }
566
+ }
567
+ ```
568
+
569
+ ### Cursor
570
+
571
+ Add to your Cursor MCP settings (`~/.cursor/mcp.json` or project `.cursor/mcp.json`):
572
+
573
+ ```json
574
+ {
575
+ "mcpServers": {
576
+ "overleaf": {
577
+ "command": "npx",
578
+ "args": ["-y", "@aloth/olcli-mcp"],
579
+ "env": {
580
+ "OVERLEAF_SESSION": "<your-overleaf-session-cookie>"
581
+ }
582
+ }
583
+ }
584
+ }
585
+ ```
586
+
587
+ ### Windsurf
588
+
589
+ Add to `~/.codeium/windsurf/mcp_config.json`:
590
+
591
+ ```json
592
+ {
593
+ "mcpServers": {
594
+ "overleaf": {
595
+ "command": "npx",
596
+ "args": ["-y", "@aloth/olcli-mcp"],
597
+ "env": {
598
+ "OVERLEAF_SESSION": "<your-overleaf-session-cookie>"
599
+ }
600
+ }
601
+ }
602
+ }
603
+ ```
604
+
605
+ ### Getting your session cookie
606
+
607
+ 1. Open Overleaf in your browser and log in
608
+ 2. Open DevTools → Application (Chrome) or Storage (Firefox) → Cookies
609
+ 3. Find `overleaf_session2` (or `sharelatex.sid` for self-hosted)
610
+ 4. Copy the value — that's your `OVERLEAF_SESSION`
611
+
612
+ Or run `olcli auth` and then the MCP server will pick it up automatically.
613
+
614
+ ### Self-hosted Overleaf
615
+
616
+ Set `OVERLEAF_BASE_URL` in your MCP env:
617
+
618
+ ```json
619
+ "env": {
620
+ "OVERLEAF_SESSION": "<cookie>",
621
+ "OVERLEAF_BASE_URL": "https://overleaf.yourcompany.com"
622
+ }
623
+ ```
624
+
625
+ ---
626
+
441
627
  ## Troubleshooting
442
628
 
443
629
  ### Session expired
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @aloth/olcli — Programmatic API
3
+ *
4
+ * Re-exports the public surface of OverleafClient and all associated
5
+ * interfaces/types so consumers can import directly from the package root.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { OverleafClient } from '@aloth/olcli';
10
+ *
11
+ * const client = await OverleafClient.fromSessionCookie(cookie);
12
+ * const projects = await client.listProjects();
13
+ * ```
14
+ */
15
+ export { OverleafClient, type Project, type ProjectInfo, type FolderEntry, type DocEntry, type FileEntry, type CommentMessage, type ProjectComment, type CommentContext, type ListCommentsOptions, type AddCommentOptions, type Credentials, type CommentStatus, } from './client.js';
16
+ export { getBaseUrl, setBaseUrl, getSessionCookieName, setSessionCookieName, getSessionCookie, setSessionCookie, getCsrf, setCsrf, getLastProject, setLastProject, clearConfig, getConfigPath, saveOlAuth, } from './config.js';
17
+ export { DEFAULT_IGNORE_PATTERNS, loadIgnore, shouldIgnore, buildTexSiblingSet, type IgnoreContext, type LoadIgnoreOptions, } from './ignore.js';
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EACL,cAAc,EAEd,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAEhB,KAAK,aAAa,GACnB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,UAAU,EACV,UAAU,EACV,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,OAAO,EACP,OAAO,EACP,cAAc,EACd,cAAc,EACd,WAAW,EACX,aAAa,EACb,UAAU,GACX,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,uBAAuB,EACvB,UAAU,EACV,YAAY,EACZ,kBAAkB,EAClB,KAAK,aAAa,EAClB,KAAK,iBAAiB,GACvB,MAAM,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @aloth/olcli — Programmatic API
3
+ *
4
+ * Re-exports the public surface of OverleafClient and all associated
5
+ * interfaces/types so consumers can import directly from the package root.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { OverleafClient } from '@aloth/olcli';
10
+ *
11
+ * const client = await OverleafClient.fromSessionCookie(cookie);
12
+ * const projects = await client.listProjects();
13
+ * ```
14
+ */
15
+ // Core client class + all public interfaces/types
16
+ export { OverleafClient, } from './client.js';
17
+ // Configuration utilities
18
+ export { getBaseUrl, setBaseUrl, getSessionCookieName, setSessionCookieName, getSessionCookie, setSessionCookie, getCsrf, setCsrf, getLastProject, setLastProject, clearConfig, getConfigPath, saveOlAuth, } from './config.js';
19
+ // Ignore subsystem
20
+ export { DEFAULT_IGNORE_PATTERNS, loadIgnore, shouldIgnore, buildTexSiblingSet, } from './ignore.js';
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,kDAAkD;AAClD,OAAO,EACL,cAAc,GAef,MAAM,aAAa,CAAC;AAErB,0BAA0B;AAC1B,OAAO,EACL,UAAU,EACV,UAAU,EACV,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,OAAO,EACP,OAAO,EACP,cAAc,EACd,cAAc,EACd,WAAW,EACX,aAAa,EACb,UAAU,GACX,MAAM,aAAa,CAAC;AAErB,mBAAmB;AACnB,OAAO,EACL,uBAAuB,EACvB,UAAU,EACV,YAAY,EACZ,kBAAkB,GAGnB,MAAM,aAAa,CAAC"}
package/dist/mcp.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * olcli MCP Server
4
+ *
5
+ * Exposes OverleafClient methods as MCP tools so AI assistants
6
+ * (Claude Desktop, Cursor, Windsurf, …) can manage Overleaf projects.
7
+ *
8
+ * Transport: stdio (standard for Claude Desktop / Cursor / Windsurf)
9
+ *
10
+ * Auth: reads session cookie from OVERLEAF_SESSION env var or .olauth file in cwd.
11
+ *
12
+ * Start:
13
+ * npx @aloth/olcli-mcp
14
+ * node dist/mcp.js
15
+ * npm run mcp # (from repo root)
16
+ */
17
+ export {};
18
+ //# sourceMappingURL=mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;GAcG"}
package/dist/mcp.js ADDED
@@ -0,0 +1,318 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * olcli MCP Server
4
+ *
5
+ * Exposes OverleafClient methods as MCP tools so AI assistants
6
+ * (Claude Desktop, Cursor, Windsurf, …) can manage Overleaf projects.
7
+ *
8
+ * Transport: stdio (standard for Claude Desktop / Cursor / Windsurf)
9
+ *
10
+ * Auth: reads session cookie from OVERLEAF_SESSION env var or .olauth file in cwd.
11
+ *
12
+ * Start:
13
+ * npx @aloth/olcli-mcp
14
+ * node dist/mcp.js
15
+ * npm run mcp # (from repo root)
16
+ */
17
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
18
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
19
+ import { z } from 'zod/v3';
20
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
21
+ import { readFile } from 'node:fs/promises';
22
+ import { join, resolve } from 'node:path';
23
+ import AdmZip from 'adm-zip';
24
+ import { OverleafClient } from './client.js';
25
+ import { getSessionCookie, getBaseUrl, } from './config.js';
26
+ // ---------------------------------------------------------------------------
27
+ // Auth helpers
28
+ // ---------------------------------------------------------------------------
29
+ /**
30
+ * Resolve session cookie: env var → .olauth file in cwd → stored config.
31
+ */
32
+ function resolveSessionCookie() {
33
+ // 1. Explicit environment variable
34
+ if (process.env.OVERLEAF_SESSION) {
35
+ return process.env.OVERLEAF_SESSION.trim();
36
+ }
37
+ // 2. .olauth file in current working directory
38
+ const olauth = join(process.cwd(), '.olauth');
39
+ if (existsSync(olauth)) {
40
+ try {
41
+ const raw = readFileSync(olauth, 'utf-8').trim();
42
+ if (raw)
43
+ return raw;
44
+ }
45
+ catch {
46
+ // fall through
47
+ }
48
+ }
49
+ // 3. Stored via `olcli auth` (Conf-based config)
50
+ const stored = getSessionCookie();
51
+ if (stored)
52
+ return stored;
53
+ throw new Error('No Overleaf session cookie found.\n' +
54
+ 'Set OVERLEAF_SESSION=<cookie> or run `olcli auth` first.');
55
+ }
56
+ // ---------------------------------------------------------------------------
57
+ // Lazy client factory — initialised once, reused across requests
58
+ // ---------------------------------------------------------------------------
59
+ let _client = null;
60
+ async function getClient() {
61
+ if (_client)
62
+ return _client;
63
+ const cookie = resolveSessionCookie();
64
+ const baseUrl = process.env.OVERLEAF_BASE_URL ?? getBaseUrl();
65
+ _client = await OverleafClient.fromSessionCookie(cookie, baseUrl);
66
+ return _client;
67
+ }
68
+ // ---------------------------------------------------------------------------
69
+ // MCP server setup
70
+ // ---------------------------------------------------------------------------
71
+ const server = new McpServer({
72
+ name: 'olcli',
73
+ version: '0.5.0',
74
+ }, {
75
+ capabilities: { tools: {} },
76
+ });
77
+ // ---------------------------------------------------------------------------
78
+ // Helper: wrap async tool handlers with consistent error formatting
79
+ // ---------------------------------------------------------------------------
80
+ function wrapTool(fn) {
81
+ return fn().then((result) => ({
82
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
83
+ }), (err) => ({
84
+ content: [{ type: 'text', text: `Error: ${err instanceof Error ? err.message : String(err)}` }],
85
+ isError: true,
86
+ }));
87
+ }
88
+ // ---------------------------------------------------------------------------
89
+ // Tool: list_projects
90
+ // ---------------------------------------------------------------------------
91
+ server.tool('list_projects', 'List all Overleaf projects in the account. Returns project IDs, names, and metadata.', async () => wrapTool(async () => {
92
+ const client = await getClient();
93
+ return client.listProjects();
94
+ }));
95
+ // ---------------------------------------------------------------------------
96
+ // Tool: get_project_info
97
+ // ---------------------------------------------------------------------------
98
+ server.tool('get_project_info', 'Get detailed information about an Overleaf project including its file tree (folders, docs, and files).', {
99
+ project_id: z.string().describe('The Overleaf project ID (24-char hex string)'),
100
+ }, async ({ project_id }) => wrapTool(async () => {
101
+ const client = await getClient();
102
+ return client.getProjectInfo(project_id);
103
+ }));
104
+ // ---------------------------------------------------------------------------
105
+ // Tool: pull_project
106
+ // ---------------------------------------------------------------------------
107
+ server.tool('pull_project', 'Download and extract an Overleaf project as a zip to a local directory. Creates the directory if it does not exist.', {
108
+ project_id: z.string().describe('The Overleaf project ID'),
109
+ output_dir: z.string().describe('Local directory path to extract files into'),
110
+ overwrite: z
111
+ .boolean()
112
+ .optional()
113
+ .default(false)
114
+ .describe('Overwrite existing files (default: false)'),
115
+ }, async ({ project_id, output_dir, overwrite }) => wrapTool(async () => {
116
+ const client = await getClient();
117
+ const zipBuf = await client.downloadProject(project_id);
118
+ const outDir = resolve(output_dir);
119
+ mkdirSync(outDir, { recursive: true });
120
+ const zip = new AdmZip(zipBuf);
121
+ const entries = zip.getEntries();
122
+ const extracted = [];
123
+ const skipped = [];
124
+ for (const entry of entries) {
125
+ if (entry.isDirectory)
126
+ continue;
127
+ const destPath = join(outDir, entry.entryName);
128
+ if (!overwrite && existsSync(destPath)) {
129
+ skipped.push(entry.entryName);
130
+ continue;
131
+ }
132
+ // Ensure parent dir exists
133
+ mkdirSync(join(outDir, entry.entryName.split('/').slice(0, -1).join('/')), { recursive: true });
134
+ writeFileSync(destPath, entry.getData());
135
+ extracted.push(entry.entryName);
136
+ }
137
+ return {
138
+ output_dir: outDir,
139
+ extracted_count: extracted.length,
140
+ skipped_count: skipped.length,
141
+ extracted,
142
+ skipped,
143
+ };
144
+ }));
145
+ // ---------------------------------------------------------------------------
146
+ // Tool: push_file
147
+ // ---------------------------------------------------------------------------
148
+ server.tool('push_file', 'Upload a local file to an Overleaf project. The remote path is inferred from the file_path argument.', {
149
+ project_id: z.string().describe('The Overleaf project ID'),
150
+ local_path: z.string().describe('Absolute or relative path of the local file to upload'),
151
+ remote_path: z
152
+ .string()
153
+ .optional()
154
+ .describe('Target path within the project (default: basename of local_path)'),
155
+ }, async ({ project_id, local_path, remote_path }) => wrapTool(async () => {
156
+ const client = await getClient();
157
+ const absPath = resolve(local_path);
158
+ const content = await readFile(absPath);
159
+ const remoteName = remote_path ?? local_path.split('/').pop() ?? local_path;
160
+ return client.uploadFile(project_id, null, remoteName, content);
161
+ }));
162
+ // ---------------------------------------------------------------------------
163
+ // Tool: compile
164
+ // ---------------------------------------------------------------------------
165
+ server.tool('compile', 'Compile an Overleaf project using the remote LaTeX compiler. Returns the PDF URL and any log messages.', {
166
+ project_id: z.string().describe('The Overleaf project ID'),
167
+ }, async ({ project_id }) => wrapTool(async () => {
168
+ const client = await getClient();
169
+ return client.compileProject(project_id);
170
+ }));
171
+ // ---------------------------------------------------------------------------
172
+ // Tool: download_pdf
173
+ // ---------------------------------------------------------------------------
174
+ server.tool('download_pdf', 'Compile an Overleaf project and download the resulting PDF to a local file.', {
175
+ project_id: z.string().describe('The Overleaf project ID'),
176
+ output_path: z.string().describe('Local file path where the PDF should be saved (e.g. output.pdf)'),
177
+ }, async ({ project_id, output_path }) => wrapTool(async () => {
178
+ const client = await getClient();
179
+ const pdfBuf = await client.downloadPdf(project_id);
180
+ const absPath = resolve(output_path);
181
+ writeFileSync(absPath, pdfBuf);
182
+ return {
183
+ path: absPath,
184
+ bytes: pdfBuf.length,
185
+ };
186
+ }));
187
+ // ---------------------------------------------------------------------------
188
+ // Tool: list_comments
189
+ // ---------------------------------------------------------------------------
190
+ server.tool('list_comments', 'List review comments on an Overleaf project. Supports filtering by status (all, open, resolved).', {
191
+ project_id: z.string().describe('The Overleaf project ID'),
192
+ status: z
193
+ .enum(['all', 'open', 'resolved'])
194
+ .optional()
195
+ .default('all')
196
+ .describe('Filter by comment status'),
197
+ include_context: z
198
+ .boolean()
199
+ .optional()
200
+ .default(false)
201
+ .describe('Include surrounding text context for each comment'),
202
+ }, async ({ project_id, status, include_context }) => wrapTool(async () => {
203
+ const client = await getClient();
204
+ return client.listComments(project_id, {
205
+ status,
206
+ contextLines: include_context ? 3 : 0,
207
+ });
208
+ }));
209
+ // ---------------------------------------------------------------------------
210
+ // Tool: get_entities
211
+ // ---------------------------------------------------------------------------
212
+ server.tool('get_entities', 'Get a flat list of all files and documents in an Overleaf project with their paths and types.', {
213
+ project_id: z.string().describe('The Overleaf project ID'),
214
+ }, async ({ project_id }) => wrapTool(async () => {
215
+ const client = await getClient();
216
+ return client.getEntities(project_id);
217
+ }));
218
+ // ---------------------------------------------------------------------------
219
+ // Tool: download_file
220
+ // ---------------------------------------------------------------------------
221
+ server.tool('download_file', 'Download a single file from an Overleaf project by its path within the project.', {
222
+ project_id: z.string().describe('The Overleaf project ID'),
223
+ remote_path: z.string().describe('Path of the file within the project (e.g. main.tex or figures/fig1.pdf)'),
224
+ output_path: z
225
+ .string()
226
+ .optional()
227
+ .describe('Local path to save the file (default: basename of remote_path in cwd)'),
228
+ }, async ({ project_id, remote_path, output_path }) => wrapTool(async () => {
229
+ const client = await getClient();
230
+ const fileBuf = await client.downloadByPath(project_id, remote_path);
231
+ const destPath = resolve(output_path ?? remote_path.split('/').pop() ?? remote_path);
232
+ writeFileSync(destPath, fileBuf);
233
+ return {
234
+ path: destPath,
235
+ bytes: fileBuf.length,
236
+ remote_path,
237
+ };
238
+ }));
239
+ // ---------------------------------------------------------------------------
240
+ // Tool: add_comment
241
+ // ---------------------------------------------------------------------------
242
+ server.tool('add_comment', 'Add a review comment to a specific location in an Overleaf project document.', {
243
+ project_id: z.string().describe('The Overleaf project ID'),
244
+ doc_path: z.string().describe('Path of the document within the project (e.g. main.tex)'),
245
+ content: z.string().describe('The comment text'),
246
+ position: z.number().int().nonnegative().optional().describe('Character offset in the document where the comment is anchored'),
247
+ length: z.number().int().nonnegative().optional().describe('Length of the highlighted text span (0 for a point comment)'),
248
+ selected_text: z.string().optional().describe('The text being commented on (optional, used for context)'),
249
+ line: z.number().int().positive().optional().describe('Line number in the document (1-based, alternative to position)'),
250
+ column: z.number().int().nonnegative().optional().describe('Column number in the document (0-based, alternative to position)'),
251
+ }, async ({ project_id, doc_path, content, position, length, selected_text, line, column }) => wrapTool(async () => {
252
+ const client = await getClient();
253
+ return client.addComment(project_id, {
254
+ filePath: doc_path,
255
+ content,
256
+ position,
257
+ length,
258
+ selectedText: selected_text,
259
+ line,
260
+ column,
261
+ });
262
+ }));
263
+ // ---------------------------------------------------------------------------
264
+ // Tool: resolve_comment
265
+ // ---------------------------------------------------------------------------
266
+ server.tool('resolve_comment', 'Mark a review comment thread as resolved.', {
267
+ project_id: z.string().describe('The Overleaf project ID'),
268
+ thread_id: z.string().describe('The comment thread ID (from list_comments)'),
269
+ }, async ({ project_id, thread_id }) => wrapTool(async () => {
270
+ const client = await getClient();
271
+ return client.resolveComment(project_id, thread_id);
272
+ }));
273
+ // ---------------------------------------------------------------------------
274
+ // Tool: delete_entity
275
+ // ---------------------------------------------------------------------------
276
+ server.tool('delete_entity', 'Delete a file or document from an Overleaf project by its remote path.', {
277
+ project_id: z.string().describe('The Overleaf project ID'),
278
+ remote_path: z.string().describe('Path of the file/document to delete within the project'),
279
+ }, async ({ project_id, remote_path }) => wrapTool(async () => {
280
+ const client = await getClient();
281
+ await client.deleteByPath(project_id, remote_path);
282
+ return { deleted: remote_path };
283
+ }));
284
+ // ---------------------------------------------------------------------------
285
+ // Tool: rename_entity
286
+ // ---------------------------------------------------------------------------
287
+ server.tool('rename_entity', 'Rename a file or document within an Overleaf project.', {
288
+ project_id: z.string().describe('The Overleaf project ID'),
289
+ remote_path: z.string().describe('Current path of the file/document within the project'),
290
+ new_name: z.string().describe('New filename (basename only, not a full path)'),
291
+ }, async ({ project_id, remote_path, new_name }) => wrapTool(async () => {
292
+ const client = await getClient();
293
+ await client.renameByPath(project_id, remote_path, new_name);
294
+ return { old_path: remote_path, new_name };
295
+ }));
296
+ // ---------------------------------------------------------------------------
297
+ // Tool: compile_with_outputs
298
+ // ---------------------------------------------------------------------------
299
+ server.tool('compile_with_outputs', 'Compile an Overleaf project and return all output file metadata (PDF, BBL, logs, etc.). Useful for arXiv submission workflows.', {
300
+ project_id: z.string().describe('The Overleaf project ID'),
301
+ }, async ({ project_id }) => wrapTool(async () => {
302
+ const client = await getClient();
303
+ return client.compileWithOutputs(project_id);
304
+ }));
305
+ // ---------------------------------------------------------------------------
306
+ // Start
307
+ // ---------------------------------------------------------------------------
308
+ async function main() {
309
+ const transport = new StdioServerTransport();
310
+ await server.connect(transport);
311
+ // Log to stderr so it doesn't pollute the MCP stdio channel
312
+ process.stderr.write('olcli MCP server started (stdio)\n');
313
+ }
314
+ main().catch((err) => {
315
+ process.stderr.write(`Fatal: ${err instanceof Error ? err.message : String(err)}\n`);
316
+ process.exit(1);
317
+ });
318
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,13 +1,24 @@
1
1
  {
2
2
  "name": "@aloth/olcli",
3
- "version": "0.4.1",
3
+ "version": "0.5.0",
4
4
  "description": "Command-line interface for Overleaf — Sync, manage, and compile LaTeX projects from your terminal",
5
5
  "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ },
13
+ "./cli": "./dist/cli.js"
14
+ },
6
15
  "bin": {
7
- "olcli": "dist/cli.js"
16
+ "olcli": "dist/cli.js",
17
+ "olcli-mcp": "dist/mcp.js"
8
18
  },
9
19
  "scripts": {
10
20
  "build": "tsc",
21
+ "mcp": "node dist/mcp.js",
11
22
  "dev": "tsx src/cli.ts",
12
23
  "lint": "eslint src/",
13
24
  "prepare": "npm run build"
@@ -44,6 +55,7 @@
44
55
  },
45
56
  "homepage": "https://github.com/aloth/olcli#readme",
46
57
  "dependencies": {
58
+ "@modelcontextprotocol/sdk": "^1.29.0",
47
59
  "adm-zip": "^0.5.16",
48
60
  "chalk": "^5.3.0",
49
61
  "cheerio": "^1.0.0",
@@ -51,7 +63,8 @@
51
63
  "conf": "^13.0.0",
52
64
  "ignore": "^7.0.5",
53
65
  "ora": "^8.0.1",
54
- "tough-cookie": "^4.1.4"
66
+ "tough-cookie": "^4.1.4",
67
+ "zod": "^4.4.3"
55
68
  },
56
69
  "devDependencies": {
57
70
  "@types/adm-zip": "^0.5.7",