myclaw-toolkit 1.0.10 → 1.0.11

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 CHANGED
@@ -4,8 +4,24 @@
4
4
  [![npm](https://img.shields.io/npm/v/myclaw-toolkit)](https://www.npmjs.com/package/myclaw-toolkit)
5
5
  [![npm downloads](https://img.shields.io/npm/dw/myclaw-toolkit)](https://www.npmjs.com/package/myclaw-toolkit)
6
6
  [![license](https://img.shields.io/npm/l/myclaw-toolkit)](./LICENSE)
7
+ [![tests](https://github.com/Dusheh/myclaw-toolkit/actions/workflows/test.yml/badge.svg)](https://github.com/Dusheh/myclaw-toolkit/actions/workflows/test.yml)
7
8
 
8
- **24-in-1 developer utility toolkit as an MCP server.** Search the web, convert currencies, check crypto prices, generate QR codes, format JSON, and more — all from any MCP-compatible AI assistant.
9
+ **24-in-1 developer utility toolkit as an MCP server — privacy-first.** Search the web, convert currencies, check crypto prices, generate QR codes, format JSON, and more — all from any MCP-compatible AI assistant.
10
+
11
+ ## 🔒 Privacy-First Design
12
+
13
+ Most tools run **100% locally on your machine** — no data ever leaves your device:
14
+
15
+ | Local tools (zero network) | Tools requiring remote API |
16
+ |---|---|
17
+ | timestamp, uuid, base64, hash | web_search, news_search |
18
+ | qrcode, wifi_qrcode | product_search, exchange_rate |
19
+ | color_tools, json_formatter | crypto_price, domain_check |
20
+ | url_tools, text_tools | rss_feed, read_page |
21
+ | bmi_calculator, vcard_generator | ai_translate, quote, compare |
22
+ | markdown_to_html | |
23
+
24
+ WiFi passwords, JSON data, text content, hashes, and Markdown documents are all processed entirely on-device. Only tools that genuinely need external data (search, exchange rates, etc.) call the remote API.
9
25
 
10
26
  ## Quick Install
11
27
 
@@ -21,7 +37,7 @@ Or add to your AI client:
21
37
  "mcpServers": {
22
38
  "myclaw-toolkit": {
23
39
  "command": "npx",
24
- "args": ["myclaw-toolkit"]
40
+ "args": ["-y", "myclaw-toolkit"]
25
41
  }
26
42
  }
27
43
  }
@@ -34,7 +50,7 @@ claude mcp add myclaw-toolkit -- npx myclaw-toolkit
34
50
 
35
51
  ## Tools
36
52
 
37
- ### Utility (Free)
53
+ ### Utility (Local)
38
54
  | Tool | Description |
39
55
  |------|-------------|
40
56
  | `timestamp` | Current Unix timestamp & ISO 8601 |
@@ -47,16 +63,16 @@ claude mcp add myclaw-toolkit -- npx myclaw-toolkit
47
63
  | `url_tools` | URL encode/decode |
48
64
  | `text_tools` | Text count, reverse, case |
49
65
 
50
- ### Data (Free)
66
+ ### Data
51
67
  | Tool | Description |
52
68
  |------|-------------|
53
- | `exchange_rate` | Real-time currency rates |
54
- | `crypto_price` | Cryptocurrency prices |
55
- | `domain_check` | Domain whois & availability |
56
- | `bmi_calculator` | BMI calculator |
57
- | `vcard_generator` | vCard (.vcf) generator |
58
- | `compare` | Side-by-side comparison |
59
- | `quote` | Random inspirational quotes |
69
+ | `exchange_rate` | Real-time currency rates (API) |
70
+ | `crypto_price` | Cryptocurrency prices (API) |
71
+ | `domain_check` | Domain whois & availability (API) |
72
+ | `bmi_calculator` | BMI calculator (local) |
73
+ | `vcard_generator` | vCard (.vcf) generator (local) |
74
+ | `compare` | Side-by-side comparison (API) |
75
+ | `quote` | Random inspirational quotes (API) |
60
76
 
61
77
  ### Search & Content
62
78
  | Tool | Description |
@@ -70,9 +86,9 @@ claude mcp add myclaw-toolkit -- npx myclaw-toolkit
70
86
  ### Processing
71
87
  | Tool | Description |
72
88
  |------|-------------|
73
- | `markdown_to_html` | Markdown → HTML |
74
- | `wifi_qrcode` | WiFi QR code generator |
75
- | `ai_translate` | AI translation |
89
+ | `markdown_to_html` | Markdown → HTML (local) |
90
+ | `wifi_qrcode` | WiFi QR code generator (local — password never sent) |
91
+ | `ai_translate` | AI translation via MyMemory API |
76
92
 
77
93
  ### Health
78
94
  | Tool | Description |
@@ -83,10 +99,14 @@ claude mcp add myclaw-toolkit -- npx myclaw-toolkit
83
99
 
84
100
  Listed on these MCP registries (help others find the toolkit):
85
101
 
86
- - [Glama](https://glama.ai/mcp/servers/Dusheh/myclaw-toolkit) — badge above
87
- - [mcp.so](https://mcp.so) — submitted via form
88
- - [Smithery](https://smithery.ai) — submitted via form
89
- - [awesome-mcp-servers](https://github.com/punkpeye/awesome-mcp-servers) — PR pending
102
+ - [Glama](https://glama.ai/mcp/servers/Dusheh/myclaw-toolkit) — auto-indexed
103
+ - [MCPFind](https://www.mcpfind.org/) — PR pending
104
+ - [mcp.so](https://mcp.so) — submitted
105
+ - [awesome-mcp-servers (punkpeye)](https://github.com/punkpeye/awesome-mcp-servers) — PR pending
106
+ - [awesome-mcp-servers (appcypher)](https://github.com/appcypher/awesome-mcp-servers) — PR pending
107
+ - [Awesome MCP List](https://github.com/MobinX/awesome-mcp-list) — PR pending
108
+ - [MCP.Directory](https://mcp.directory) — submitted
109
+ - [Official MCP Registry](https://registry.modelcontextprotocol.io) — published, awaiting indexing
90
110
 
91
111
  ## Environment Variables
92
112
 
@@ -98,11 +118,14 @@ Listed on these MCP registries (help others find the toolkit):
98
118
 
99
119
  ```bash
100
120
  git clone https://github.com/Dusheh/myclaw-toolkit
101
- cd toolkit
121
+ cd myclaw-toolkit
102
122
  npm install
103
- npm run dev
123
+ npm run dev # Run with tsx
124
+ npm run build # Compile TypeScript
125
+ npm test # Run 24 unit tests
126
+ npm run lint # ESLint check
104
127
  ```
105
128
 
106
129
  ## License
107
130
 
108
- MIT — [MyClaw](https://myclaw.dev)
131
+ MIT
package/dist/index.js CHANGED
@@ -19,6 +19,18 @@ import { marked } from "marked";
19
19
  // ── Version (read from package.json, never hardcoded) ─────────────
20
20
  const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf-8"));
21
21
  const VERSION = pkg.version;
22
+ // ── Rate Limiter (protects backend from runaway AI clients) ─────────
23
+ const RATE_WINDOW_MS = 60_000; // 1 minute window
24
+ const MAX_REQUESTS_PER_WINDOW = 100;
25
+ let requestTimestamps = [];
26
+ function checkRateLimit() {
27
+ const now = Date.now();
28
+ requestTimestamps = requestTimestamps.filter(t => now - t < RATE_WINDOW_MS);
29
+ if (requestTimestamps.length >= MAX_REQUESTS_PER_WINDOW)
30
+ return false;
31
+ requestTimestamps.push(now);
32
+ return true;
33
+ }
22
34
  // ── Config ──────────────────────────────────────────────────────────
23
35
  const API_BASE = process.env.MYCLAW_API || "http://47.103.7.241";
24
36
  const USER_AGENT = `myclaw-toolkit-mcp/${VERSION}`;
@@ -28,6 +40,9 @@ const FETCH_TIMEOUT_MS = 15_000;
28
40
  * Only used for tools that genuinely need external data.
29
41
  */
30
42
  async function apiCall(path) {
43
+ if (!checkRateLimit()) {
44
+ return JSON.stringify({ error: "Rate limit exceeded", limit: `${MAX_REQUESTS_PER_WINDOW} requests per ${RATE_WINDOW_MS / 1000}s`, path });
45
+ }
31
46
  const controller = new AbortController();
32
47
  const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
33
48
  try {
@@ -237,3 +237,34 @@ describe("wifi_qrcode format", () => {
237
237
  expect(wifiString).toBe("WIFI:S:MyNetwork;T:WPA;P:secret123;;");
238
238
  });
239
239
  });
240
+ // ═══════════════════════════════════════════════════════════════════
241
+ // Rate Limiter Tests
242
+ // ═══════════════════════════════════════════════════════════════════
243
+ describe("rate_limiter", () => {
244
+ it("allows requests within limit", () => {
245
+ const RATE_WINDOW_MS = 60_000;
246
+ const MAX = 100;
247
+ let timestamps = [];
248
+ const check = () => {
249
+ const now = Date.now();
250
+ timestamps = timestamps.filter(t => now - t < RATE_WINDOW_MS);
251
+ if (timestamps.length >= MAX)
252
+ return false;
253
+ timestamps.push(now);
254
+ return true;
255
+ };
256
+ // First 100 requests should pass
257
+ for (let i = 0; i < MAX; i++) {
258
+ expect(check()).toBe(true);
259
+ }
260
+ // 101st should fail
261
+ expect(check()).toBe(false);
262
+ });
263
+ it("resets after window expires", () => {
264
+ const now = Date.now();
265
+ // Create 100 timestamps all older than the window
266
+ const timestamps = Array.from({ length: 100 }, () => now - 90_000);
267
+ const filtered = timestamps.filter(t => now - t < 60_000);
268
+ expect(filtered.length).toBe(0); // all expired
269
+ });
270
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myclaw-toolkit",
3
- "version": "1.0.10",
3
+ "version": "1.0.11",
4
4
  "description": "23-in-1 developer utility toolkit as an MCP server — search, exchange rates, crypto, QR codes, translation, and more",
5
5
  "mcpName": "io.github.Dusheh/myclaw-toolkit",
6
6
  "type": "module",