diff options
| author | haoyuren <13851610112@163.com> | 2026-07-28 06:29:04 +0800 |
|---|---|---|
| committer | haoyuren <13851610112@163.com> | 2026-07-28 06:29:04 +0800 |
| commit | d35a6a0ef366f86aeba28c06f40e44cd29cf1f07 (patch) | |
| tree | 1f9e08527da6720722dde971636273d859af89d6 /src/mcp | |
| parent | 1ab00142191f4e3b94ba36d2a33914697864c892 (diff) | |
Codex/agent-neutral setup, terminal IME fix, hide own overlay cursor
- Write AGENTS.md (the cross-tool agent-instructions standard) at the
project root alongside .claude/CLAUDE.md, generated from one guide;
includes an Agent Setup section with the project-specific Codex MCP
registration command. AGENTS.md is excluded from Overleaf sync.
- MCP server resolves the project directory from its own script location
when cwd doesn't contain the state file, so clients that launch MCP
servers from a global config (Codex) work without special setup
- Terminal: swallow the duplicate compositionend commit when switching
input sources mid-composition (xterm finalizes on the keydown and then
again on compositionend, sending pinyin text twice)
- Don't render our own colored overlay cursor — the native caret already
marks our position; overlay cursors are collaborators-only (web parity)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Diffstat (limited to 'src/mcp')
| -rw-r--r-- | src/mcp/lattex.mjs | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/src/mcp/lattex.mjs b/src/mcp/lattex.mjs index 64520f7..e0cb6cd 100644 --- a/src/mcp/lattex.mjs +++ b/src/mcp/lattex.mjs @@ -3,8 +3,9 @@ // Licensed under AGPL-3.0 - see LICENSE file // MCP Server: LatteX -// Provides tools for Claude Code to interact with the Overleaf project: -// comments, chat, file listing, compilation + debugging +// Provides tools for coding agents (Claude Code, Codex, any MCP client) to +// interact with the Overleaf project: comments, chat, file listing, +// compilation + debugging import { Server } from '@modelcontextprotocol/sdk/server/index.js' import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js' @@ -13,14 +14,34 @@ import { ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js' import { readFileSync, readdirSync, statSync, writeFileSync, existsSync, unlinkSync } from 'fs' -import { join, relative } from 'path' +import { join, relative, dirname } from 'path' +import { fileURLToPath } from 'url' import https from 'https' +// ── Project directory resolution ────────────────────────────── +// +// Claude Code launches MCP servers with the project as cwd, but other MCP +// clients (Codex reads global config) may not. The packaged server is copied +// into <project>/.lattex/lattex-mcp.mjs, so the script's own location also +// identifies the project. Resolution order: cwd, then script parent dir. + +function resolveProjectDir() { + const cwd = process.cwd() + if (existsSync(join(cwd, '.lattex-mcp.json'))) return cwd + try { + const scriptDir = dirname(fileURLToPath(import.meta.url)) + const candidate = dirname(scriptDir) // <project>/.lattex/.. = <project> + if (existsSync(join(candidate, '.lattex-mcp.json'))) return candidate + } catch { /* fall through */ } + return cwd +} + +const PROJECT_DIR = resolveProjectDir() + // ── State ────────────────────────────────────────────────────── function readState() { - const cwd = process.cwd() - const statePath = join(cwd, '.lattex-mcp.json') + const statePath = join(PROJECT_DIR, '.lattex-mcp.json') try { return JSON.parse(readFileSync(statePath, 'utf-8')) } catch { @@ -847,7 +868,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => { // ── Project ─────────────────────────────────── case 'list_project_files': { - const cwd = process.cwd() + const cwd = PROJECT_DIR const files = walkDir(cwd, cwd) .filter(f => !f.path.startsWith('.')) @@ -870,7 +891,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => { case 'compile_latex': { const mainFile = args?.main_file || null - const cwd = process.cwd() + const cwd = PROJECT_DIR const requestPath = join(cwd, '.lattex-compile-request') const resultPath = join(cwd, '.lattex-compile-result') @@ -1015,7 +1036,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => { } case 'get_online_users': { - const cwd = process.cwd() + const cwd = PROJECT_DIR const usersPath = join(cwd, '.lattex-online-users.json') try { const users = JSON.parse(readFileSync(usersPath, 'utf-8')) @@ -1032,7 +1053,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => { // ── PDF ────────────────────────────────────────── case 'read_compiled_pdf': { - const cwd = process.cwd() + const cwd = PROJECT_DIR const pdfPath = join(cwd, '.build', 'output.pdf') try { statSync(pdfPath) |
