kleanmcp 1.0.1

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,31 @@
1
+ # kleanmcp
2
+
3
+ ## Example
4
+
5
+ ```
6
+ export const Tool1 = ToolDefinition(
7
+ "tool_name_1",
8
+ "this tool is a test tool 1",
9
+ [
10
+ {
11
+ name: "arg1",
12
+ description: "describing arg1",
13
+ type: "string",
14
+ required: false,
15
+ },
16
+ ] as const,
17
+ )(async (
18
+ _reference: object,
19
+ arg_string: string,
20
+ _extra?: any,
21
+ ): Promise<CallToolResult> => {
22
+ return {
23
+ content: [
24
+ {
25
+ type: "text",
26
+ text: arg_string,
27
+ },
28
+ ],
29
+ };
30
+ });
31
+ ```
package/build.ts ADDED
@@ -0,0 +1,30 @@
1
+ import { $, build } from 'bun'
2
+ import pack from './package.json'
3
+
4
+ await $`rm -rf dist`
5
+
6
+ const external = Object.keys(pack.dependencies).filter(
7
+ x => !["elysia-jsonrpc"].includes(x)
8
+ );
9
+
10
+ const buildresults = await Promise.all([
11
+ build({
12
+ entrypoints: ["./src/index.ts", "./src/types.ts"],
13
+ format: "esm",
14
+ outdir: "dist",
15
+ naming: "[name].mjs",
16
+ external,
17
+ }),
18
+ build({
19
+ entrypoints: ["./src/index.ts", "./src/types.ts"],
20
+ format: "cjs",
21
+ outdir: "dist",
22
+ naming: "[name].cjs",
23
+ external,
24
+ }),
25
+ $`tsc --project tsconfig.dts.json`
26
+ ])
27
+
28
+ console.log(buildresults.map((x:any) => x['success'] != undefined? x.success : x.exitCode == 0))
29
+
30
+ process.exit()
package/bun.lock ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "lockfileVersion": 1,
3
+ "configVersion": 1,
4
+ "workspaces": {
5
+ "": {
6
+ "name": "leanmcp",
7
+ "devDependencies": {
8
+ "@types/bun": "latest",
9
+ },
10
+ "peerDependencies": {
11
+ "elysia": "^1.4.25",
12
+ "typescript": "^5",
13
+ "zod": "^4.3.6",
14
+ },
15
+ },
16
+ },
17
+ "packages": {
18
+ "@borewit/text-codec": ["@borewit/text-codec@0.2.1", "", {}, "sha512-k7vvKPbf7J2fZ5klGRD9AeKfUvojuZIQ3BT5u7Jfv+puwXkUBUT5PVyMDfJZpy30CBDXGMgw7fguK/lpOMBvgw=="],
19
+
20
+ "@sinclair/typebox": ["@sinclair/typebox@0.34.48", "", {}, "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA=="],
21
+
22
+ "@tokenizer/inflate": ["@tokenizer/inflate@0.4.1", "", { "dependencies": { "debug": "^4.4.3", "token-types": "^6.1.1" } }, "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA=="],
23
+
24
+ "@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
25
+
26
+ "@types/bun": ["@types/bun@1.3.9", "", { "dependencies": { "bun-types": "1.3.9" } }, "sha512-KQ571yULOdWJiMH+RIWIOZ7B2RXQGpL1YQrBtLIV3FqDcCu6FsbFUBwhdKUlCKUpS3PJDsHlJ1QKlpxoVR+xtw=="],
27
+
28
+ "@types/node": ["@types/node@25.3.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-4K3bqJpXpqfg2XKGK9bpDTc6xO/xoUP/RBWS7AtRMug6zZFaRekiLzjVtAoZMquxoAbzBvy5nxQ7veS5eYzf8A=="],
29
+
30
+ "bun-types": ["bun-types@1.3.9", "", { "dependencies": { "@types/node": "*" } }, "sha512-+UBWWOakIP4Tswh0Bt0QD0alpTY8cb5hvgiYeWCMet9YukHbzuruIEeXC2D7nMJPB12kbh8C7XJykSexEqGKJg=="],
31
+
32
+ "cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="],
33
+
34
+ "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
35
+
36
+ "elysia": ["elysia@1.4.25", "", { "dependencies": { "cookie": "^1.1.1", "exact-mirror": "^0.2.7", "fast-decode-uri-component": "^1.0.1", "memoirist": "^0.4.0" }, "peerDependencies": { "@sinclair/typebox": ">= 0.34.0 < 1", "@types/bun": ">= 1.2.0", "file-type": ">= 20.0.0", "openapi-types": ">= 12.0.0", "typescript": ">= 5.0.0" }, "optionalPeers": ["@types/bun", "typescript"] }, "sha512-liKjavH99Gpzrv9cDil6uYWmPuqESfPFV1FIaFSd3iNqo3y7e29sN43VxFIK8tWWnyi6eDAmi2SZk8hNAMQMyg=="],
37
+
38
+ "exact-mirror": ["exact-mirror@0.2.7", "", { "peerDependencies": { "@sinclair/typebox": "^0.34.15" }, "optionalPeers": ["@sinclair/typebox"] }, "sha512-+MeEmDcLA4o/vjK2zujgk+1VTxPR4hdp23qLqkWfStbECtAq9gmsvQa3LW6z/0GXZyHJobrCnmy1cdeE7BjsYg=="],
39
+
40
+ "fast-decode-uri-component": ["fast-decode-uri-component@1.0.1", "", {}, "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg=="],
41
+
42
+ "file-type": ["file-type@21.3.0", "", { "dependencies": { "@tokenizer/inflate": "^0.4.1", "strtok3": "^10.3.4", "token-types": "^6.1.1", "uint8array-extras": "^1.4.0" } }, "sha512-8kPJMIGz1Yt/aPEwOsrR97ZyZaD1Iqm8PClb1nYFclUCkBi0Ma5IsYNQzvSFS9ib51lWyIw5mIT9rWzI/xjpzA=="],
43
+
44
+ "ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
45
+
46
+ "memoirist": ["memoirist@0.4.0", "", {}, "sha512-zxTgA0mSYELa66DimuNQDvyLq36AwDlTuVRbnQtB+VuTcKWm5Qc4z3WkSpgsFWHNhexqkIooqpv4hdcqrX5Nmg=="],
47
+
48
+ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
49
+
50
+ "openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="],
51
+
52
+ "strtok3": ["strtok3@10.3.4", "", { "dependencies": { "@tokenizer/token": "^0.3.0" } }, "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg=="],
53
+
54
+ "token-types": ["token-types@6.1.2", "", { "dependencies": { "@borewit/text-codec": "^0.2.1", "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww=="],
55
+
56
+ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
57
+
58
+ "uint8array-extras": ["uint8array-extras@1.5.0", "", {}, "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A=="],
59
+
60
+ "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="],
61
+
62
+ "zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="],
63
+ }
64
+ }
@@ -0,0 +1,31 @@
1
+ # test_leanmcp
2
+
3
+ ## Example
4
+
5
+ ```
6
+ export const Tool1 = ToolDefinition(
7
+ "tool_name_1",
8
+ "this tool is a test tool 1",
9
+ [
10
+ {
11
+ name: "arg1",
12
+ description: "describing arg1",
13
+ type: "string",
14
+ required: false,
15
+ },
16
+ ] as const,
17
+ )(async (
18
+ _reference: object,
19
+ arg_string: string,
20
+ _extra?: any,
21
+ ): Promise<CallToolResult> => {
22
+ return {
23
+ content: [
24
+ {
25
+ type: "text",
26
+ text: arg_string,
27
+ },
28
+ ],
29
+ };
30
+ });
31
+ ```
@@ -0,0 +1,75 @@
1
+ {
2
+ "lockfileVersion": 1,
3
+ "configVersion": 1,
4
+ "workspaces": {
5
+ "": {
6
+ "name": "test_leanmcp",
7
+ "dependencies": {
8
+ "@elysiajs/cors": "^1.4.1",
9
+ "@elysiajs/eden": "^1.4.8",
10
+ "elysia": "^1.4.25",
11
+ "leanmcp": "link:leanmcp",
12
+ "zod": "^4.3.6",
13
+ },
14
+ "devDependencies": {
15
+ "@types/bun": "latest",
16
+ },
17
+ "peerDependencies": {
18
+ "typescript": "^5",
19
+ },
20
+ },
21
+ },
22
+ "packages": {
23
+ "@borewit/text-codec": ["@borewit/text-codec@0.2.1", "", {}, "sha512-k7vvKPbf7J2fZ5klGRD9AeKfUvojuZIQ3BT5u7Jfv+puwXkUBUT5PVyMDfJZpy30CBDXGMgw7fguK/lpOMBvgw=="],
24
+
25
+ "@elysiajs/cors": ["@elysiajs/cors@1.4.1", "", { "peerDependencies": { "elysia": ">= 1.4.0" } }, "sha512-lQfad+F3r4mNwsxRKbXyJB8Jg43oAOXjRwn7sKUL6bcOW3KjUqUimTS+woNpO97efpzjtDE0tEjGk9DTw8lqTQ=="],
26
+
27
+ "@elysiajs/eden": ["@elysiajs/eden@1.4.8", "", { "peerDependencies": { "elysia": ">=1.4.19" } }, "sha512-a7oct2kFa49tH+GawZtSUCZR2rQgucNYgGLz8alXUqb4IrU3PASA0T4zXJw4MhdV1Xb6vyiR7p7kkqJcVjgbkA=="],
28
+
29
+ "@sinclair/typebox": ["@sinclair/typebox@0.34.48", "", {}, "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA=="],
30
+
31
+ "@tokenizer/inflate": ["@tokenizer/inflate@0.4.1", "", { "dependencies": { "debug": "^4.4.3", "token-types": "^6.1.1" } }, "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA=="],
32
+
33
+ "@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
34
+
35
+ "@types/bun": ["@types/bun@1.3.9", "", { "dependencies": { "bun-types": "1.3.9" } }, "sha512-KQ571yULOdWJiMH+RIWIOZ7B2RXQGpL1YQrBtLIV3FqDcCu6FsbFUBwhdKUlCKUpS3PJDsHlJ1QKlpxoVR+xtw=="],
36
+
37
+ "@types/node": ["@types/node@25.3.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-4K3bqJpXpqfg2XKGK9bpDTc6xO/xoUP/RBWS7AtRMug6zZFaRekiLzjVtAoZMquxoAbzBvy5nxQ7veS5eYzf8A=="],
38
+
39
+ "bun-types": ["bun-types@1.3.9", "", { "dependencies": { "@types/node": "*" } }, "sha512-+UBWWOakIP4Tswh0Bt0QD0alpTY8cb5hvgiYeWCMet9YukHbzuruIEeXC2D7nMJPB12kbh8C7XJykSexEqGKJg=="],
40
+
41
+ "cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="],
42
+
43
+ "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
44
+
45
+ "elysia": ["elysia@1.4.25", "", { "dependencies": { "cookie": "^1.1.1", "exact-mirror": "^0.2.7", "fast-decode-uri-component": "^1.0.1", "memoirist": "^0.4.0" }, "peerDependencies": { "@sinclair/typebox": ">= 0.34.0 < 1", "@types/bun": ">= 1.2.0", "file-type": ">= 20.0.0", "openapi-types": ">= 12.0.0", "typescript": ">= 5.0.0" }, "optionalPeers": ["@types/bun", "typescript"] }, "sha512-liKjavH99Gpzrv9cDil6uYWmPuqESfPFV1FIaFSd3iNqo3y7e29sN43VxFIK8tWWnyi6eDAmi2SZk8hNAMQMyg=="],
46
+
47
+ "exact-mirror": ["exact-mirror@0.2.7", "", { "peerDependencies": { "@sinclair/typebox": "^0.34.15" }, "optionalPeers": ["@sinclair/typebox"] }, "sha512-+MeEmDcLA4o/vjK2zujgk+1VTxPR4hdp23qLqkWfStbECtAq9gmsvQa3LW6z/0GXZyHJobrCnmy1cdeE7BjsYg=="],
48
+
49
+ "fast-decode-uri-component": ["fast-decode-uri-component@1.0.1", "", {}, "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg=="],
50
+
51
+ "file-type": ["file-type@21.3.0", "", { "dependencies": { "@tokenizer/inflate": "^0.4.1", "strtok3": "^10.3.4", "token-types": "^6.1.1", "uint8array-extras": "^1.4.0" } }, "sha512-8kPJMIGz1Yt/aPEwOsrR97ZyZaD1Iqm8PClb1nYFclUCkBi0Ma5IsYNQzvSFS9ib51lWyIw5mIT9rWzI/xjpzA=="],
52
+
53
+ "ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
54
+
55
+ "leanmcp": ["leanmcp@link:leanmcp", {}],
56
+
57
+ "memoirist": ["memoirist@0.4.0", "", {}, "sha512-zxTgA0mSYELa66DimuNQDvyLq36AwDlTuVRbnQtB+VuTcKWm5Qc4z3WkSpgsFWHNhexqkIooqpv4hdcqrX5Nmg=="],
58
+
59
+ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
60
+
61
+ "openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="],
62
+
63
+ "strtok3": ["strtok3@10.3.4", "", { "dependencies": { "@tokenizer/token": "^0.3.0" } }, "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg=="],
64
+
65
+ "token-types": ["token-types@6.1.2", "", { "dependencies": { "@borewit/text-codec": "^0.2.1", "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww=="],
66
+
67
+ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
68
+
69
+ "uint8array-extras": ["uint8array-extras@1.5.0", "", {}, "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A=="],
70
+
71
+ "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="],
72
+
73
+ "zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="],
74
+ }
75
+ }
@@ -0,0 +1,125 @@
1
+ import { Elysia } from 'elysia'
2
+ import cors from '@elysiajs/cors'
3
+ import {
4
+ type CallToolResult,
5
+ type JSONRPCErrorResponse,
6
+ type ToolDefinitionGeneric,
7
+ type ToolSet,
8
+ type JSONRPCResponse,
9
+ ToolDefinition,
10
+ } from 'leanmcp/types'
11
+ import { treaty } from '@elysiajs/eden';
12
+ import {
13
+ MCPServerService,
14
+ elysiaJsonRPC
15
+ } from 'leanmcp';
16
+
17
+ export const Tool1 = ToolDefinition(
18
+ "tool_name_1",
19
+ "this tool is a test tool 1",
20
+ [
21
+ {
22
+ name: "arg1",
23
+ description: "describing arg1",
24
+ type: "string",
25
+ required: false,
26
+ },
27
+ ] as const,
28
+ )(async (
29
+ _reference: object,
30
+ arg_string: string,
31
+ _extra?: any,
32
+ ): Promise<CallToolResult> => {
33
+ return {
34
+ content: [
35
+ {
36
+ type: "text",
37
+ text: arg_string,
38
+ },
39
+ ],
40
+ };
41
+ });
42
+
43
+ export const Tool2 = ToolDefinition(
44
+ "tool_name_2",
45
+ "this tool is a test tool 2",
46
+ [
47
+ {
48
+ name: "arg1",
49
+ description: "describing arg1",
50
+ type: "string",
51
+ required: false,
52
+ },
53
+ {
54
+ name: "arg2",
55
+ description: "describing arg2",
56
+ type: "boolean",
57
+ required: false,
58
+ },
59
+ ] as const,
60
+ )(async (
61
+ _reference: any,
62
+ arg1: string,
63
+ arg2: boolean,
64
+ _extra?: any,
65
+ ): Promise<CallToolResult> => {
66
+ throw new Error("this always fails");
67
+ });
68
+
69
+ export class TestToolSet implements ToolSet {
70
+ getTools(): ToolDefinitionGeneric[] {
71
+ return [Tool1, Tool2];
72
+ }
73
+ getTool(toolName: string): ToolDefinitionGeneric | undefined {
74
+ return this.getTools().find(x => x.name == toolName);
75
+ }
76
+ }
77
+
78
+
79
+ const serverService = new MCPServerService(
80
+ "testServerTitle",
81
+ "1.0.0",
82
+ "No instructions",
83
+ (toolName: string) => {
84
+ return serverService;
85
+ },
86
+ [new TestToolSet()],
87
+ );
88
+
89
+ export const app = new Elysia().use(cors({
90
+ origin: "*",
91
+ methods: ["GET", "POST", "OPTIONS"],
92
+ allowedHeaders: [
93
+ "Content-Type",
94
+ "Authorization",
95
+ "mcp-protocol-version",
96
+ "mcp-session-id",
97
+ ]
98
+ })).use(elysiaJsonRPC({
99
+ debug: true,
100
+ dns_rebind_origin: undefined,
101
+ service: serverService,
102
+ onError: (res: JSONRPCErrorResponse) => {
103
+ // console.log("onError", res.error.data);
104
+ },
105
+ onResponse: (res: any) => {
106
+ // console.log("onResponse");
107
+ },
108
+ onRequest: (res: any) => {
109
+ // console.log("onRequest");
110
+ },
111
+ }));
112
+
113
+ const client = treaty<typeof app>(app);
114
+ const resp = await client["stream"].post({
115
+ id: "1",
116
+ jsonrpc: "2.0",
117
+ method: "tools/list",
118
+ });
119
+
120
+ const response = resp.data as JSONRPCResponse;
121
+ if (response.id == "1" && response.jsonrpc == "2.0" && response.result) {
122
+ console.log("works!")
123
+ } else {
124
+ console.error("failed!")
125
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "test_leanmcp",
3
+ "module": "index.ts",
4
+ "type": "module",
5
+ "private": true,
6
+ "devDependencies": {
7
+ "@types/bun": "latest"
8
+ },
9
+ "peerDependencies": {
10
+ "typescript": "^5"
11
+ },
12
+ "dependencies": {
13
+ "@elysiajs/cors": "^1.4.1",
14
+ "@elysiajs/eden": "^1.4.8",
15
+ "elysia": "^1.4.25",
16
+ "leanmcp": "link:leanmcp",
17
+ "zod": "^4.3.6"
18
+ }
19
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "compilerOptions": {
3
+ // Environment setup & latest features
4
+ "lib": ["ESNext"],
5
+ "target": "ESNext",
6
+ "module": "Preserve",
7
+ "moduleDetection": "force",
8
+ "jsx": "react-jsx",
9
+ "allowJs": true,
10
+
11
+ // Bundler mode
12
+ "moduleResolution": "bundler",
13
+ "allowImportingTsExtensions": true,
14
+ "verbatimModuleSyntax": true,
15
+ "noEmit": true,
16
+
17
+ // Best practices
18
+ "strict": true,
19
+ "skipLibCheck": true,
20
+ "noFallthroughCasesInSwitch": true,
21
+ "noUncheckedIndexedAccess": true,
22
+ "noImplicitOverride": true,
23
+
24
+ // Some stricter flags (disabled by default)
25
+ "noUnusedLocals": false,
26
+ "noUnusedParameters": false,
27
+ "noPropertyAccessFromIndexSignature": false
28
+ }
29
+ }
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "kleanmcp",
3
+ "type": "module",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://github.com/zeilenschubser/kleanmcp.git"
7
+ },
8
+ "version": "1.0.1",
9
+ "license": "SEE LICENSE IN ./LICENSE",
10
+ "main": "./dist/index.cjs",
11
+ "module": "./dist/index.mjs",
12
+ "types": "./dist/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.mjs",
17
+ "require": "./dist/index.mjs"
18
+ },
19
+ "./types": {
20
+ "types": "./dist/types.d.ts",
21
+ "import": "./dist/types.mjs",
22
+ "require": "./dist/types.mjs"
23
+ }
24
+ },
25
+ "scripts": {
26
+ "build": "bun build.ts"
27
+ },
28
+ "devDependencies": {
29
+ "@types/bun": "latest"
30
+ },
31
+ "dependencies": {
32
+ "elysia-jsonrpc": "1.0.50",
33
+ "elysia": "^1.4.25",
34
+ "zod": "^4.3.6"
35
+ },
36
+ "peerDependencies": {
37
+ "typescript": "^5"
38
+ }
39
+ }
package/src/index.ts ADDED
@@ -0,0 +1,131 @@
1
+
2
+ import {
3
+ InputSchemaFromParameters,
4
+ ToolArgsToParameterList,
5
+ type CallToolResult,
6
+ type Tool,
7
+ type ToolDefinitionGeneric,
8
+ type ToolSet
9
+ } from "./types";
10
+
11
+ import {
12
+ MCPError,
13
+ type InitializeParams,
14
+ type InitializeResult,
15
+ type MCPServerInterface,
16
+ type PingParams,
17
+ type PingResult,
18
+ type PromptsGetParams,
19
+ type PromptsGetResult,
20
+ type PromptsListParams,
21
+ type PromptsListResult,
22
+ type ResourcesListParams,
23
+ type ResourcesListResult,
24
+ type ResourcesReadParams,
25
+ type ResourcesReadResult,
26
+ type ResourcesSubscribeParams,
27
+ type ResourcesSubscribeResult,
28
+ type ResourcesTemplatesListParams,
29
+ type ResourcesTemplatesListResult,
30
+ type ToolsCallParams,
31
+ type ToolsCallResult,
32
+ type ToolsListParams,
33
+ type ToolsListResult,
34
+ } from "elysia-jsonrpc/mcp";
35
+
36
+ import elysiaJsonRPC from "elysia-jsonrpc";
37
+ export { elysiaJsonRPC };
38
+
39
+ export type ReferenceForToolCallFunction = (toolName: string) => any;
40
+
41
+ export class MCPServerService implements MCPServerInterface {
42
+ constructor(
43
+ readonly serverTitle: string,
44
+ readonly serverVersion: string,
45
+ readonly serverInstructions: string,
46
+ readonly getReferenceInstanceForToolCall: ReferenceForToolCallFunction,
47
+ readonly toolsets: ToolSet[],
48
+ ) {}
49
+ initialize(params: InitializeParams): Promise<InitializeResult> {
50
+ return Promise.resolve({
51
+ capabilities: {
52
+ tools: {},
53
+ },
54
+ serverInfo: {
55
+ name: this.serverTitle,
56
+ version: this.serverVersion,
57
+ },
58
+ protocolVersion: "2025-11-25",
59
+ instructions: this.serverInstructions,
60
+ } as InitializeResult);
61
+ }
62
+ ping(params: PingParams): Promise<PingResult> {
63
+ return Promise.resolve({} as PingResult);
64
+ }
65
+ "tools/list"(params: ToolsListParams): Promise<ToolsListResult> {
66
+ return Promise.resolve({
67
+ tools: this.toolsets.flatMap((toolset: ToolSet): Tool[] => {
68
+ return toolset.getTools().map((tool: ToolDefinitionGeneric): Tool => {
69
+ return {
70
+ name: tool.name,
71
+ description: tool.description,
72
+ inputSchema: InputSchemaFromParameters(
73
+ tool.params,
74
+ )
75
+ }
76
+ });
77
+ })
78
+ } as ToolsListResult);
79
+ }
80
+
81
+ getTool(toolName: string): ToolDefinitionGeneric | null {
82
+ for (const toolset of this.toolsets) {
83
+ const maybeTool = toolset.getTool(toolName);
84
+ if (maybeTool) return maybeTool;
85
+ }
86
+ return null;
87
+ }
88
+
89
+ async "tools/call"(params: ToolsCallParams): Promise<ToolsCallResult> {
90
+ const toolName: string = params.name;
91
+ const toolArgs: any = params.arguments || {};
92
+ const tool = this.getTool(toolName);
93
+ if (!tool) throw new MCPError("Tool not found!", { toolName: toolName });
94
+ const referenceInstance = this.getReferenceInstanceForToolCall(toolName);
95
+ const result: CallToolResult = await tool.callback(
96
+ referenceInstance,
97
+ ...ToolArgsToParameterList(toolArgs, tool.params),
98
+ {},
99
+ );
100
+ return ((result: CallToolResult) => {toolArgs
101
+ return {
102
+ toolUseId: "",
103
+ content: result.content,
104
+ type: "tool_result",
105
+ isError: result.isError || false,
106
+ } as ToolsCallResult;
107
+ })(result);
108
+ }
109
+ "prompts/list"(params: PromptsListParams): Promise<PromptsListResult> {
110
+ throw new Error("Method not implemented.");
111
+ }
112
+ "prompts/get"(params: PromptsGetParams): Promise<PromptsGetResult> {
113
+ throw new Error("Method not implemented.");
114
+ }
115
+ "resources/list"(params: ResourcesListParams): Promise<ResourcesListResult> {
116
+ throw new Error("Method not implemented.");
117
+ }
118
+ "resources/read"(params: ResourcesReadParams): Promise<ResourcesReadResult> {
119
+ throw new Error("Method not implemented.");
120
+ }
121
+ "resources/subscribe"(
122
+ params: ResourcesSubscribeParams,
123
+ ): Promise<ResourcesSubscribeResult> {
124
+ throw new Error("Method not implemented.");
125
+ }
126
+ "resources/templates/list"(
127
+ params: ResourcesTemplatesListParams,
128
+ ): Promise<ResourcesTemplatesListResult> {
129
+ throw new Error("Method not implemented.");
130
+ }
131
+ }