#
tokens: 3078/50000 9/9 files
lines: on (toggle) GitHub
raw markdown copy reset
# Directory Structure

```
├── .gitignore
├── .npmignore
├── jest.config.js
├── LICENSE
├── package-lock.json
├── package.json
├── README.md
├── src
│   ├── diffGetter.ts
│   └── index.ts
├── test
│   └── diffGetter.test.ts
└── tsconfig.json
```

# Files

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
1 | node_modules/
2 | build/
3 | *.log
4 | .env*
```

--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------

```
1 | node_modules
2 | src
3 | test
4 | tsconfig.json
5 | jest.config.js
6 | .gitignore
7 | package-lock.json
8 | 
```

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
 1 | # mcp-server-diff-typescript MCP Server
 2 | 
 3 | A Model Context Protocol server that provides unified diff generation capabilities.
 4 | 
 5 | This TypeScript-based MCP server implements a diff generation system. It provides a tool to generate unified diffs between two text strings, which is useful for comparing and analyzing text differences.
 6 | 
 7 | <a href="https://glama.ai/mcp/servers/3sbmp65pce"><img width="380" height="200" src="https://glama.ai/mcp/servers/3sbmp65pce/badge" alt="Server Diff TypeScript MCP server" /></a>
 8 | 
 9 | ## Features
10 | 
11 | ### Tools
12 | 
13 | - `get-unified-diff` - Generate unified diff between two text strings
14 |   - Takes `oldString` and `newString` as required parameters
15 |   - Returns the difference in unified diff format
16 |   - Uses the `diff` package for accurate difference detection
17 |   - Includes 3 lines of context around changes
18 | 
19 | ## Installation
20 | 
21 | ### As a Global Package
22 | 
23 | ```bash
24 | npm install -g mcp-server-diff-typescript
25 | ```
26 | 
27 | ### As a Project Dependency
28 | 
29 | ```bash
30 | npm install mcp-server-diff-typescript
31 | ```
32 | 
33 | ## Usage
34 | 
35 | ### Using with Claude Desktop
36 | 
37 | To use with Claude Desktop, add the server config:
38 | 
39 | On MacOS: `~/Library/Application Support/Claude/claude_desktop_config.json`  
40 | On Windows: `%APPDATA%/Claude/claude_desktop_config.json`
41 | 
42 | 
43 | ```json
44 | "mcpServers": {
45 |   "mcp-server-diff-typescript": {
46 |     "command": "npx",
47 |     "args": [
48 |       "-y",
49 |       "mcp-server-diff-typescript"
50 |     ]
51 |   }
52 | }
53 | ```
54 | 
55 | or Add the following configuration:
56 | 
57 | ```bash
58 | git clone https://github.com/tatn/mcp-server-diff-typescript.git
59 | cd mcp-server-diff-typescript
60 | npm install
61 | npm run build
62 | ```
63 | 
64 | ```json
65 | "mcpServers": {
66 |   "mcp-server-diff-typescript": {
67 |     "command": "node",
68 |     "args": [
69 |       "/path/to/mcp-server-diff-typescript/build/index.js"
70 |     ]
71 |   }
72 | }
73 | ```
74 | 
75 | ### Debugging
76 | 
77 | To debug the MCP server:
78 | 
79 | ```bash
80 | npx @modelcontextprotocol/inspector npx -y mcp-server-diff-typescript
81 | ```
82 | 
83 | 
84 | ```bash
85 | npx @modelcontextprotocol/inspector node /path/to/mcp-server-diff-typescript/build/index.js
86 | ```
87 | 
```

--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------

```javascript
 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */
 2 | export default {
 3 |   preset: 'ts-jest',
 4 |   testEnvironment: 'node',
 5 |   extensionsToTreatAsEsm: ['.ts'],
 6 |   moduleNameMapper: {
 7 |     '^(\\.{1,2}/.*)\\.js$': '$1',
 8 |   },
 9 |   transform: {
10 |     '^.+\\.tsx?$': ['ts-jest', {
11 |       useESM: true,
12 |     }],
13 |   },
14 | };
```

--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "compilerOptions": {
 3 |     "target": "ES2022",
 4 |     "module": "Node16",
 5 |     "moduleResolution": "Node16",
 6 |     "outDir": "./build",
 7 |     "rootDir": "./src",
 8 |     "strict": true,
 9 |     "esModuleInterop": true,
10 |     "skipLibCheck": true,
11 |     "forceConsistentCasingInFileNames": true,
12 |     "declaration": true,
13 |     "sourceMap": true
14 |   },
15 |   "include": ["src/**/*"],
16 |   "exclude": ["node_modules","build"]
17 | }
18 | 
```

--------------------------------------------------------------------------------
/src/diffGetter.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { diffLines, createPatch } from 'diff';
 2 | 
 3 | export function generateUnifiedDiff(oldString: string, newString: string, oldHeader: string = '', newHeader: string = '', fileName: string = ''): string {
 4 |   const diff = diffLines(oldString, newString);
 5 |   if (diff.length === 1 && !diff[0].added && !diff[0].removed) {
 6 |     return ''; // No change detected
 7 |   }
 8 |   return createPatch(fileName, oldString, newString, oldHeader, newHeader, { context: 3 });
 9 | }
10 | 
```

--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "name": "mcp-server-diff-typescript",
 3 |   "version": "1.0.5",
 4 |   "description": "A Model Context Protocol server that provides unified diff generation capabilities",
 5 |   "main": "./build/index.js",
 6 |   "type": "module",
 7 |   "bin": {
 8 |     "mcp-server-diff-typescript": "build/index.js"
 9 |   },
