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 +44 -21
- package/dist/index.js +15 -0
- package/dist/tools.test.js +31 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,8 +4,24 @@
|
|
|
4
4
|
[](https://www.npmjs.com/package/myclaw-toolkit)
|
|
5
5
|
[](https://www.npmjs.com/package/myclaw-toolkit)
|
|
6
6
|
[](./LICENSE)
|
|
7
|
+
[](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 (
|
|
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
|
|
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) —
|
|
87
|
-
- [
|
|
88
|
-
- [
|
|
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
|
|
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 {
|
package/dist/tools.test.js
CHANGED
|
@@ -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.
|
|
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",
|