@mrfentmen/diff-mcp 1.0.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 ADDED
@@ -0,0 +1,21 @@
1
+ # Diff MCP
2
+
3
+ Compare two texts and show line changes locally. No network, no key.
4
+
5
+ This file is self contained. It reads public data only and never writes to the machine. All output is bounded and honest about what could not be fetched.
6
+
7
+ ## Tools
8
+
9
+
10
+ * `diff_text` Simple diff.
11
+ * `unified_diff` Unified diff with context.
12
+
13
+ ## Usage
14
+
15
+ ```bash
16
+ npm install
17
+ npm run build
18
+ node dist/index.js
19
+ ```
20
+
21
+ Diffing runs locally with the diff library.
package/dist/api.js ADDED
@@ -0,0 +1,24 @@
1
+ import { diffLines, createTwoFilesPatch } from "diff";
2
+ export class DiffError extends Error {
3
+ }
4
+ export async function diffText(args) {
5
+ const a = args.a ?? "";
6
+ const b = args.b ?? "";
7
+ const changes = diffLines(a, b);
8
+ const out = [];
9
+ for (const c of changes) {
10
+ const lines = c.value.split("\n").filter(Boolean);
11
+ if (c.added)
12
+ out.push(...lines.map((l) => `+ ${l}`));
13
+ else if (c.removed)
14
+ out.push(...lines.map((l) => `- ${l}`));
15
+ else
16
+ out.push(...lines.map((l) => ` ${l}`));
17
+ }
18
+ return out.slice(0, 200).join("\n");
19
+ }
20
+ export async function unifiedDiff(args) {
21
+ const ctx = Math.min(Math.max(args.context ?? 3, 0), 10);
22
+ const patch = createTwoFilesPatch("original", "changed", args.a ?? "", args.b ?? "", "", "", { context: ctx });
23
+ return patch.slice(0, 8000);
24
+ }
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
2
+ import { createServer } from "./server.js";
3
+ const main = async () => { const server = createServer(); await server.connect(new StdioServerTransport()); };
4
+ main().catch((error) => { console.error("Fatal error:", error); process.exit(1); });
package/dist/server.js ADDED
@@ -0,0 +1,38 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { z } from "zod";
3
+ import { diffText } from "./api.js";
4
+ import { unifiedDiff } from "./api.js";
5
+ const text = (value) => ({ content: [{ type: "text", text: value }] });
6
+ const textError = (t) => ({ content: [{ type: "text", text: t }], isError: true });
7
+ const READ_ONLY = { readOnlyHint: true, openWorldHint: true };
8
+ const error = (e) => `Error: ${e instanceof Error ? e.message : String(e)}`;
9
+ export function createServer() {
10
+ const server = new McpServer({ name: "diff-mcp", version: "1.0.0" });
11
+ server.registerTool("diff_text", {
12
+ title: "Diff text",
13
+ description: "Show the diff between two texts.",
14
+ inputSchema: z.object({ a: z.string().describe("Original text."), b: z.string().describe("New text.") }),
15
+ annotations: READ_ONLY,
16
+ }, async (args) => {
17
+ try {
18
+ return text(await diffText(args));
19
+ }
20
+ catch (e) {
21
+ return textError(error(e));
22
+ }
23
+ });
24
+ server.registerTool("unified_diff", {
25
+ title: "Unified diff",
26
+ description: "Show a unified diff between two texts.",
27
+ inputSchema: z.object({ a: z.string().describe("Original text."), b: z.string().describe("New text."), context: z.number().describe("Context lines.").optional() }),
28
+ annotations: READ_ONLY,
29
+ }, async (args) => {
30
+ try {
31
+ return text(await unifiedDiff(args));
32
+ }
33
+ catch (e) {
34
+ return textError(error(e));
35
+ }
36
+ });
37
+ return server;
38
+ }
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "version": "1.0.0",
3
+ "type": "module",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/mrfentmen/diff-mcp.git"
7
+ },
8
+ "bin": {
9
+ "diff-mcp": "./dist/index.js"
10
+ },
11
+ "main": "./dist/index.js",
12
+ "files": [
13
+ "dist",
14
+ "server.json",
15
+ "README.md"
16
+ ],
17
+ "scripts": {
18
+ "build": "tsc -p tsconfig.json",
19
+ "start": "node dist/index.js",
20
+ "dev": "npm run build && node dist/index.js"
21
+ },
22
+ "license": "MIT",
23
+ "dependencies": {
24
+ "@modelcontextprotocol/sdk": "^1.0.4",
25
+ "diff": "^7.0.0",
26
+ "js-yaml": "^4.1.0",
27
+ "marked": "^14.0.0",
28
+ "turndown": "^7.2.0",
29
+ "zod": "^3.23.8"
30
+ },
31
+ "devDependencies": {
32
+ "@types/diff": "^7.0.2",
33
+ "@types/js-yaml": "^4.0.9",
34
+ "@types/node": "^22.0.0",
35
+ "@types/turndown": "^5.0.6",
36
+ "typescript": "^5.6.0"
37
+ },
38
+ "name": "@mrfentmen/diff-mcp",
39
+ "description": "Compare two texts or files and show line changes locally. No network and no key.",
40
+ "mcpName": "io.github.mrfentmen/diff-mcp",
41
+ "keywords": [
42
+ "mcp",
43
+ "diff",
44
+ "compare",
45
+ "text",
46
+ "files"
47
+ ],
48
+ "engines": {
49
+ "node": ">=20"
50
+ }
51
+ }
package/server.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
+ "name": "io.github.mrfentmen/diff-mcp",
4
+ "description": "Compare two texts or files and show line changes locally. No network and no key.",
5
+ "repository": {
6
+ "url": "https://github.com/mrfentmen/diff-mcp",
7
+ "source": "github"
8
+ },
9
+ "version": "1.0.0",
10
+ "packages": [
11
+ {
12
+ "registryType": "npm",
13
+ "identifier": "@mrfentmen/diff-mcp",
14
+ "version": "1.0.0",
15
+ "transport": {
16
+ "type": "stdio"
17
+ }
18
+ }
19
+ ]
20
+ }