|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +Lara Translate MCP Server is a Model Context Protocol (MCP) server that provides translation capabilities through the Lara Translate API. The server supports both STDIO and HTTP transport modes. |
| 8 | + |
| 9 | +## Development Commands |
| 10 | + |
| 11 | +### Setup |
| 12 | +```bash |
| 13 | +# Install dependencies |
| 14 | +pnpm install |
| 15 | + |
| 16 | +# Build the project |
| 17 | +pnpm run build |
| 18 | +``` |
| 19 | + |
| 20 | +### Development |
| 21 | +```bash |
| 22 | +# Run in development mode with hot reload |
| 23 | +pnpm run dev |
| 24 | + |
| 25 | +# Start the built server |
| 26 | +pnpm run start |
| 27 | +``` |
| 28 | + |
| 29 | +### Testing |
| 30 | +```bash |
| 31 | +# Run all tests once |
| 32 | +pnpm test |
| 33 | + |
| 34 | +# Run tests in watch mode |
| 35 | +pnpm test:watch |
| 36 | + |
| 37 | +# Run tests with coverage report |
| 38 | +pnpm test:coverage |
| 39 | +``` |
| 40 | + |
| 41 | +### Docker Development |
| 42 | +```bash |
| 43 | +# Build Docker image |
| 44 | +docker build -t lara-mcp . |
| 45 | +``` |
| 46 | + |
| 47 | +## Architecture |
| 48 | + |
| 49 | +### Server Modes |
| 50 | + |
| 51 | +The server operates in two transport modes determined by the `TRANSPORT` environment variable: |
| 52 | + |
| 53 | +1. **STDIO Mode** (`src/index.ts:56-75`): Direct MCP server using stdio transport, requires `LARA_ACCESS_KEY_ID` and `LARA_ACCESS_KEY_SECRET` environment variables. |
| 54 | + |
| 55 | +2. **HTTP Mode** (`src/index.ts:42-54`): REST API server with MCP protocol endpoint at `/v1` |
| 56 | + |
| 57 | +### Core Components |
| 58 | + |
| 59 | +#### MCP Server (`src/mcp/server.ts`) |
| 60 | + |
| 61 | +The server factory function `getMcpServer(accessKeyId, accessKeySecret)` creates an MCP server instance with: |
| 62 | +- `accessKeyId`: The Lara Translate API access key ID |
| 63 | +- `accessKeySecret`: The Lara Translate API access key secret |
| 64 | + |
| 65 | +The server initializes a `Translator` instance from the `@translated/lara` SDK and configures MCP request handlers for tools and resources. |
| 66 | + |
| 67 | +#### Tools (`src/mcp/tools/`) |
| 68 | + |
| 69 | +All MCP tools are organized in individual files under `src/mcp/tools/`: |
| 70 | + |
| 71 | +**Translation Tools:** |
| 72 | +- `translate.ts` - Main translation with context, instructions, memory support, and glossaries |
| 73 | + - Advanced options: `glossaries` (array of glossary IDs, max 10), `no_trace` (privacy flag), `priority` (normal/background), `timeout_in_millis` (max 300000ms) |
| 74 | + - Validation includes format checks for glossary IDs (`gls_*` pattern) and timeout limits |
| 75 | + |
| 76 | +**Glossary Management Tools:** |
| 77 | +- `list_glossaries.ts` - List all glossaries |
| 78 | +- `get_glossary.ts` - Get glossary by ID (returns null if not found) |
| 79 | + - Validates glossary ID format with regex `/^gls_[a-zA-Z0-9_-]+$/` |
| 80 | + |
| 81 | +**Memory Management Tools:** |
| 82 | +- `list_memories.ts` - List all translation memories |
| 83 | +- `create_memory.ts` - Create new memory (supports MyMemory import via `external_id`) |
| 84 | +- `update_memory.tool.ts` - Update memory name |
| 85 | +- `delete_memory.ts` - Delete memory |
| 86 | +- `add_translation.ts` - Add translation unit to memory |
| 87 | +- `delete_translation.ts` - Remove translation unit from memory |
| 88 | +- `import_tmx.ts` - Import TMX file (supports gzip compression) |
| 89 | +- `check_import_status.ts` - Check TMX import job status |
| 90 | + |
| 91 | +**Language Support:** |
| 92 | +- `list_languages.ts` - List supported languages |
| 93 | + |
| 94 | +Each tool exports a handler function and a Zod validation schema. Tool registration happens in `src/mcp/tools.ts` which maintains two handler maps: |
| 95 | +- `handlers` - Tools with arguments (e.g., translate, create_memory) |
| 96 | +- `listers` - Tools without arguments (e.g., list_memories, list_languages) |
| 97 | + |
| 98 | +#### Resources (`src/mcp/resources.ts`) |
| 99 | + |
| 100 | +The MCP server exposes translation memories as resources: |
| 101 | +- Resource URI format: `memory://{memoryId}` |
| 102 | +- Resource template: `memory://{memoryId}` for listing memories |
| 103 | + |
| 104 | +### Path Aliases |
| 105 | + |
| 106 | +The project uses path aliases (configured in `tsconfig.json` and `package.json` imports): |
| 107 | +- `#env` → `src/env.js` |
| 108 | +- `#exception` → `src/exception.js` |
| 109 | +- `#logger` → `src/logger.js` |
| 110 | +- `#rest/server` → `src/rest/server.js` |
| 111 | +- `#mcp/server` → `src/mcp/server.js` |
| 112 | + |
| 113 | +### Environment Variables |
| 114 | + |
| 115 | +Core configuration (`src/env.ts`): |
| 116 | +- `TRANSPORT` - Server mode: `stdio` or `http` (default: `stdio`) |
| 117 | +- `HOST` / `PORT` - HTTP server binding (default: `0.0.0.0:3000`) |
| 118 | +- `LARA_ACCESS_KEY_ID` / `LARA_ACCESS_KEY_SECRET` - API credentials (required for STDIO mode) |
| 119 | +- `LOGGING_LEVEL` - Log level: `debug`, `info`, `warn`, `error` (default: `info`) |
| 120 | + |
| 121 | +### Error Handling |
| 122 | + |
| 123 | +Custom exception classes (`src/exception.ts`): |
| 124 | +- `ServerException` - Base exception with error code |
| 125 | +- `InvalidInputError` - Invalid request parameters (code: -32600) |
| 126 | +- `InvalidCredentialsError` - Authentication failure (code: -32600) |
| 127 | +- `MethodNotAllowedError` - HTTP method not allowed (code: -32601) |
| 128 | + |
| 129 | +Error handling in `src/mcp/tools.ts`: |
| 130 | +- Zod validation errors return specific field names (not full error details for security) |
| 131 | +- Existing `InvalidInputError` instances are preserved and re-thrown |
| 132 | +- Other unexpected errors are logged internally and returned as generic "An error occurred while processing your request" message |
| 133 | +- Privacy-sensitive translations (with `no_trace=true`) are logged for audit purposes |
| 134 | + |
| 135 | +### Logging |
| 136 | + |
| 137 | +The server uses Pino structured logging (`src/logger.ts`). Log level is controlled by `LOGGING_LEVEL` environment variable. |
| 138 | + |
| 139 | +## Testing |
| 140 | + |
| 141 | +Tests are located in `src/__tests__/` and mirror the source structure: |
| 142 | +- `tools/` - Individual tool tests (71 total tests) |
| 143 | +- `server/` - REST server tests |
| 144 | +- `utils/mocks.ts` - Shared test utilities with Vitest mocks |
| 145 | + |
| 146 | +Tests use Vitest with coverage reporting (v8 provider). |
| 147 | + |
| 148 | +## Security Features |
| 149 | + |
| 150 | +- **Input validation**: All glossary IDs validated with regex, timeout capped at 300000ms, max 10 glossaries per request |
| 151 | +- **Error sanitization**: Zod errors filtered to show only field names, SDK errors hidden behind generic messages |
| 152 | +- **Audit logging**: Privacy-sensitive requests (no_trace=true) logged for compliance |
| 153 | +- **Credential protection**: Access key ID never logged in debug mode |
| 154 | + |
| 155 | +## Important Notes |
| 156 | + |
| 157 | +- When adding new tools, update both the handler in `src/mcp/tools/{tool}.ts` and register it in `src/mcp/tools.ts`. |
| 158 | +- All file imports must use the `.js` extension even though source files are `.ts` (ES module resolution requirement). |
| 159 | +- The `translate` tool builds options object dynamically - only includes non-empty arrays and defined values to avoid passing `undefined` to SDK. |
| 160 | +- Semicolons are consistently used throughout the codebase. |
0 commit comments