@netique/overleaf-mcp 0.1.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/LICENSE +693 -0
- package/README.md +152 -0
- package/dist/api/commentTypes.js +5 -0
- package/dist/api/commentTypes.js.map +1 -0
- package/dist/api/compileTypes.js +2 -0
- package/dist/api/compileTypes.js.map +1 -0
- package/dist/api/errors.js +17 -0
- package/dist/api/errors.js.map +1 -0
- package/dist/api/http.js +52 -0
- package/dist/api/http.js.map +1 -0
- package/dist/api/projectTypes.js +38 -0
- package/dist/api/projectTypes.js.map +1 -0
- package/dist/api/socket.js +348 -0
- package/dist/api/socket.js.map +1 -0
- package/dist/api/types.js +18 -0
- package/dist/api/types.js.map +1 -0
- package/dist/config.js +13 -0
- package/dist/config.js.map +1 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +1 -0
- package/dist/ot/diff.js +32 -0
- package/dist/ot/diff.js.map +1 -0
- package/dist/ot/trackedChanges.js +19 -0
- package/dist/ot/trackedChanges.js.map +1 -0
- package/dist/session/activeProject.js +45 -0
- package/dist/session/activeProject.js.map +1 -0
- package/dist/session/docCache.js +21 -0
- package/dist/session/docCache.js.map +1 -0
- package/dist/session/identity.js +59 -0
- package/dist/session/identity.js.map +1 -0
- package/dist/tools/comments.js +195 -0
- package/dist/tools/comments.js.map +1 -0
- package/dist/tools/compile.js +188 -0
- package/dist/tools/compile.js.map +1 -0
- package/dist/tools/editFile.js +123 -0
- package/dist/tools/editFile.js.map +1 -0
- package/dist/tools/listFiles.js +42 -0
- package/dist/tools/listFiles.js.map +1 -0
- package/dist/tools/listProjects.js +88 -0
- package/dist/tools/listProjects.js.map +1 -0
- package/dist/tools/openProject.js +58 -0
- package/dist/tools/openProject.js.map +1 -0
- package/dist/tools/readFile.js +133 -0
- package/dist/tools/readFile.js.map +1 -0
- package/dist/tools/trackedChanges.js +260 -0
- package/dist/tools/trackedChanges.js.map +1 -0
- package/dist/util/logger.js +18 -0
- package/dist/util/logger.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { joinDoc } from "../api/socket.js";
|
|
3
|
+
import { olGet, expectOk } from "../api/http.js";
|
|
4
|
+
import { findByPath, getActiveProject } from "../session/activeProject.js";
|
|
5
|
+
import { updateDoc } from "../session/docCache.js";
|
|
6
|
+
import { logger } from "../util/logger.js";
|
|
7
|
+
const Schema = z.object({
|
|
8
|
+
path: z
|
|
9
|
+
.string()
|
|
10
|
+
.min(1)
|
|
11
|
+
.optional()
|
|
12
|
+
.describe("Project-relative path of the file, e.g. 'main.tex' or 'chapters/intro.tex'. If omitted, defaults to the project's root doc (visible as `root_doc_path` in `open_project`'s response)."),
|
|
13
|
+
});
|
|
14
|
+
const BINARY_EXTS = new Set([
|
|
15
|
+
"png", "jpg", "jpeg", "gif", "bmp", "tif", "tiff", "webp", "svg",
|
|
16
|
+
"pdf", "eps", "ps", "ai",
|
|
17
|
+
"zip", "tar", "gz", "bz2", "7z",
|
|
18
|
+
"ttf", "otf", "woff", "woff2",
|
|
19
|
+
]);
|
|
20
|
+
function mimeForName(name) {
|
|
21
|
+
const ext = name.split(".").pop()?.toLowerCase() ?? "";
|
|
22
|
+
switch (ext) {
|
|
23
|
+
case "png": return "image/png";
|
|
24
|
+
case "jpg":
|
|
25
|
+
case "jpeg": return "image/jpeg";
|
|
26
|
+
case "gif": return "image/gif";
|
|
27
|
+
case "bmp": return "image/bmp";
|
|
28
|
+
case "webp": return "image/webp";
|
|
29
|
+
case "tif":
|
|
30
|
+
case "tiff": return "image/tiff";
|
|
31
|
+
case "svg": return "image/svg+xml";
|
|
32
|
+
case "pdf": return "application/pdf";
|
|
33
|
+
case "zip": return "application/zip";
|
|
34
|
+
case "ttf": return "font/ttf";
|
|
35
|
+
case "otf": return "font/otf";
|
|
36
|
+
case "woff": return "font/woff";
|
|
37
|
+
case "woff2": return "font/woff2";
|
|
38
|
+
default: return "application/octet-stream";
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export function registerReadFile(server) {
|
|
42
|
+
server.registerTool("read_file", {
|
|
43
|
+
title: "Read a file from the open Overleaf project",
|
|
44
|
+
description: "Reads the contents of a file by project-relative path. " +
|
|
45
|
+
"For text docs (.tex, .bib, .md, etc.) returns the full text and the current OT version. " +
|
|
46
|
+
"For binary files (images, PDFs) returns base64 + MIME type via HTTP download.",
|
|
47
|
+
inputSchema: Schema.shape,
|
|
48
|
+
annotations: { readOnlyHint: true },
|
|
49
|
+
}, async (args) => {
|
|
50
|
+
const ap = getActiveProject();
|
|
51
|
+
if (!ap) {
|
|
52
|
+
return { content: [{ type: "text", text: "No project is open. Call open_project first." }], isError: true };
|
|
53
|
+
}
|
|
54
|
+
const resolvedPath = args.path ?? ap.rootDocPath;
|
|
55
|
+
if (!resolvedPath) {
|
|
56
|
+
return { content: [{ type: "text", text: "No path provided and the project has no configured root doc. Pass a `path` from `list_files`." }], isError: true };
|
|
57
|
+
}
|
|
58
|
+
const entity = findByPath(resolvedPath);
|
|
59
|
+
if (!entity) {
|
|
60
|
+
return {
|
|
61
|
+
content: [{ type: "text", text: `Path not found in project: '${resolvedPath}'. Use list_files to inspect available paths.` }],
|
|
62
|
+
isError: true,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
if (entity.kind === "folder") {
|
|
66
|
+
return { content: [{ type: "text", text: `'${resolvedPath}' is a folder, not a file.` }], isError: true };
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
if (entity.kind === "doc") {
|
|
70
|
+
const doc = await joinDoc(entity.id);
|
|
71
|
+
const text = doc.docLines.join("\n");
|
|
72
|
+
// Pin the doc cache to exactly what the agent just saw, so a later
|
|
73
|
+
// edit_file uses the same baseline. If the server has moved on
|
|
74
|
+
// (concurrent edit) between read and edit, the resulting op will be
|
|
75
|
+
// sent with a stale `v` and the server will reject or transform —
|
|
76
|
+
// either is correct behavior, but we no longer silently overwrite.
|
|
77
|
+
updateDoc(entity.id, text, doc.version);
|
|
78
|
+
const ranges = doc.ranges;
|
|
79
|
+
const changeCount = Array.isArray(ranges?.changes) ? ranges.changes.length : 0;
|
|
80
|
+
const commentCount = Array.isArray(ranges?.comments) ? ranges.comments.length : 0;
|
|
81
|
+
return {
|
|
82
|
+
content: [{ type: "text", text }],
|
|
83
|
+
structuredContent: {
|
|
84
|
+
path: entity.path,
|
|
85
|
+
doc_id: entity.id,
|
|
86
|
+
kind: "doc",
|
|
87
|
+
version: doc.version,
|
|
88
|
+
line_count: doc.docLines.length,
|
|
89
|
+
byte_count: Buffer.byteLength(text, "utf8"),
|
|
90
|
+
has_ranges: doc.ranges !== undefined && doc.ranges !== null,
|
|
91
|
+
tracked_change_count: changeCount,
|
|
92
|
+
comment_count: commentCount,
|
|
93
|
+
// Surface up to the 5 most recent tracked-change entries so the
|
|
94
|
+
// agent (and our tests) can see what's in the review panel.
|
|
95
|
+
recent_changes: Array.isArray(ranges?.changes) ? ranges.changes.slice(-5) : [],
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
// Binary fileRef: HTTP download.
|
|
100
|
+
const res = await olGet(`project/${ap.projectId}/file/${entity.id}`);
|
|
101
|
+
await expectOk(res, `GET project/${ap.projectId}/file/${entity.id}`);
|
|
102
|
+
const buf = Buffer.from(await res.arrayBuffer());
|
|
103
|
+
const ext = entity.name.split(".").pop()?.toLowerCase() ?? "";
|
|
104
|
+
const looksText = !BINARY_EXTS.has(ext) && buf.length > 0 && buf.subarray(0, Math.min(2048, buf.length)).every((b) => b === 9 || b === 10 || b === 13 || (b >= 32 && b < 127) || b >= 128);
|
|
105
|
+
if (looksText) {
|
|
106
|
+
return {
|
|
107
|
+
content: [{ type: "text", text: buf.toString("utf8") }],
|
|
108
|
+
structuredContent: { path: entity.path, file_id: entity.id, kind: "file", byte_count: buf.length, encoding: "utf8" },
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
content: [
|
|
113
|
+
{ type: "text", text: `(binary file, ${buf.length} bytes, base64 below)` },
|
|
114
|
+
{ type: "text", text: buf.toString("base64") },
|
|
115
|
+
],
|
|
116
|
+
structuredContent: {
|
|
117
|
+
path: entity.path,
|
|
118
|
+
file_id: entity.id,
|
|
119
|
+
kind: "file",
|
|
120
|
+
byte_count: buf.length,
|
|
121
|
+
mime_type: mimeForName(entity.name),
|
|
122
|
+
encoding: "base64",
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
128
|
+
logger.error("read_file failed", msg);
|
|
129
|
+
return { content: [{ type: "text", text: `Failed to read '${args.path}': ${msg}` }], isError: true };
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=readFile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readFile.js","sourceRoot":"","sources":["../../src/tools/readFile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { asJson, olGet, olPostJson, expectOk } from "../api/http.js";
|
|
3
|
+
import { getActiveProject } from "../session/activeProject.js";
|
|
4
|
+
import { applyOtUpdate, getActiveSocket } from "../api/socket.js";
|
|
5
|
+
import { getIdentity } from "../session/identity.js";
|
|
6
|
+
import { generateIdSeed } from "../ot/trackedChanges.js";
|
|
7
|
+
import { logger } from "../util/logger.js";
|
|
8
|
+
function memberMap(ap) {
|
|
9
|
+
const m = new Map();
|
|
10
|
+
const add = (u) => {
|
|
11
|
+
if (!u?._id)
|
|
12
|
+
return;
|
|
13
|
+
const name = [u.first_name, u.last_name].filter(Boolean).join(" ") || undefined;
|
|
14
|
+
m.set(u._id, { name, email: u.email });
|
|
15
|
+
};
|
|
16
|
+
add(ap.project.owner);
|
|
17
|
+
for (const u of ap.project.members ?? [])
|
|
18
|
+
add(u);
|
|
19
|
+
return m;
|
|
20
|
+
}
|
|
21
|
+
function docPathById(ap) {
|
|
22
|
+
const m = new Map();
|
|
23
|
+
for (const e of ap.entities)
|
|
24
|
+
if (e.kind === "doc")
|
|
25
|
+
m.set(e.id, e.path);
|
|
26
|
+
return m;
|
|
27
|
+
}
|
|
28
|
+
async function fetchAllRanges(projectId) {
|
|
29
|
+
const res = await olGet(`project/${projectId}/ranges`);
|
|
30
|
+
return await asJson(res, "GET /ranges");
|
|
31
|
+
}
|
|
32
|
+
function flattenChanges(ranges, pathMap, members) {
|
|
33
|
+
const out = [];
|
|
34
|
+
for (const docRange of ranges) {
|
|
35
|
+
for (const c of docRange.ranges?.changes ?? []) {
|
|
36
|
+
const op = c.op;
|
|
37
|
+
const isInsert = typeof op.i === "string";
|
|
38
|
+
const text = (op.i ?? op.d ?? "");
|
|
39
|
+
const userId = c.metadata?.user_id;
|
|
40
|
+
const author = userId ? members.get(userId) : undefined;
|
|
41
|
+
out.push({
|
|
42
|
+
change_id: c.id,
|
|
43
|
+
doc_id: docRange.id,
|
|
44
|
+
doc_path: pathMap.get(docRange.id),
|
|
45
|
+
kind: isInsert ? "insert" : "delete",
|
|
46
|
+
position: op.p,
|
|
47
|
+
text,
|
|
48
|
+
user_id: userId,
|
|
49
|
+
author_name: author?.name,
|
|
50
|
+
author_email: author?.email,
|
|
51
|
+
timestamp: c.metadata?.ts,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return out;
|
|
56
|
+
}
|
|
57
|
+
// ---------- list_tracked_changes ----------
|
|
58
|
+
const ListSchema = z.object({
|
|
59
|
+
author_email: z.string().optional().describe("Filter to changes by this exact author email."),
|
|
60
|
+
author_id_endswith: z.string().optional().describe("Filter to changes by user_id matching this suffix (handy when you don't know the email)."),
|
|
61
|
+
path_contains: z.string().optional().describe("Filter to changes in docs whose project-relative path matches this substring."),
|
|
62
|
+
kind: z.enum(["any", "insert", "delete"]).default("any").describe("Filter by op kind."),
|
|
63
|
+
text_contains: z.string().optional().describe("Case-insensitive substring filter on the inserted/deleted text."),
|
|
64
|
+
limit: z.number().int().min(1).max(2000).default(200).describe("Max changes to return (newest first)."),
|
|
65
|
+
full_text: z.boolean().default(false).describe("Include the full op text. Default truncates each to 200 chars to keep responses compact."),
|
|
66
|
+
});
|
|
67
|
+
// ---------- accept_changes ----------
|
|
68
|
+
const AcceptSchema = z.object({
|
|
69
|
+
change_ids: z.array(z.string().min(8)).min(1).describe("Tracked-change ids to accept (from list_tracked_changes)."),
|
|
70
|
+
});
|
|
71
|
+
async function postAccept(projectId, docId, changeIds) {
|
|
72
|
+
const res = await olPostJson(`project/${projectId}/doc/${docId}/changes/accept`, { change_ids: changeIds });
|
|
73
|
+
await expectOk(res, `POST project/${projectId}/doc/${docId}/changes/accept`);
|
|
74
|
+
}
|
|
75
|
+
// ---------- reject_changes ----------
|
|
76
|
+
const RejectSchema = AcceptSchema;
|
|
77
|
+
async function rejectViaOt(docId, changes) {
|
|
78
|
+
// Build inverse ops. Reverse-sort by position so applying earlier ops doesn't
|
|
79
|
+
// shift the positions of later ones (matches Overleaf's frontend reject-changes.ts comment).
|
|
80
|
+
const ordered = [...changes].sort((a, b) => b.position - a.position);
|
|
81
|
+
const ops = ordered.map((c) => c.kind === "insert"
|
|
82
|
+
? { p: c.position, d: c.text, u: true } // undo a tracked insert -> delete the text
|
|
83
|
+
: { p: c.position, i: c.text, u: true } // undo a tracked delete -> re-mark as present
|
|
84
|
+
);
|
|
85
|
+
const identity = await getIdentity();
|
|
86
|
+
const sock = getActiveSocket();
|
|
87
|
+
// Version must be the current server version. We don't track it for arbitrary
|
|
88
|
+
// docs the way docCache does for ones we've joined for editing — but the
|
|
89
|
+
// server will still accept and transform if our v is slightly stale. Use 0
|
|
90
|
+
// is a no-go; better to joinDoc first to fetch the version.
|
|
91
|
+
// Easiest: just fetch via socket joinDoc to get latest version.
|
|
92
|
+
const { joinDoc } = await import("../api/socket.js");
|
|
93
|
+
const fresh = await joinDoc(docId);
|
|
94
|
+
const update = {
|
|
95
|
+
doc: docId,
|
|
96
|
+
op: ops,
|
|
97
|
+
v: fresh.version,
|
|
98
|
+
meta: {
|
|
99
|
+
source: sock?.publicId ?? "overleaf-mcp",
|
|
100
|
+
ts: Date.now(),
|
|
101
|
+
user_id: identity.userId,
|
|
102
|
+
tc: generateIdSeed(),
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
await applyOtUpdate(docId, update);
|
|
106
|
+
}
|
|
107
|
+
// ---------- registration ----------
|
|
108
|
+
export function registerTrackedChanges(server) {
|
|
109
|
+
server.registerTool("list_tracked_changes", {
|
|
110
|
+
title: "List pending tracked changes across the open project",
|
|
111
|
+
description: "Enumerates every pending tracked-change suggestion in the open project (across all docs), with author name + email, doc path, op kind ('insert' | 'delete'), position, inserted/deleted text, and a stable change_id. " +
|
|
112
|
+
"Use this to plan an `accept_changes` or `reject_changes` call: filter the result by author / doc / kind / text, collect the matching change_id values, then pass them. " +
|
|
113
|
+
"Tracked changes only — review-panel comments are listed by `list_comments`.",
|
|
114
|
+
inputSchema: ListSchema.shape,
|
|
115
|
+
annotations: { readOnlyHint: true },
|
|
116
|
+
}, async (args) => {
|
|
117
|
+
const ap = getActiveProject();
|
|
118
|
+
if (!ap)
|
|
119
|
+
return { content: [{ type: "text", text: "No project is open." }], isError: true };
|
|
120
|
+
try {
|
|
121
|
+
const ranges = await fetchAllRanges(ap.projectId);
|
|
122
|
+
const pathMap = docPathById(ap);
|
|
123
|
+
const members = memberMap(ap);
|
|
124
|
+
let all = flattenChanges(ranges, pathMap, members);
|
|
125
|
+
if (args.author_email) {
|
|
126
|
+
const wanted = args.author_email;
|
|
127
|
+
all = all.filter((c) => c.author_email === wanted);
|
|
128
|
+
}
|
|
129
|
+
if (args.author_id_endswith) {
|
|
130
|
+
const suffix = args.author_id_endswith;
|
|
131
|
+
all = all.filter((c) => (c.user_id ?? "").endsWith(suffix));
|
|
132
|
+
}
|
|
133
|
+
if (args.path_contains) {
|
|
134
|
+
const needle = args.path_contains.toLowerCase();
|
|
135
|
+
all = all.filter((c) => (c.doc_path ?? "").toLowerCase().includes(needle));
|
|
136
|
+
}
|
|
137
|
+
if (args.kind !== "any")
|
|
138
|
+
all = all.filter((c) => c.kind === args.kind);
|
|
139
|
+
if (args.text_contains) {
|
|
140
|
+
const needle = args.text_contains.toLowerCase();
|
|
141
|
+
all = all.filter((c) => c.text.toLowerCase().includes(needle));
|
|
142
|
+
}
|
|
143
|
+
all.sort((a, b) => (b.timestamp ? Date.parse(b.timestamp) : 0) - (a.timestamp ? Date.parse(a.timestamp) : 0));
|
|
144
|
+
const truncated = all.length > args.limit;
|
|
145
|
+
const shown = all.slice(0, args.limit).map((c) => ({
|
|
146
|
+
...c,
|
|
147
|
+
text: args.full_text ? c.text : c.text.slice(0, 200),
|
|
148
|
+
text_truncated: !args.full_text && c.text.length > 200,
|
|
149
|
+
}));
|
|
150
|
+
const payload = { count: shown.length, total_matched: all.length, truncated, changes: shown };
|
|
151
|
+
return {
|
|
152
|
+
content: [{ type: "text", text: JSON.stringify(payload, null, 2) }],
|
|
153
|
+
structuredContent: payload,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
catch (err) {
|
|
157
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
158
|
+
logger.error("list_tracked_changes failed", msg);
|
|
159
|
+
return { content: [{ type: "text", text: `Failed: ${msg}` }], isError: true };
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
server.registerTool("accept_changes", {
|
|
163
|
+
title: "Accept tracked changes by id",
|
|
164
|
+
description: "Permanently accepts the specified tracked-change suggestions. The text stays in the doc; the pending-change metadata is cleared. Pass the `change_id` values from `list_tracked_changes`. Changes that span multiple docs are grouped automatically. Irreversible.",
|
|
165
|
+
inputSchema: AcceptSchema.shape,
|
|
166
|
+
}, async (args) => {
|
|
167
|
+
const ap = getActiveProject();
|
|
168
|
+
if (!ap)
|
|
169
|
+
return { content: [{ type: "text", text: "No project is open." }], isError: true };
|
|
170
|
+
try {
|
|
171
|
+
// Resolve which doc each change belongs to (via ranges).
|
|
172
|
+
const ranges = await fetchAllRanges(ap.projectId);
|
|
173
|
+
const docByChange = new Map();
|
|
174
|
+
for (const docRange of ranges) {
|
|
175
|
+
for (const c of docRange.ranges?.changes ?? [])
|
|
176
|
+
docByChange.set(c.id, docRange.id);
|
|
177
|
+
}
|
|
178
|
+
const grouped = new Map();
|
|
179
|
+
const unknown = [];
|
|
180
|
+
for (const cid of args.change_ids) {
|
|
181
|
+
const did = docByChange.get(cid);
|
|
182
|
+
if (!did)
|
|
183
|
+
unknown.push(cid);
|
|
184
|
+
else {
|
|
185
|
+
const arr = grouped.get(did) ?? [];
|
|
186
|
+
arr.push(cid);
|
|
187
|
+
grouped.set(did, arr);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (unknown.length === args.change_ids.length) {
|
|
191
|
+
return { content: [{ type: "text", text: `None of the provided change_ids exist as pending changes. Maybe already accepted/rejected. unknown: ${unknown.join(", ")}` }], isError: true };
|
|
192
|
+
}
|
|
193
|
+
let accepted = 0;
|
|
194
|
+
const docResults = [];
|
|
195
|
+
const pathMap = docPathById(ap);
|
|
196
|
+
for (const [docId, ids] of grouped) {
|
|
197
|
+
await postAccept(ap.projectId, docId, ids);
|
|
198
|
+
accepted += ids.length;
|
|
199
|
+
docResults.push({ doc_id: docId, doc_path: pathMap.get(docId), count: ids.length });
|
|
200
|
+
}
|
|
201
|
+
const note = unknown.length ? ` (${unknown.length} unknown id(s) skipped)` : "";
|
|
202
|
+
return {
|
|
203
|
+
content: [{ type: "text", text: `Accepted ${accepted} change(s) across ${docResults.length} doc(s)${note}.` }],
|
|
204
|
+
structuredContent: { accepted, docs: docResults, unknown },
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
catch (err) {
|
|
208
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
209
|
+
logger.error("accept_changes failed", msg);
|
|
210
|
+
return { content: [{ type: "text", text: `Failed: ${msg}` }], isError: true };
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
server.registerTool("reject_changes", {
|
|
214
|
+
title: "Reject tracked changes by id",
|
|
215
|
+
description: "Rejects the specified tracked-change suggestions. For tracked inserts the inserted text is removed; for tracked deletes the strikethrough is cleared and the text stays. Implemented as an OT update with `u:true` flags on the inverse ops — same pathway Overleaf's web client uses. Pass the `change_id` values from `list_tracked_changes`. Irreversible.",
|
|
216
|
+
inputSchema: RejectSchema.shape,
|
|
217
|
+
}, async (args) => {
|
|
218
|
+
const ap = getActiveProject();
|
|
219
|
+
if (!ap)
|
|
220
|
+
return { content: [{ type: "text", text: "No project is open." }], isError: true };
|
|
221
|
+
try {
|
|
222
|
+
// Find the full change records (need position and text to invert).
|
|
223
|
+
const ranges = await fetchAllRanges(ap.projectId);
|
|
224
|
+
const pathMap = docPathById(ap);
|
|
225
|
+
const members = memberMap(ap);
|
|
226
|
+
const flat = flattenChanges(ranges, pathMap, members);
|
|
227
|
+
const wanted = new Set(args.change_ids);
|
|
228
|
+
const matches = flat.filter((c) => wanted.has(c.change_id));
|
|
229
|
+
const missing = args.change_ids.filter((id) => !flat.some((c) => c.change_id === id));
|
|
230
|
+
if (matches.length === 0) {
|
|
231
|
+
return { content: [{ type: "text", text: `No matching pending changes for the supplied ids. They may already be accepted/rejected. missing: ${missing.join(", ")}` }], isError: true };
|
|
232
|
+
}
|
|
233
|
+
// Group by doc and reject per doc.
|
|
234
|
+
const byDoc = new Map();
|
|
235
|
+
for (const c of matches) {
|
|
236
|
+
const arr = byDoc.get(c.doc_id) ?? [];
|
|
237
|
+
arr.push(c);
|
|
238
|
+
byDoc.set(c.doc_id, arr);
|
|
239
|
+
}
|
|
240
|
+
let rejected = 0;
|
|
241
|
+
const docResults = [];
|
|
242
|
+
for (const [docId, list] of byDoc) {
|
|
243
|
+
await rejectViaOt(docId, list);
|
|
244
|
+
rejected += list.length;
|
|
245
|
+
docResults.push({ doc_id: docId, doc_path: pathMap.get(docId), count: list.length });
|
|
246
|
+
}
|
|
247
|
+
const note = missing.length ? ` (${missing.length} unknown id(s) skipped)` : "";
|
|
248
|
+
return {
|
|
249
|
+
content: [{ type: "text", text: `Rejected ${rejected} change(s) across ${docResults.length} doc(s)${note}.` }],
|
|
250
|
+
structuredContent: { rejected, docs: docResults, missing },
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
catch (err) {
|
|
254
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
255
|
+
logger.error("reject_changes failed", msg);
|
|
256
|
+
return { content: [{ type: "text", text: `Failed: ${msg}` }], isError: true };
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
//# sourceMappingURL=trackedChanges.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trackedChanges.js","sourceRoot":"","sources":["../../src/tools/trackedChanges.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// All logging goes to stderr — stdout is reserved for the MCP JSON-RPC channel.
|
|
2
|
+
const LEVELS = { debug: 10, info: 20, warn: 30, error: 40 };
|
|
3
|
+
const threshold = LEVELS[process.env.OL_MCP_LOG_LEVEL ?? "info"] ?? LEVELS.info;
|
|
4
|
+
function log(level, msg, extra) {
|
|
5
|
+
if (LEVELS[level] < threshold)
|
|
6
|
+
return;
|
|
7
|
+
const line = extra === undefined
|
|
8
|
+
? `[overleaf-mcp ${level}] ${msg}`
|
|
9
|
+
: `[overleaf-mcp ${level}] ${msg} ${typeof extra === "string" ? extra : JSON.stringify(extra)}`;
|
|
10
|
+
process.stderr.write(line + "\n");
|
|
11
|
+
}
|
|
12
|
+
export const logger = {
|
|
13
|
+
debug: (m, e) => log("debug", m, e),
|
|
14
|
+
info: (m, e) => log("info", m, e),
|
|
15
|
+
warn: (m, e) => log("warn", m, e),
|
|
16
|
+
error: (m, e) => log("error", m, e),
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/util/logger.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAIhF,MAAM,MAAM,GAA0B,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AACnF,MAAM,SAAS,GAAG,MAAM,CAAE,OAAO,CAAC,GAAG,CAAC,gBAA0B,IAAI,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC;AAE3F,SAAS,GAAG,CAAC,KAAY,EAAE,GAAW,EAAE,KAAe;IACrD,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,SAAS;QAAE,OAAO;IACtC,MAAM,IAAI,GAAG,KAAK,KAAK,SAAS;QAC9B,CAAC,CAAC,iBAAiB,KAAK,KAAK,GAAG,EAAE;QAClC,CAAC,CAAC,iBAAiB,KAAK,KAAK,GAAG,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;IAClG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,KAAK,EAAE,CAAC,CAAS,EAAE,CAAW,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IACrD,IAAI,EAAE,CAAC,CAAS,EAAE,CAAW,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IACnD,IAAI,EAAE,CAAC,CAAS,EAAE,CAAW,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IACnD,KAAK,EAAE,CAAC,CAAS,EAAE,CAAW,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;CACtD,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@netique/overleaf-mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server for Overleaf with tracked-changes support, via the Socket.IO web API (not the Git bridge).",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"overleaf-mcp": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"README.md",
|
|
12
|
+
"LICENSE"
|
|
13
|
+
],
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/netique/overleaf-mcp.git"
|
|
17
|
+
},
|
|
18
|
+
"homepage": "https://github.com/netique/overleaf-mcp#readme",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/netique/overleaf-mcp/issues"
|
|
21
|
+
},
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc -p tsconfig.json && chmod +x dist/index.js",
|
|
27
|
+
"dev": "tsx watch src/index.ts",
|
|
28
|
+
"start": "node dist/index.js",
|
|
29
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
30
|
+
"test": "node --test --import tsx tests/unit/*.spec.ts",
|
|
31
|
+
"prepublishOnly": "npm run build"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"overleaf",
|
|
35
|
+
"mcp",
|
|
36
|
+
"model-context-protocol",
|
|
37
|
+
"latex",
|
|
38
|
+
"tracked-changes",
|
|
39
|
+
"claude"
|
|
40
|
+
],
|
|
41
|
+
"license": "AGPL-3.0-or-later",
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=20"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
47
|
+
"diff-match-patch": "^1.0.5",
|
|
48
|
+
"uuid": "^11.0.0",
|
|
49
|
+
"ws": "^8.20.1",
|
|
50
|
+
"zod": "^4.4.3"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/diff-match-patch": "^1.0.36",
|
|
54
|
+
"@types/node": "^22.0.0",
|
|
55
|
+
"@types/uuid": "^10.0.0",
|
|
56
|
+
"@types/ws": "^8.18.1",
|
|
57
|
+
"tsx": "^4.19.0",
|
|
58
|
+
"typescript": "^5.6.0"
|
|
59
|
+
}
|
|
60
|
+
}
|