10 |   "files": [
11 |     "build"
12 |   ],
13 |   "scripts": {
14 |     "build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"",
15 |     "prepare": "npm run build",
16 |     "watch": "tsc --watch",
17 |     "test": "jest",
18 |     "inspector": "npx @modelcontextprotocol/inspector build/index.js"
19 |   },
20 |   "repository": {
21 |     "type": "git",
22 |     "url": "git+https://github.com/tatn/mcp-server-diff-typescript.git"
23 |   },
24 |   "keywords": [
25 |     "mcp",
26 |     "server",
27 |     "diff",
28 |     "unified"
29 |   ],
30 |   "homepage": "https://github.com/tatn/mcp-server-diff-typescript",
31 |   "license": "MIT",
32 |   "author": "tatn",
33 |   "dependencies": {
34 |     "@modelcontextprotocol/sdk": "0.6.0",
35 |     "diff": "^7.0.0"
36 |   },
37 |   "devDependencies": {
38 |     "@types/diff": "^7.0.0",
39 |     "@types/jest": "^29.5.14",
40 |     "@types/node": "^20.11.24",
41 |     "jest": "^29.7.0",
42 |     "ts-jest": "^29.2.5",
43 |     "typescript": "^5.3.3"
44 |   },
45 |   "types": "build/index.d.ts"
46 | }
47 | 
```

--------------------------------------------------------------------------------
/test/diffGetter.test.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { generateUnifiedDiff } from '../src/diffGetter';
 2 | 
 3 | describe('generateUnifiedDiff', () => {
 4 |   it('should return an empty string when there are no changes', () => {
 5 |     const oldString = 'Hello World';
 6 |     const newString = 'Hello World';
 7 |     const result = generateUnifiedDiff(oldString, newString);
 8 |     expect(result).toBe('');
 9 |   });
10 | 
11 |   it('should generate a unified diff for changed content', () => {
12 |     const oldString = 'Hello World';
13 |     const newString = 'Hello GitHub Copilot';
14 |     const result = generateUnifiedDiff(oldString, newString);
15 |     expect(result).toContain('Hello World');
16 |     expect(result).toContain('Hello GitHub Copilot');
17 |   });
18 | 
19 |   it('should include headers in the diff', () => {
20 |     const oldString = 'Hello World';
21 |     const newString = 'Hello GitHub Copilot';
22 |     const oldHeader = 'v1';
23 |     const newHeader = 'v2';
24 |     const result = generateUnifiedDiff(oldString, newString, oldHeader, newHeader);
25 |     expect(result).toContain('--- 	v1');
26 |     expect(result).toContain('+++ 	v2');
27 |   });
28 | 
29 |   it('should include file name in the diff', () => {
30 |     const oldString = 'Hello World';
31 |     const newString = 'Hello GitHub Copilot';
32 |     const fileName = 'testFile.txt';
33 |     const result = generateUnifiedDiff(oldString, newString, '', '', fileName);
34 |     expect(result).toContain('--- testFile.txt');
35 |     expect(result).toContain('+++ testFile.txt');
36 |   });
37 | });
```

--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------

```typescript
 1 | #!/usr/bin/env node
 2 | 
 3 | /**
 4 |  * MCP server that returns the difference between strings in Unified Diff format.
 5 |  */
 6 | 
 7 | import { Server } from "@modelcontextprotocol/sdk/server/index.js";
 8 | import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
 9 | import { generateUnifiedDiff } from "./diffGetter.js";
10 | import {
11 |   CallToolRequestSchema,
12 |   ListToolsRequestSchema,
13 | } from "@modelcontextprotocol/sdk/types.js";
14 | 
15 | const server = new Server(
16 |   {
17 |     name: "mcp-server-diff-typescript",
18 |     version: "0.1.0",
19 |   },
20 |   {
21 |     capabilities: {
22 |       resources: {},
23 |       tools: {},
24 |       prompts: {},
25 |     },
26 |   }
27 | );
28 | 
29 | /**
30 | 
31 |  */
32 | server.setRequestHandler(ListToolsRequestSchema, async () => {
33 |   return {
34 |     tools: [
35 |       {
36 |         name: "get-unified-diff",
37 |         description: "Get the difference between two text articles in Unified diff format.",
38 |         inputSchema: {
39 |           type: "object",
40 |           properties: {
41 |             oldString: {
42 |               type: "string",
43 |               description: "old string to compare"
44 |             },
45 |             newString: {
46 |               type: "string",
47 |               description: "new string to compare"
48 |             }
49 |           },
50 |           required: ["oldString", "newString"]
51 |         }
52 |       }
53 |     ]
54 |   };
55 | });
56 | 
57 | /**
58 |  * Handler for the create_note and get-unified-diff tools.
59 |  */
60 | server.setRequestHandler(CallToolRequestSchema, async (request) => {
61 |   switch (request.params.name) {
62 |     case "get-unified-diff": {
63 |       const oldString = String(request.params.arguments?.oldString);
64 |       const newString = String(request.params.arguments?.newString);
65 |       if (!oldString || !newString) {
66 |         throw new Error("oldString and newString are required");
67 |       }
68 | 
69 |       const diffResult = generateUnifiedDiff(oldString, newString, "", "", "");
70 | 
71 |       return {
72 |         content: [{
73 |           type: "text",
74 |           text: diffResult
75 |         }]
76 |       };
77 |     }
78 |     default:
79 |       throw new Error("Unknown tool");
80 |   }
81 | });
82 | 
83 | /**
84 |  * Start the server using stdio transport.
85 |  * This allows the server to communicate via standard input/output streams.
86 |  */
87 | async function main() {
88 |   const transport = new StdioServerTransport();
89 |   await server.connect(transport);
90 | }
91 | 
92 | main().catch((error) => {
93 |   console.error("Server error:", error);
94 |   process.exit(1);
95 | });
96 | 
```