lit-forge-mcp 0.1.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.
Files changed (42) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +87 -0
  3. package/dist/index.d.ts +2 -0
  4. package/dist/index.js +26 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/tools/convert-base64.d.ts +2 -0
  7. package/dist/tools/convert-base64.js +38 -0
  8. package/dist/tools/convert-base64.js.map +1 -0
  9. package/dist/tools/convert-timestamp.d.ts +2 -0
  10. package/dist/tools/convert-timestamp.js +52 -0
  11. package/dist/tools/convert-timestamp.js.map +1 -0
  12. package/dist/tools/convert-url.d.ts +2 -0
  13. package/dist/tools/convert-url.js +33 -0
  14. package/dist/tools/convert-url.js.map +1 -0
  15. package/dist/tools/convert-yaml-json.d.ts +2 -0
  16. package/dist/tools/convert-yaml-json.js +46 -0
  17. package/dist/tools/convert-yaml-json.js.map +1 -0
  18. package/dist/tools/decode-jwt.d.ts +2 -0
  19. package/dist/tools/decode-jwt.js +56 -0
  20. package/dist/tools/decode-jwt.js.map +1 -0
  21. package/dist/tools/describe-cron.d.ts +2 -0
  22. package/dist/tools/describe-cron.js +63 -0
  23. package/dist/tools/describe-cron.js.map +1 -0
  24. package/dist/tools/format-json.d.ts +2 -0
  25. package/dist/tools/format-json.js +37 -0
  26. package/dist/tools/format-json.js.map +1 -0
  27. package/dist/tools/generate-hash.d.ts +2 -0
  28. package/dist/tools/generate-hash.js +29 -0
  29. package/dist/tools/generate-hash.js.map +1 -0
  30. package/dist/tools/generate-uuid.d.ts +2 -0
  31. package/dist/tools/generate-uuid.js +41 -0
  32. package/dist/tools/generate-uuid.js.map +1 -0
  33. package/dist/tools/index.d.ts +1 -0
  34. package/dist/tools/index.js +24 -0
  35. package/dist/tools/index.js.map +1 -0
  36. package/dist/tools/test-regex.d.ts +2 -0
  37. package/dist/tools/test-regex.js +54 -0
  38. package/dist/tools/test-regex.js.map +1 -0
  39. package/dist/tools/types.d.ts +11 -0
  40. package/dist/tools/types.js +21 -0
  41. package/dist/tools/types.js.map +1 -0
  42. package/package.json +55 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 lit-forge
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # lit-forge MCP server
2
+
3
+ [lit-forge.com](https://lit-forge.com) の開発者向けユーティリティを Model Context Protocol(MCP)経由で AI から直接呼び出せるようにする stdio サーバーです。
4
+
5
+ Claude Desktop / Claude Code / Cursor など、MCP に対応した任意の AI クライアントで動作します。
6
+
7
+ ## 提供ツール(10 種)
8
+
9
+ | ツール名 | 説明 |
10
+ |---|---|
11
+ | `format_json` | JSON 整形(pretty)/ 圧縮(minify) |
12
+ | `test_regex` | 正規表現マッチ(JavaScript 互換、フラグ指定可、名前付きグループ対応) |
13
+ | `decode_jwt` | JWT を Header / Payload / Signature に分解(exp/nbf/iat の人間可読化と有効期限判定つき) |
14
+ | `convert_base64` | Base64 エンコード/デコード(UTF-8 / URL-safe 対応) |
15
+ | `convert_url` | URL パーセントエンコード/デコード(component / URI 切替) |
16
+ | `generate_hash` | MD5 / SHA-1 / SHA-256 / SHA-384 / SHA-512(hex / base64) |
17
+ | `generate_uuid` | UUID v4 / v7 を最大 100 件まで一括生成 |
18
+ | `convert_timestamp` | Unix 時刻 ⇔ ISO 8601 日時(秒/ミリ秒切替) |
19
+ | `convert_yaml_json` | YAML ⇔ JSON 相互変換(js-yaml) |
20
+ | `describe_cron` | cron 式を人間可読化 + 次回実行時刻を計算(IANA タイムゾーン対応) |
21
+
22
+ すべて純関数(外部 API 不要・状態を持たない)で動作します。AI が出力した JSON を整形したり、JWT をデバッグしたり、UUID をテストデータとして大量生成したりするのに便利です。
23
+
24
+ ## インストール / 設定
25
+
26
+ ### Claude Desktop の場合
27
+
28
+ `claude_desktop_config.json` に以下を追加します。
29
+
30
+ ```json
31
+ {
32
+ "mcpServers": {
33
+ "lit-forge": {
34
+ "command": "npx",
35
+ "args": ["-y", "lit-forge-mcp"]
36
+ }
37
+ }
38
+ }
39
+ ```
40
+
41
+ 設定ファイルの場所:
42
+ - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
43
+ - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
44
+
45
+ ### Claude Code の場合
46
+
47
+ ```bash
48
+ claude mcp add lit-forge -- npx -y lit-forge-mcp
49
+ ```
50
+
51
+ ### Cursor の場合
52
+
53
+ `~/.cursor/mcp.json`(または プロジェクト直下の `.cursor/mcp.json`)に同じ JSON を追加します。
54
+
55
+ ## ローカル開発
56
+
57
+ ```bash
58
+ git clone https://github.com/nobuoseki/lit-forge.git
59
+ cd lit-forge/mcp-server
60
+ npm install
61
+ npm run build
62
+ node dist/index.js # stdio で起動
63
+ ```
64
+
65
+ ### 動作確認
66
+
67
+ ```bash
68
+ echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"smoke","version":"0.0.1"}}}
69
+ {"jsonrpc":"2.0","method":"notifications/initialized"}
70
+ {"jsonrpc":"2.0","id":2,"method":"tools/list"}' | node dist/index.js
71
+ ```
72
+
73
+ `tools/list` のレスポンスに 10 ツールが並べば成功です。
74
+
75
+ ## 使用例
76
+
77
+ Claude にこんな依頼ができます:
78
+
79
+ - 「この JWT をデコードして payload の中身を見せて」
80
+ - 「`name: foo\nlist: [1,2,3]` を JSON にして」
81
+ - 「`0 9 * * 1-5` を日本語で説明して、次の 5 回の実行時刻も Asia/Tokyo で出して」
82
+ - 「テストデータ用に UUID v7 を 20 個生成して」
83
+ - 「`(\\w+)@(\\w+)` でメールアドレスをパースしたいんだけど、`alice@example.com bob@test.jp` で試して」
84
+
85
+ ## ライセンス
86
+
87
+ MIT
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env node
2
+ // lit-forge MCP server エントリポイント。stdio で起動し、10 ツールを登録する。
3
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
+ import { tools } from "./tools/index.js";
6
+ const server = new McpServer({
7
+ name: "lit-forge",
8
+ version: "0.1.0",
9
+ });
10
+ for (const tool of tools) {
11
+ server.registerTool(tool.name, {
12
+ title: tool.title,
13
+ description: tool.description,
14
+ inputSchema: tool.inputSchema,
15
+ }, tool.handler);
16
+ }
17
+ async function main() {
18
+ const transport = new StdioServerTransport();
19
+ await server.connect(transport);
20
+ console.error(`lit-forge MCP server running on stdio (${tools.length} tools)`);
21
+ }
22
+ main().catch((err) => {
23
+ console.error("Fatal error:", err);
24
+ process.exit(1);
25
+ });
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,wDAAwD;AAExD,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEzC,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,WAAW;IACjB,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;IACzB,MAAM,CAAC,YAAY,CACjB,IAAI,CAAC,IAAI,EACT;QACE,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,WAAW,EAAE,IAAI,CAAC,WAAW;KAC9B,EACD,IAAI,CAAC,OAAO,CACb,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,0CAA0C,KAAK,CAAC,MAAM,SAAS,CAAC,CAAC;AACjF,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;IACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { type LitForgeTool } from "./types.js";
2
+ export declare const convertBase64: LitForgeTool;
@@ -0,0 +1,38 @@
1
+ // Base64 エンコード / デコード。UTF-8 と URL-safe Base64 に対応。
2
+ import { z } from "zod";
3
+ import { errorReply, jsonReply } from "./types.js";
4
+ const inputSchema = {
5
+ text: z.string().describe("変換対象のテキスト"),
6
+ mode: z.enum(["encode", "decode"]).describe("encode: テキスト→Base64 / decode: Base64→テキスト"),
7
+ urlSafe: z
8
+ .boolean()
9
+ .default(false)
10
+ .describe("URL-safe Base64(+/= を -_ に置換、パディングなし)を使うか"),
11
+ };
12
+ export const convertBase64 = {
13
+ name: "convert_base64",
14
+ title: "Base64 変換",
15
+ description: "テキストと Base64 を相互変換します。UTF-8 で扱い、URL-safe Base64 にも対応します。",
16
+ inputSchema,
17
+ handler: ({ text, mode, urlSafe }) => {
18
+ if (mode === "encode") {
19
+ const b64 = Buffer.from(text, "utf8").toString("base64");
20
+ const result = urlSafe
21
+ ? b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "")
22
+ : b64;
23
+ return jsonReply({ result });
24
+ }
25
+ try {
26
+ const normalized = urlSafe
27
+ ? text.replace(/-/g, "+").replace(/_/g, "/")
28
+ : text;
29
+ const padded = normalized + "=".repeat((4 - (normalized.length % 4)) % 4);
30
+ const result = Buffer.from(padded, "base64").toString("utf8");
31
+ return jsonReply({ result });
32
+ }
33
+ catch (e) {
34
+ return errorReply(`Base64 デコードに失敗: ${e instanceof Error ? e.message : String(e)}`);
35
+ }
36
+ },
37
+ };
38
+ //# sourceMappingURL=convert-base64.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convert-base64.js","sourceRoot":"","sources":["../../src/tools/convert-base64.ts"],"names":[],"mappings":"AAAA,mDAAmD;AAEnD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAqB,MAAM,YAAY,CAAC;AAEtE,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;IACtC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,2CAA2C,CAAC;IACxF,OAAO,EAAE,CAAC;SACP,OAAO,EAAE;SACT,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CAAC,2CAA2C,CAAC;CACzD,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAiB;IACzC,IAAI,EAAE,gBAAgB;IACtB,KAAK,EAAE,WAAW;IAClB,WAAW,EACT,0DAA0D;IAC5D,WAAW;IACX,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE;QACnC,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtB,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACzD,MAAM,MAAM,GAAG,OAAO;gBACpB,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;gBAChE,CAAC,CAAC,GAAG,CAAC;YACR,OAAO,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QAC/B,CAAC;QACD,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,OAAO;gBACxB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC;gBAC5C,CAAC,CAAC,IAAI,CAAC;YACT,MAAM,MAAM,GACV,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC7D,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC9D,OAAO,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,UAAU,CACf,mBAAmB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAChE,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { type LitForgeTool } from "./types.js";
2
+ export declare const convertTimestamp: LitForgeTool;
@@ -0,0 +1,52 @@
1
+ // Unix タイムスタンプと ISO 日時を相互変換。
2
+ import { z } from "zod";
3
+ import { errorReply, jsonReply } from "./types.js";
4
+ const inputSchema = {
5
+ value: z
6
+ .string()
7
+ .describe("変換する値。to_iso なら数値文字列、to_unix なら ISO 日時"),
8
+ mode: z
9
+ .enum(["to_iso", "to_unix"])
10
+ .describe("to_iso: Unix→ISO / to_unix: ISO→Unix"),
11
+ unit: z
12
+ .enum(["seconds", "milliseconds"])
13
+ .default("seconds")
14
+ .describe("Unix 時刻の単位(既定 seconds)"),
15
+ };
16
+ export const convertTimestamp = {
17
+ name: "convert_timestamp",
18
+ title: "タイムスタンプ変換",
19
+ description: "Unix タイムスタンプ(秒またはミリ秒)と ISO 8601 日時を相互変換します。タイムゾーンは UTC で扱います。",
20
+ inputSchema,
21
+ handler: ({ value, mode, unit }) => {
22
+ if (mode === "to_iso") {
23
+ const num = Number(value);
24
+ if (!Number.isFinite(num)) {
25
+ return errorReply(`数値として解釈できません: ${value}`);
26
+ }
27
+ const ms = unit === "seconds" ? num * 1000 : num;
28
+ const date = new Date(ms);
29
+ if (Number.isNaN(date.getTime())) {
30
+ return errorReply(`日時として解釈できません: ${value}`);
31
+ }
32
+ return jsonReply({
33
+ iso: date.toISOString(),
34
+ utc: date.toUTCString(),
35
+ unix: unit === "seconds" ? num : Math.floor(num / 1000),
36
+ unixMs: ms,
37
+ });
38
+ }
39
+ const date = new Date(value);
40
+ if (Number.isNaN(date.getTime())) {
41
+ return errorReply(`ISO 日時として解釈できません: ${value}`);
42
+ }
43
+ const unix = Math.floor(date.getTime() / 1000);
44
+ return jsonReply({
45
+ unix,
46
+ unixMs: date.getTime(),
47
+ iso: date.toISOString(),
48
+ result: unit === "seconds" ? unix : date.getTime(),
49
+ });
50
+ },
51
+ };
52
+ //# sourceMappingURL=convert-timestamp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convert-timestamp.js","sourceRoot":"","sources":["../../src/tools/convert-timestamp.ts"],"names":[],"mappings":"AAAA,6BAA6B;AAE7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAqB,MAAM,YAAY,CAAC;AAEtE,MAAM,WAAW,GAAG;IAClB,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,QAAQ,CAAC,wCAAwC,CAAC;IACrD,IAAI,EAAE,CAAC;SACJ,IAAI,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;SAC3B,QAAQ,CAAC,sCAAsC,CAAC;IACnD,IAAI,EAAE,CAAC;SACJ,IAAI,CAAC,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;SACjC,OAAO,CAAC,SAAS,CAAC;SAClB,QAAQ,CAAC,wBAAwB,CAAC;CACtC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAiB;IAC5C,IAAI,EAAE,mBAAmB;IACzB,KAAK,EAAE,WAAW;IAClB,WAAW,EACT,+DAA+D;IACjE,WAAW;IACX,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE;QACjC,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtB,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YAC1B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1B,OAAO,UAAU,CAAC,iBAAiB,KAAK,EAAE,CAAC,CAAC;YAC9C,CAAC;YACD,MAAM,EAAE,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;YACjD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC;YAC1B,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;gBACjC,OAAO,UAAU,CAAC,iBAAiB,KAAK,EAAE,CAAC,CAAC;YAC9C,CAAC;YACD,OAAO,SAAS,CAAC;gBACf,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE;gBACvB,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE;gBACvB,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC;gBACvD,MAAM,EAAE,EAAE;aACX,CAAC,CAAC;QACL,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;YACjC,OAAO,UAAU,CAAC,qBAAqB,KAAK,EAAE,CAAC,CAAC;QAClD,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;QAC/C,OAAO,SAAS,CAAC;YACf,IAAI;YACJ,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE;YACtB,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE;YACvB,MAAM,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE;SACnD,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { type LitForgeTool } from "./types.js";
2
+ export declare const convertUrl: LitForgeTool;
@@ -0,0 +1,33 @@
1
+ // URL エンコード / デコード(パーセントエンコード)。
2
+ import { z } from "zod";
3
+ import { errorReply, jsonReply } from "./types.js";
4
+ const inputSchema = {
5
+ text: z.string().describe("変換対象のテキスト"),
6
+ mode: z
7
+ .enum(["encode", "decode"])
8
+ .describe("encode: テキスト→%xx / decode: %xx→テキスト"),
9
+ component: z
10
+ .boolean()
11
+ .default(true)
12
+ .describe("true: encodeURIComponent / false: encodeURI を使う(既定 true)"),
13
+ };
14
+ export const convertUrl = {
15
+ name: "convert_url",
16
+ title: "URL エンコード / デコード",
17
+ description: "テキストをパーセントエンコード(%xx)でエンコード/デコードします。component=true(既定)は予約文字も含めて全エスケープします。",
18
+ inputSchema,
19
+ handler: ({ text, mode, component }) => {
20
+ try {
21
+ if (mode === "encode") {
22
+ const result = component ? encodeURIComponent(text) : encodeURI(text);
23
+ return jsonReply({ result });
24
+ }
25
+ const result = component ? decodeURIComponent(text) : decodeURI(text);
26
+ return jsonReply({ result });
27
+ }
28
+ catch (e) {
29
+ return errorReply(`URL ${mode === "encode" ? "エンコード" : "デコード"}に失敗: ${e instanceof Error ? e.message : String(e)}`);
30
+ }
31
+ },
32
+ };
33
+ //# sourceMappingURL=convert-url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convert-url.js","sourceRoot":"","sources":["../../src/tools/convert-url.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAEhC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAqB,MAAM,YAAY,CAAC;AAEtE,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;IACtC,IAAI,EAAE,CAAC;SACJ,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;SAC1B,QAAQ,CAAC,qCAAqC,CAAC;IAClD,SAAS,EAAE,CAAC;SACT,OAAO,EAAE;SACT,OAAO,CAAC,IAAI,CAAC;SACb,QAAQ,CAAC,0DAA0D,CAAC;CACxE,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAiB;IACtC,IAAI,EAAE,aAAa;IACnB,KAAK,EAAE,kBAAkB;IACzB,WAAW,EACT,0EAA0E;IAC5E,WAAW;IACX,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE;QACrC,IAAI,CAAC;YACH,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtB,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;gBACtE,OAAO,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;YAC/B,CAAC;YACD,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YACtE,OAAO,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,UAAU,CACf,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,QACzC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAC3C,EAAE,CACH,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { type LitForgeTool } from "./types.js";
2
+ export declare const convertYamlJson: LitForgeTool;
@@ -0,0 +1,46 @@
1
+ // YAML ⇔ JSON 相互変換。
2
+ import yaml from "js-yaml";
3
+ import { z } from "zod";
4
+ import { errorReply, jsonReply } from "./types.js";
5
+ const inputSchema = {
6
+ text: z.string().describe("変換元のテキスト"),
7
+ mode: z
8
+ .enum(["yaml_to_json", "json_to_yaml"])
9
+ .describe("yaml_to_json: YAML→JSON / json_to_yaml: JSON→YAML"),
10
+ indent: z
11
+ .number()
12
+ .int()
13
+ .min(0)
14
+ .max(8)
15
+ .default(2)
16
+ .describe("出力のインデント幅(YAML/JSON 共通、0〜8)"),
17
+ };
18
+ export const convertYamlJson = {
19
+ name: "convert_yaml_json",
20
+ title: "YAML ⇔ JSON 変換",
21
+ description: "YAML と JSON を相互変換します。YAML は js-yaml に準拠、JSON は標準 JSON.stringify を使います。",
22
+ inputSchema,
23
+ handler: ({ text, mode, indent }) => {
24
+ const trimmed = text.trim();
25
+ if (!trimmed)
26
+ return jsonReply({ result: "" });
27
+ try {
28
+ if (mode === "yaml_to_json") {
29
+ const obj = yaml.load(trimmed);
30
+ return jsonReply({ result: JSON.stringify(obj, null, indent) });
31
+ }
32
+ const obj = JSON.parse(trimmed);
33
+ const result = yaml.dump(obj, {
34
+ indent,
35
+ sortKeys: false,
36
+ lineWidth: -1,
37
+ noRefs: true,
38
+ });
39
+ return jsonReply({ result });
40
+ }
41
+ catch (e) {
42
+ return errorReply(`${mode === "yaml_to_json" ? "YAML" : "JSON"} のパースに失敗: ${e instanceof Error ? e.message : String(e)}`);
43
+ }
44
+ },
45
+ };
46
+ //# sourceMappingURL=convert-yaml-json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convert-yaml-json.js","sourceRoot":"","sources":["../../src/tools/convert-yaml-json.ts"],"names":[],"mappings":"AAAA,oBAAoB;AAEpB,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAqB,MAAM,YAAY,CAAC;AAEtE,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;IACrC,IAAI,EAAE,CAAC;SACJ,IAAI,CAAC,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;SACtC,QAAQ,CAAC,mDAAmD,CAAC;IAChE,MAAM,EAAE,CAAC;SACN,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,CAAC,CAAC;SACN,OAAO,CAAC,CAAC,CAAC;SACV,QAAQ,CAAC,6BAA6B,CAAC;CAC3C,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAiB;IAC3C,IAAI,EAAE,mBAAmB;IACzB,KAAK,EAAE,gBAAgB;IACvB,WAAW,EACT,wEAAwE;IAC1E,WAAW;IACX,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;QAClC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO;YAAE,OAAO,SAAS,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;QAE/C,IAAI,CAAC;YACH,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;gBAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAC/B,OAAO,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;YAClE,CAAC;YACD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAChC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;gBAC5B,MAAM;gBACN,QAAQ,EAAE,KAAK;gBACf,SAAS,EAAE,CAAC,CAAC;gBACb,MAAM,EAAE,IAAI;aACb,CAAC,CAAC;YACH,OAAO,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,UAAU,CACf,GAAG,IAAI,KAAK,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,aAC1C,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAC3C,EAAE,CACH,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { type LitForgeTool } from "./types.js";
2
+ export declare const decodeJwt: LitForgeTool;
@@ -0,0 +1,56 @@
1
+ // JWT トークンを Header / Payload / Signature に分解してデコード。署名検証は行わない。
2
+ import { z } from "zod";
3
+ import { errorReply, jsonReply } from "./types.js";
4
+ const inputSchema = {
5
+ token: z.string().describe("JWT トークン全体(xxx.yyy.zzz 形式)"),
6
+ };
7
+ function base64UrlToObject(s) {
8
+ const base64 = s.replace(/-/g, "+").replace(/_/g, "/");
9
+ const padded = base64 + "=".repeat((4 - (base64.length % 4)) % 4);
10
+ const json = Buffer.from(padded, "base64").toString("utf8");
11
+ return JSON.parse(json);
12
+ }
13
+ export const decodeJwt = {
14
+ name: "decode_jwt",
15
+ title: "JWT デコード",
16
+ description: "JWT トークンを Header / Payload / Signature に分解してデコードします(署名検証は行いません)。exp / nbf / iat の人間可読時刻と有効期限切れ判定も付与します。",
17
+ inputSchema,
18
+ handler: ({ token }) => {
19
+ const parts = token.trim().split(".");
20
+ if (parts.length !== 3) {
21
+ return errorReply("JWT の形式が無効です(xxx.yyy.zzz の 3 パートが必要)");
22
+ }
23
+ let header;
24
+ let payload;
25
+ try {
26
+ header = base64UrlToObject(parts[0]);
27
+ }
28
+ catch (e) {
29
+ return errorReply(`Header のデコードに失敗: ${e instanceof Error ? e.message : String(e)}`);
30
+ }
31
+ try {
32
+ payload = base64UrlToObject(parts[1]);
33
+ }
34
+ catch (e) {
35
+ return errorReply(`Payload のデコードに失敗: ${e instanceof Error ? e.message : String(e)}`);
36
+ }
37
+ const p = payload;
38
+ const now = Math.floor(Date.now() / 1000);
39
+ const expired = typeof p.exp === "number" ? now > p.exp : false;
40
+ const claims = {};
41
+ for (const k of ["exp", "nbf", "iat"]) {
42
+ const v = p[k];
43
+ if (typeof v === "number") {
44
+ claims[`${k}Iso`] = new Date(v * 1000).toISOString();
45
+ }
46
+ }
47
+ return jsonReply({
48
+ header,
49
+ payload,
50
+ signature: parts[2],
51
+ expired,
52
+ ...claims,
53
+ });
54
+ },
55
+ };
56
+ //# sourceMappingURL=decode-jwt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decode-jwt.js","sourceRoot":"","sources":["../../src/tools/decode-jwt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { type LitForgeTool } from "./types.js";
2
+ export declare const describeCron: LitForgeTool;
@@ -0,0 +1,63 @@
1
+ // cron 式を人間可読な日本語/英語に変換し、次回実行時刻も計算。
2
+ import cronstrue from "cronstrue/i18n.js";
3
+ import { CronExpressionParser } from "cron-parser";
4
+ import { z } from "zod";
5
+ import { errorReply, jsonReply } from "./types.js";
6
+ const inputSchema = {
7
+ expression: z.string().describe("cron 式(5 フィールド or 6 フィールド)"),
8
+ locale: z
9
+ .enum(["ja", "en"])
10
+ .default("ja")
11
+ .describe("人間可読説明の言語(ja / en)"),
12
+ nextCount: z
13
+ .number()
14
+ .int()
15
+ .min(0)
16
+ .max(20)
17
+ .default(5)
18
+ .describe("計算する次回実行回数(0〜20)"),
19
+ timezone: z
20
+ .string()
21
+ .default("UTC")
22
+ .describe("タイムゾーン(IANA 形式、例: Asia/Tokyo)"),
23
+ };
24
+ export const describeCron = {
25
+ name: "describe_cron",
26
+ title: "cron 式の説明と次回実行時刻",
27
+ description: "cron 式を人間可読な文章に変換し、指定タイムゾーンでの次回実行時刻を計算します。標準 5 フィールド・6 フィールド(秒つき)に対応。",
28
+ inputSchema,
29
+ handler: ({ expression, locale, nextCount, timezone }) => {
30
+ let description;
31
+ try {
32
+ description = cronstrue.toString(expression, {
33
+ locale: locale,
34
+ });
35
+ }
36
+ catch (e) {
37
+ return errorReply(`cron 式の解釈に失敗: ${e instanceof Error ? e.message : String(e)}`);
38
+ }
39
+ const nextRuns = [];
40
+ if (nextCount > 0) {
41
+ try {
42
+ const interval = CronExpressionParser.parse(expression, {
43
+ tz: timezone,
44
+ });
45
+ for (let i = 0; i < nextCount; i++) {
46
+ const iso = interval.next().toISOString();
47
+ if (iso)
48
+ nextRuns.push(iso);
49
+ }
50
+ }
51
+ catch (e) {
52
+ return errorReply(`次回実行時刻の計算に失敗: ${e instanceof Error ? e.message : String(e)}`);
53
+ }
54
+ }
55
+ return jsonReply({
56
+ expression,
57
+ description,
58
+ timezone,
59
+ nextRuns,
60
+ });
61
+ },
62
+ };
63
+ //# sourceMappingURL=describe-cron.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"describe-cron.js","sourceRoot":"","sources":["../../src/tools/describe-cron.ts"],"names":[],"mappings":"AAAA,oCAAoC;AAEpC,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAqB,MAAM,YAAY,CAAC;AAEtE,MAAM,WAAW,GAAG;IAClB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;IAC7D,MAAM,EAAE,CAAC;SACN,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;SAClB,OAAO,CAAC,IAAI,CAAC;SACb,QAAQ,CAAC,oBAAoB,CAAC;IACjC,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,EAAE,CAAC;SACP,OAAO,CAAC,CAAC,CAAC;SACV,QAAQ,CAAC,kBAAkB,CAAC;IAC/B,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CAAC,+BAA+B,CAAC;CAC7C,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAiB;IACxC,IAAI,EAAE,eAAe;IACrB,KAAK,EAAE,kBAAkB;IACzB,WAAW,EACT,uEAAuE;IACzE,WAAW;IACX,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE;QACvD,IAAI,WAAmB,CAAC;QACxB,IAAI,CAAC;YACH,WAAW,GAAG,SAAS,CAAC,QAAQ,CAAC,UAAoB,EAAE;gBACrD,MAAM,EAAE,MAAgB;aACzB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,UAAU,CACf,iBAAiB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAC9D,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YAClB,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,oBAAoB,CAAC,KAAK,CAAC,UAAU,EAAE;oBACtD,EAAE,EAAE,QAAQ;iBACb,CAAC,CAAC;gBACH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;oBACnC,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;oBAC1C,IAAI,GAAG;wBAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAC9B,CAAC;YACH,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,UAAU,CACf,iBAAiB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAC9D,CAAC;YACJ,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;YACf,UAAU;YACV,WAAW;YACX,QAAQ;YACR,QAAQ;SACT,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { type LitForgeTool } from "./types.js";
2
+ export declare const formatJson: LitForgeTool;
@@ -0,0 +1,37 @@
1
+ // JSON 整形・圧縮・バリデーション。
2
+ import { z } from "zod";
3
+ import { errorReply, jsonReply } from "./types.js";
4
+ const inputSchema = {
5
+ text: z.string().describe("整形または圧縮する JSON 文字列"),
6
+ mode: z
7
+ .enum(["pretty", "minify"])
8
+ .default("pretty")
9
+ .describe("pretty: インデントあり / minify: 1 行に圧縮"),
10
+ indent: z
11
+ .number()
12
+ .int()
13
+ .min(0)
14
+ .max(8)
15
+ .default(2)
16
+ .describe("pretty 時のインデント幅(0〜8)"),
17
+ };
18
+ export const formatJson = {
19
+ name: "format_json",
20
+ title: "JSON 整形 / 圧縮",
21
+ description: "JSON 文字列を整形(pretty)または 1 行に圧縮(minify)します。構文エラーがあれば箇所と内容を返します。",
22
+ inputSchema,
23
+ handler: ({ text, mode, indent }) => {
24
+ let parsed;
25
+ try {
26
+ parsed = JSON.parse(text);
27
+ }
28
+ catch (e) {
29
+ return errorReply(`JSON 構文エラー: ${e instanceof Error ? e.message : String(e)}`);
30
+ }
31
+ const result = mode === "minify"
32
+ ? JSON.stringify(parsed)
33
+ : JSON.stringify(parsed, null, indent);
34
+ return jsonReply({ result, byteLength: Buffer.byteLength(result, "utf8") });
35
+ },
36
+ };
37
+ //# sourceMappingURL=format-json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-json.js","sourceRoot":"","sources":["../../src/tools/format-json.ts"],"names":[],"mappings":"AAAA,sBAAsB;AAEtB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAqB,MAAM,YAAY,CAAC;AAEtE,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;IAC/C,IAAI,EAAE,CAAC;SACJ,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;SAC1B,OAAO,CAAC,QAAQ,CAAC;SACjB,QAAQ,CAAC,kCAAkC,CAAC;IAC/C,MAAM,EAAE,CAAC;SACN,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,CAAC,CAAC;SACN,OAAO,CAAC,CAAC,CAAC;SACV,QAAQ,CAAC,sBAAsB,CAAC;CACpC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAiB;IACtC,IAAI,EAAE,aAAa;IACnB,KAAK,EAAE,cAAc;IACrB,WAAW,EACT,+DAA+D;IACjE,WAAW;IACX,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;QAClC,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,UAAU,CACf,eAAe,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAC5D,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GACV,IAAI,KAAK,QAAQ;YACf,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;YACxB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC3C,OAAO,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IAC9E,CAAC;CACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { type LitForgeTool } from "./types.js";
2
+ export declare const generateHash: LitForgeTool;
@@ -0,0 +1,29 @@
1
+ // 文字列のハッシュを生成。SHA-1/256/384/512 と MD5 をサポート。
2
+ import { createHash } from "node:crypto";
3
+ import { z } from "zod";
4
+ import { jsonReply } from "./types.js";
5
+ const ALGORITHMS = ["md5", "sha1", "sha256", "sha384", "sha512"];
6
+ const inputSchema = {
7
+ text: z.string().describe("ハッシュ化するテキスト(UTF-8)"),
8
+ algorithm: z
9
+ .enum(ALGORITHMS)
10
+ .default("sha256")
11
+ .describe("ハッシュアルゴリズム(既定 sha256)"),
12
+ encoding: z
13
+ .enum(["hex", "base64"])
14
+ .default("hex")
15
+ .describe("出力エンコーディング(hex / base64)"),
16
+ };
17
+ export const generateHash = {
18
+ name: "generate_hash",
19
+ title: "ハッシュ生成",
20
+ description: "テキストのハッシュ値を生成します(MD5 / SHA-1 / SHA-256 / SHA-384 / SHA-512)。MD5 と SHA-1 は互換性目的で残しており、新規用途は SHA-256 以上を推奨します。",
21
+ inputSchema,
22
+ handler: ({ text, algorithm, encoding }) => {
23
+ const result = createHash(algorithm)
24
+ .update(text, "utf8")
25
+ .digest(encoding);
26
+ return jsonReply({ algorithm, encoding, result });
27
+ },
28
+ };
29
+ //# sourceMappingURL=generate-hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-hash.js","sourceRoot":"","sources":["../../src/tools/generate-hash.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAE7C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,SAAS,EAAqB,MAAM,YAAY,CAAC;AAE1D,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAU,CAAC;AAE1E,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;IAC/C,SAAS,EAAE,CAAC;SACT,IAAI,CAAC,UAAU,CAAC;SAChB,OAAO,CAAC,QAAQ,CAAC;SACjB,QAAQ,CAAC,uBAAuB,CAAC;IACpC,QAAQ,EAAE,CAAC;SACR,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;SACvB,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CAAC,0BAA0B,CAAC;CACxC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAiB;IACxC,IAAI,EAAE,eAAe;IACrB,KAAK,EAAE,QAAQ;IACf,WAAW,EACT,8GAA8G;IAChH,WAAW;IACX,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE;QACzC,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC;aACjC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC;aACpB,MAAM,CAAC,QAAQ,CAAC,CAAC;QACpB,OAAO,SAAS,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IACpD,CAAC;CACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { type LitForgeTool } from "./types.js";
2
+ export declare const generateUuid: LitForgeTool;
@@ -0,0 +1,41 @@
1
+ // UUID v4 / v7 を最大 100 件まで一括生成。
2
+ import { randomUUID, randomBytes } from "node:crypto";
3
+ import { z } from "zod";
4
+ import { jsonReply } from "./types.js";
5
+ const inputSchema = {
6
+ version: z
7
+ .enum(["v4", "v7"])
8
+ .default("v4")
9
+ .describe("v4: 完全ランダム / v7: 先頭48bitが Unix ミリ秒で時刻順"),
10
+ count: z
11
+ .number()
12
+ .int()
13
+ .min(1)
14
+ .max(100)
15
+ .default(1)
16
+ .describe("生成件数(1〜100)"),
17
+ };
18
+ // v7: RFC 9562 準拠。先頭48ビットが Unix ミリ秒。
19
+ function generateV7() {
20
+ const unixMs = Date.now();
21
+ const tsHex = unixMs.toString(16).padStart(12, "0");
22
+ const rand = randomBytes(10);
23
+ // 上位4ビットをバージョン(0x7)に
24
+ rand[0] = (rand[0] & 0x0f) | 0x70;
25
+ // バリアントビットを RFC 4122 (10xx) に
26
+ rand[2] = (rand[2] & 0x3f) | 0x80;
27
+ const hex = rand.toString("hex");
28
+ return `${tsHex.slice(0, 8)}-${tsHex.slice(8, 12)}-${hex.slice(0, 4)}-${hex.slice(4, 8)}-${hex.slice(8, 20)}`;
29
+ }
30
+ export const generateUuid = {
31
+ name: "generate_uuid",
32
+ title: "UUID 生成",
33
+ description: "UUID v4(完全ランダム)または v7(時刻順ソート可能)を最大 100 件まで一括生成します。",
34
+ inputSchema,
35
+ handler: ({ version, count }) => {
36
+ const fn = version === "v4" ? () => randomUUID() : generateV7;
37
+ const uuids = Array.from({ length: count }, fn);
38
+ return jsonReply({ version, count, uuids });
39
+ },
40
+ };
41
+ //# sourceMappingURL=generate-uuid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-uuid.js","sourceRoot":"","sources":["../../src/tools/generate-uuid.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAEhC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,SAAS,EAAqB,MAAM,YAAY,CAAC;AAE1D,MAAM,WAAW,GAAG;IAClB,OAAO,EAAE,CAAC;SACP,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;SAClB,OAAO,CAAC,IAAI,CAAC;SACb,QAAQ,CAAC,wCAAwC,CAAC;IACrD,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,GAAG,CAAC;SACR,OAAO,CAAC,CAAC,CAAC;SACV,QAAQ,CAAC,aAAa,CAAC;CAC3B,CAAC;AAEF,qCAAqC;AACrC,SAAS,UAAU;IACjB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IAC7B,qBAAqB;IACrB,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAClC,8BAA8B;IAC9B,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAClC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACjC,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;AAChH,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAiB;IACxC,IAAI,EAAE,eAAe;IACrB,KAAK,EAAE,SAAS;IAChB,WAAW,EACT,oDAAoD;IACtD,WAAW;IACX,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE;QAC9B,MAAM,EAAE,GAAG,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC;QAC9D,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAChD,OAAO,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9C,CAAC;CACF,CAAC"}
@@ -0,0 +1 @@
1
+ export declare const tools: import("./types.js").LitForgeTool[];
@@ -0,0 +1,24 @@
1
+ // 全ツールを集約してエクスポート。新しいツール追加時はここに 1 行足す。
2
+ import { formatJson } from "./format-json.js";
3
+ import { testRegex } from "./test-regex.js";
4
+ import { decodeJwt } from "./decode-jwt.js";
5
+ import { convertBase64 } from "./convert-base64.js";
6
+ import { convertUrl } from "./convert-url.js";
7
+ import { generateHash } from "./generate-hash.js";
8
+ import { generateUuid } from "./generate-uuid.js";
9
+ import { convertTimestamp } from "./convert-timestamp.js";
10
+ import { convertYamlJson } from "./convert-yaml-json.js";
11
+ import { describeCron } from "./describe-cron.js";
12
+ export const tools = [
13
+ formatJson,
14
+ testRegex,
15
+ decodeJwt,
16
+ convertBase64,
17
+ convertUrl,
18
+ generateHash,
19
+ generateUuid,
20
+ convertTimestamp,
21
+ convertYamlJson,
22
+ describeCron,
23
+ ];
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AAEvC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,UAAU;IACV,SAAS;IACT,SAAS;IACT,aAAa;IACb,UAAU;IACV,YAAY;IACZ,YAAY;IACZ,gBAAgB;IAChB,eAAe;IACf,YAAY;CACb,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { type LitForgeTool } from "./types.js";
2
+ export declare const testRegex: LitForgeTool;
@@ -0,0 +1,54 @@
1
+ // 正規表現マッチ。JavaScript の RegExp(ECMAScript 準拠)を使う。
2
+ import { z } from "zod";
3
+ import { errorReply, jsonReply } from "./types.js";
4
+ const inputSchema = {
5
+ pattern: z.string().describe("正規表現本体(スラッシュは付けない)"),
6
+ flags: z
7
+ .string()
8
+ .regex(/^[gimsuy]*$/)
9
+ .default("g")
10
+ .describe("正規表現フラグ(g/i/m/s/u/y のみ)"),
11
+ text: z.string().describe("マッチさせる対象テキスト"),
12
+ maxMatches: z
13
+ .number()
14
+ .int()
15
+ .min(1)
16
+ .max(1000)
17
+ .default(100)
18
+ .describe("返すマッチ件数の上限"),
19
+ };
20
+ export const testRegex = {
21
+ name: "test_regex",
22
+ title: "正規表現テスト",
23
+ description: "JavaScript 互換の正規表現でテキストをマッチします。マッチ位置・キャプチャグループ・名前付きグループを返します。",
24
+ inputSchema,
25
+ handler: ({ pattern, flags, text, maxMatches }) => {
26
+ let re;
27
+ try {
28
+ // g フラグが無いと matchAll はエラーになるので強制付与
29
+ re = new RegExp(pattern, flags.includes("g") ? flags : flags + "g");
30
+ }
31
+ catch (e) {
32
+ return errorReply(`正規表現エラー: ${e instanceof Error ? e.message : String(e)}`);
33
+ }
34
+ const matches = [];
35
+ let count = 0;
36
+ for (const m of text.matchAll(re)) {
37
+ if (count >= maxMatches)
38
+ break;
39
+ matches.push({
40
+ match: m[0],
41
+ index: m.index ?? -1,
42
+ groups: m.slice(1).map((g) => g ?? ""),
43
+ ...(m.groups ? { namedGroups: m.groups } : {}),
44
+ });
45
+ count++;
46
+ }
47
+ return jsonReply({
48
+ matchCount: matches.length,
49
+ truncated: count >= maxMatches,
50
+ matches,
51
+ });
52
+ },
53
+ };
54
+ //# sourceMappingURL=test-regex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-regex.js","sourceRoot":"","sources":["../../src/tools/test-regex.ts"],"names":[],"mappings":"AAAA,iDAAiD;AAEjD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAqB,MAAM,YAAY,CAAC;AAEtE,MAAM,WAAW,GAAG;IAClB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;IAClD,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,KAAK,CAAC,aAAa,CAAC;SACpB,OAAO,CAAC,GAAG,CAAC;SACZ,QAAQ,CAAC,yBAAyB,CAAC;IACtC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;IACzC,UAAU,EAAE,CAAC;SACV,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,IAAI,CAAC;SACT,OAAO,CAAC,GAAG,CAAC;SACZ,QAAQ,CAAC,YAAY,CAAC;CAC1B,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAiB;IACrC,IAAI,EAAE,YAAY;IAClB,KAAK,EAAE,SAAS;IAChB,WAAW,EACT,+DAA+D;IACjE,WAAW;IACX,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE;QAChD,IAAI,EAAU,CAAC;QACf,IAAI,CAAC;YACH,mCAAmC;YACnC,EAAE,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC;QACtE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,UAAU,CACf,YAAY,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACzD,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,GAKR,EAAE,CAAC;QACR,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;YAClC,IAAI,KAAK,IAAI,UAAU;gBAAE,MAAM;YAC/B,OAAO,CAAC,IAAI,CAAC;gBACX,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;gBACX,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;gBACpB,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAqB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC1D,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC/C,CAAC,CAAC;YACH,KAAK,EAAE,CAAC;QACV,CAAC;QACD,OAAO,SAAS,CAAC;YACf,UAAU,EAAE,OAAO,CAAC,MAAM;YAC1B,SAAS,EAAE,KAAK,IAAI,UAAU;YAC9B,OAAO;SACR,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { ZodRawShape } from "zod";
2
+ import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
3
+ export type LitForgeTool = {
4
+ name: string;
5
+ title: string;
6
+ description: string;
7
+ inputSchema: ZodRawShape;
8
+ handler: (args: any) => CallToolResult | Promise<CallToolResult>;
9
+ };
10
+ export declare function jsonReply(data: unknown): CallToolResult;
11
+ export declare function errorReply(message: string): CallToolResult;
@@ -0,0 +1,21 @@
1
+ // MCP ツールの共通型。registerTool に渡す形に揃える。
2
+ // 型は各ツール内で zod から推論し、配列に集約する際は緩く扱う。
3
+ // 構造化レスポンスをテキスト 1 件で返すためのヘルパー。
4
+ // MCP は content[].text を string で要求するので JSON.stringify する。
5
+ export function jsonReply(data) {
6
+ return {
7
+ content: [
8
+ {
9
+ type: "text",
10
+ text: JSON.stringify(data, null, 2),
11
+ },
12
+ ],
13
+ };
14
+ }
15
+ export function errorReply(message) {
16
+ return {
17
+ isError: true,
18
+ content: [{ type: "text", text: message }],
19
+ };
20
+ }
21
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,oCAAoC;AAapC,+BAA+B;AAC/B,2DAA2D;AAC3D,MAAM,UAAU,SAAS,CAAC,IAAa;IACrC,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;aACpC;SACF;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,OAAe;IACxC,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;KAC3C,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "lit-forge-mcp",
3
+ "version": "0.1.0",
4
+ "description": "MCP server exposing lit-forge.com developer utilities (JSON / regex / JWT / Base64 / URL / hash / UUID / timestamp / YAML↔JSON / cron) as callable tools.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "homepage": "https://lit-forge.com",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/nobuoseki/lit-forge",
11
+ "directory": "mcp-server"
12
+ },
13
+ "keywords": [
14
+ "mcp",
15
+ "model-context-protocol",
16
+ "claude",
17
+ "developer-tools",
18
+ "json",
19
+ "regex",
20
+ "jwt",
21
+ "base64",
22
+ "uuid",
23
+ "yaml",
24
+ "cron"
25
+ ],
26
+ "bin": {
27
+ "lit-forge-mcp": "./dist/index.js"
28
+ },
29
+ "files": [
30
+ "dist",
31
+ "README.md",
32
+ "LICENSE"
33
+ ],
34
+ "scripts": {
35
+ "build": "tsc && chmod 755 dist/index.js",
36
+ "start": "node dist/index.js",
37
+ "dev": "tsc --watch",
38
+ "prepare": "npm run build"
39
+ },
40
+ "dependencies": {
41
+ "@modelcontextprotocol/sdk": "^1.29.0",
42
+ "cron-parser": "^5.5.0",
43
+ "cronstrue": "^3.14.0",
44
+ "js-yaml": "^4.1.0",
45
+ "zod": "^3.25.0"
46
+ },
47
+ "devDependencies": {
48
+ "@types/js-yaml": "^4.0.9",
49
+ "@types/node": "^22.0.0",
50
+ "typescript": "^5.6.0"
51
+ },
52
+ "engines": {
53
+ "node": ">=18"
54
+ }
55
+ }