@unclick/mcp-server 0.2.4 → 0.3.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 +139 -139
- package/dist/algolia-tool.d.ts +5 -0
- package/dist/algolia-tool.d.ts.map +1 -0
- package/dist/algolia-tool.js +121 -0
- package/dist/algolia-tool.js.map +1 -0
- package/dist/assemblyai-tool.d.ts +7 -0
- package/dist/assemblyai-tool.d.ts.map +1 -0
- package/dist/assemblyai-tool.js +127 -0
- package/dist/assemblyai-tool.js.map +1 -0
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +261 -0
- package/dist/catalog.js.map +1 -1
- package/dist/circleci-tool.d.ts +7 -0
- package/dist/circleci-tool.d.ts.map +1 -0
- package/dist/circleci-tool.js +133 -0
- package/dist/circleci-tool.js.map +1 -0
- package/dist/cohere-tool.d.ts +7 -0
- package/dist/cohere-tool.d.ts.map +1 -0
- package/dist/cohere-tool.js +225 -0
- package/dist/cohere-tool.js.map +1 -0
- package/dist/convertkit-tool.d.ts +7 -0
- package/dist/convertkit-tool.d.ts.map +1 -0
- package/dist/convertkit-tool.js +213 -0
- package/dist/convertkit-tool.js.map +1 -0
- package/dist/datadog-tool.d.ts +7 -0
- package/dist/datadog-tool.d.ts.map +1 -0
- package/dist/datadog-tool.js +121 -0
- package/dist/datadog-tool.js.map +1 -0
- package/dist/deepl-tool.d.ts +5 -0
- package/dist/deepl-tool.d.ts.map +1 -0
- package/dist/deepl-tool.js +137 -0
- package/dist/deepl-tool.js.map +1 -0
- package/dist/flyio-tool.d.ts +6 -0
- package/dist/flyio-tool.d.ts.map +1 -0
- package/dist/flyio-tool.js +158 -0
- package/dist/flyio-tool.js.map +1 -0
- package/dist/groq-tool.d.ts +3 -0
- package/dist/groq-tool.d.ts.map +1 -0
- package/dist/groq-tool.js +109 -0
- package/dist/groq-tool.js.map +1 -0
- package/dist/gumroad-tool.d.ts +6 -0
- package/dist/gumroad-tool.d.ts.map +1 -0
- package/dist/gumroad-tool.js +90 -0
- package/dist/gumroad-tool.js.map +1 -0
- package/dist/heygen-tool.d.ts +5 -0
- package/dist/heygen-tool.d.ts.map +1 -0
- package/dist/heygen-tool.js +134 -0
- package/dist/heygen-tool.js.map +1 -0
- package/dist/higgsfield-tool.d.ts +5 -0
- package/dist/higgsfield-tool.d.ts.map +1 -0
- package/dist/higgsfield-tool.js +120 -0
- package/dist/higgsfield-tool.js.map +1 -0
- package/dist/keychain-crypto.d.ts +24 -0
- package/dist/keychain-crypto.d.ts.map +1 -0
- package/dist/keychain-crypto.js +60 -0
- package/dist/keychain-crypto.js.map +1 -0
- package/dist/keychain-secure-input.d.ts +17 -0
- package/dist/keychain-secure-input.d.ts.map +1 -0
- package/dist/keychain-secure-input.js +229 -0
- package/dist/keychain-secure-input.js.map +1 -0
- package/dist/keychain-tool.d.ts +3 -0
- package/dist/keychain-tool.d.ts.map +1 -0
- package/dist/keychain-tool.js +516 -0
- package/dist/keychain-tool.js.map +1 -0
- package/dist/kling-tool.d.ts +3 -0
- package/dist/kling-tool.d.ts.map +1 -0
- package/dist/kling-tool.js +102 -0
- package/dist/kling-tool.js.map +1 -0
- package/dist/lemonsqueezy-tool.d.ts +7 -0
- package/dist/lemonsqueezy-tool.d.ts.map +1 -0
- package/dist/lemonsqueezy-tool.js +220 -0
- package/dist/lemonsqueezy-tool.js.map +1 -0
- package/dist/linear-tool.js +73 -73
- package/dist/local-catalog-handlers.d.ts +3 -0
- package/dist/local-catalog-handlers.d.ts.map +1 -0
- package/dist/local-catalog-handlers.js +1254 -0
- package/dist/local-catalog-handlers.js.map +1 -0
- package/dist/mailchimp-tool.d.ts +8 -0
- package/dist/mailchimp-tool.d.ts.map +1 -0
- package/dist/mailchimp-tool.js +138 -0
- package/dist/mailchimp-tool.js.map +1 -0
- package/dist/mapbox-tool.d.ts +6 -0
- package/dist/mapbox-tool.d.ts.map +1 -0
- package/dist/mapbox-tool.js +106 -0
- package/dist/mapbox-tool.js.map +1 -0
- package/dist/memory/db.d.ts +10 -0
- package/dist/memory/db.d.ts.map +1 -0
- package/dist/memory/db.js +22 -0
- package/dist/memory/db.js.map +1 -0
- package/dist/memory/handlers.d.ts +11 -0
- package/dist/memory/handlers.d.ts.map +1 -0
- package/dist/memory/handlers.js +125 -0
- package/dist/memory/handlers.js.map +1 -0
- package/dist/memory/local.d.ts +37 -0
- package/dist/memory/local.d.ts.map +1 -0
- package/dist/memory/local.js +386 -0
- package/dist/memory/local.js.map +1 -0
- package/dist/memory/supabase.d.ts +34 -0
- package/dist/memory/supabase.d.ts.map +1 -0
- package/dist/memory/supabase.js +209 -0
- package/dist/memory/supabase.js.map +1 -0
- package/dist/memory/types.d.ts +81 -0
- package/dist/memory/types.d.ts.map +1 -0
- package/dist/memory/types.js +5 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/mistral-tool.d.ts +4 -0
- package/dist/mistral-tool.d.ts.map +1 -0
- package/dist/mistral-tool.js +145 -0
- package/dist/mistral-tool.js.map +1 -0
- package/dist/mixpanel-tool.d.ts +6 -0
- package/dist/mixpanel-tool.d.ts.map +1 -0
- package/dist/mixpanel-tool.js +162 -0
- package/dist/mixpanel-tool.js.map +1 -0
- package/dist/monday-tool.js +46 -46
- package/dist/musicbrainz-tool.js +1 -1
- package/dist/musicbrainz-tool.js.map +1 -1
- package/dist/neon-tool.d.ts +7 -0
- package/dist/neon-tool.d.ts.map +1 -0
- package/dist/neon-tool.js +156 -0
- package/dist/neon-tool.js.map +1 -0
- package/dist/pagerduty-tool.d.ts +8 -0
- package/dist/pagerduty-tool.d.ts.map +1 -0
- package/dist/pagerduty-tool.js +185 -0
- package/dist/pagerduty-tool.js.map +1 -0
- package/dist/perplexity-tool.d.ts +2 -0
- package/dist/perplexity-tool.d.ts.map +1 -0
- package/dist/perplexity-tool.js +93 -0
- package/dist/perplexity-tool.js.map +1 -0
- package/dist/pika-tool.d.ts +4 -0
- package/dist/pika-tool.d.ts.map +1 -0
- package/dist/pika-tool.js +102 -0
- package/dist/pika-tool.js.map +1 -0
- package/dist/pinecone-tool.d.ts +6 -0
- package/dist/pinecone-tool.d.ts.map +1 -0
- package/dist/pinecone-tool.js +148 -0
- package/dist/pinecone-tool.js.map +1 -0
- package/dist/postmark-tool.d.ts +7 -0
- package/dist/postmark-tool.d.ts.map +1 -0
- package/dist/postmark-tool.js +148 -0
- package/dist/postmark-tool.js.map +1 -0
- package/dist/qc-tool.d.ts +4 -0
- package/dist/qc-tool.d.ts.map +1 -0
- package/dist/qc-tool.js +415 -0
- package/dist/qc-tool.js.map +1 -0
- package/dist/render-tool.d.ts +7 -0
- package/dist/render-tool.d.ts.map +1 -0
- package/dist/render-tool.js +158 -0
- package/dist/render-tool.js.map +1 -0
- package/dist/runway-tool.d.ts +4 -0
- package/dist/runway-tool.d.ts.map +1 -0
- package/dist/runway-tool.js +110 -0
- package/dist/runway-tool.js.map +1 -0
- package/dist/segment-tool.d.ts +6 -0
- package/dist/segment-tool.d.ts.map +1 -0
- package/dist/segment-tool.js +129 -0
- package/dist/segment-tool.js.map +1 -0
- package/dist/sendgrid-tool.d.ts +7 -0
- package/dist/sendgrid-tool.d.ts.map +1 -0
- package/dist/sendgrid-tool.js +124 -0
- package/dist/sendgrid-tool.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +129 -0
- package/dist/server.js.map +1 -1
- package/dist/togetherai-tool.d.ts +5 -0
- package/dist/togetherai-tool.d.ts.map +1 -0
- package/dist/togetherai-tool.js +129 -0
- package/dist/togetherai-tool.js.map +1 -0
- package/dist/toilets-tool.js +2 -2
- package/dist/tool-wiring.d.ts +4608 -692
- package/dist/tool-wiring.d.ts.map +1 -1
- package/dist/tool-wiring.js +2946 -463
- package/dist/tool-wiring.js.map +1 -1
- package/dist/turso-tool.d.ts +6 -0
- package/dist/turso-tool.d.ts.map +1 -0
- package/dist/turso-tool.js +158 -0
- package/dist/turso-tool.js.map +1 -0
- package/dist/upstash-tool.d.ts +8 -0
- package/dist/upstash-tool.d.ts.map +1 -0
- package/dist/upstash-tool.js +191 -0
- package/dist/upstash-tool.js.map +1 -0
- package/package.json +66 -65
- package/public/icon.svg +15 -15
- package/server.json +37 -37
package/README.md
CHANGED
|
@@ -1,139 +1,139 @@
|
|
|
1
|
-
# @unclick/mcp-server
|
|
2
|
-
|
|
3
|
-
**MCP server for the [UnClick](https://unclick.world) tool marketplace.**
|
|
4
|
-
|
|
5
|
-
Lets any MCP-compatible AI agent (Claude, Cursor, etc.) discover and use every tool in the UnClick marketplace — URL shortening, QR codes, image processing, hashing, CSV/JSON, regex, cron, color utilities, key-value storage, and more.
|
|
6
|
-
|
|
7
|
-
## Quick Start
|
|
8
|
-
|
|
9
|
-
### Claude Desktop
|
|
10
|
-
|
|
11
|
-
Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
|
|
12
|
-
|
|
13
|
-
```json
|
|
14
|
-
{
|
|
15
|
-
"mcpServers": {
|
|
16
|
-
"unclick": {
|
|
17
|
-
"command": "npx",
|
|
18
|
-
"args": ["-y", "@unclick/mcp-server"],
|
|
19
|
-
"env": {
|
|
20
|
-
"UNCLICK_API_KEY": "your_api_key_here"
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
Get your API key at [unclick.world](https://unclick.world).
|
|
28
|
-
|
|
29
|
-
### Local / Development
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
UNCLICK_API_KEY=unck_... npx @unclick/mcp-server
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## Configuration
|
|
36
|
-
|
|
37
|
-
| Environment Variable | Default | Description |
|
|
38
|
-
|---|---|---|
|
|
39
|
-
| `UNCLICK_API_KEY` | *(required)* | Your UnClick API key |
|
|
40
|
-
| `UNCLICK_BASE_URL` | `https://api.unclick.world` | Override API base URL (for self-hosted) |
|
|
41
|
-
|
|
42
|
-
## Tools Exposed
|
|
43
|
-
|
|
44
|
-
### Discovery (Meta Tools)
|
|
45
|
-
|
|
46
|
-
These tools let agents explore the full marketplace dynamically.
|
|
47
|
-
|
|
48
|
-
| Tool | Description |
|
|
49
|
-
|---|---|
|
|
50
|
-
| `unclick_search` | Search for tools by keyword. "I need to resize an image" → returns the image tool with endpoints and schemas. |
|
|
51
|
-
| `unclick_browse` | Browse all tools, optionally filtered by category (text, data, media, time, network, generation, storage). |
|
|
52
|
-
| `unclick_tool_info` | Get full details on a specific tool: all endpoints, required params, and response shapes. |
|
|
53
|
-
| `unclick_call` | Universal caller — specify any `endpoint_id` and `params`, the server routes the call. |
|
|
54
|
-
|
|
55
|
-
**Discovery flow for an agent:**
|
|
56
|
-
1. `unclick_search` → "what tool handles X?"
|
|
57
|
-
2. `unclick_tool_info` → "what are the exact params for that tool?"
|
|
58
|
-
3. `unclick_call` → call it
|
|
59
|
-
|
|
60
|
-
### Direct Tools (Zero Friction)
|
|
61
|
-
|
|
62
|
-
The most-used tools are exposed as first-class MCP tools for immediate use without discovery:
|
|
63
|
-
|
|
64
|
-
| Tool | What it does |
|
|
65
|
-
|---|---|
|
|
66
|
-
| `unclick_shorten_url` | Shorten a URL |
|
|
67
|
-
| `unclick_generate_qr` | Generate a QR code (PNG/SVG) |
|
|
68
|
-
| `unclick_hash` | Hash text with MD5/SHA1/SHA256/SHA512 |
|
|
69
|
-
| `unclick_transform_text` | Change text case (camel, snake, kebab, title, etc.) |
|
|
70
|
-
| `unclick_validate_email` | Validate an email address |
|
|
71
|
-
| `unclick_validate_url` | Validate a URL (+ optional reachability check) |
|
|
72
|
-
| `unclick_resize_image` | Resize a base64-encoded image |
|
|
73
|
-
| `unclick_parse_csv` | Parse CSV to JSON |
|
|
74
|
-
| `unclick_json_format` | Pretty-print JSON |
|
|
75
|
-
| `unclick_encode` | Encode/decode base64, URL, HTML, or hex |
|
|
76
|
-
| `unclick_generate_uuid` | Generate UUIDs |
|
|
77
|
-
| `unclick_random_password` | Generate a secure password |
|
|
78
|
-
| `unclick_cron_parse` | Parse a cron expression + show next occurrences |
|
|
79
|
-
| `unclick_ip_parse` | Parse an IP address |
|
|
80
|
-
| `unclick_color_convert` | Convert color between hex/RGB/HSL/HSV |
|
|
81
|
-
| `unclick_regex_test` | Test a regex and get all matches |
|
|
82
|
-
| `unclick_timestamp_convert` | Convert timestamps between formats |
|
|
83
|
-
| `unclick_diff_text` | Line-by-line diff of two strings |
|
|
84
|
-
| `unclick_kv_set` | Store a value in the key-value store |
|
|
85
|
-
| `unclick_kv_get` | Retrieve a value from the key-value store |
|
|
86
|
-
|
|
87
|
-
## Full Tool Catalog
|
|
88
|
-
|
|
89
|
-
The marketplace currently includes 23 tool groups spanning:
|
|
90
|
-
|
|
91
|
-
- **Text** — transform (case, slug, count), encode/decode (base64, URL, HTML, hex), hash/HMAC, regex, markdown, diff
|
|
92
|
-
- **Data** — JSON utilities, CSV processing, input validation (email, URL, phone, credit card, IP, color)
|
|
93
|
-
- **Media** — image processing (resize, convert, crop, rotate, compress, grayscale), QR code generation, color utilities
|
|
94
|
-
- **Time** — timestamp conversion, cron parsing/building
|
|
95
|
-
- **Network** — URL shortening, IP utilities (parse, subnet, CIDR)
|
|
96
|
-
- **Generation** — UUID v4, random (numbers, strings, passwords, picks, shuffles, colors)
|
|
97
|
-
- **Storage** — key-value store (with TTL), webhook bins
|
|
98
|
-
|
|
99
|
-
All tools are accessible via `unclick_call` with the appropriate `endpoint_id`.
|
|
100
|
-
|
|
101
|
-
## Example Usage
|
|
102
|
-
|
|
103
|
-
**Agent discovers and uses a tool:**
|
|
104
|
-
```
|
|
105
|
-
Agent: I need to hash a password before storing it.
|
|
106
|
-
|
|
107
|
-
1. unclick_search({ query: "hash password" })
|
|
108
|
-
→ Returns: hash tool (slug: hash, endpoints: hash.compute, hash.verify, hash.hmac)
|
|
109
|
-
|
|
110
|
-
2. unclick_call({ endpoint_id: "hash.compute", params: { text: "my-secret", algorithm: "sha256" } })
|
|
111
|
-
→ { algorithm: "sha256", hash: "abc123...", length: 64 }
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
**Direct tool usage:**
|
|
115
|
-
```
|
|
116
|
-
Agent: unclick_generate_qr({ text: "https://example.com", format: "png", size: 400 })
|
|
117
|
-
→ { binary: true, content_type: "image/png", data: "<base64>" }
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
## Development
|
|
121
|
-
|
|
122
|
-
```bash
|
|
123
|
-
# Run locally with tsx (no build step)
|
|
124
|
-
UNCLICK_API_KEY=unck_... npm run dev
|
|
125
|
-
|
|
126
|
-
# Build
|
|
127
|
-
npm run build
|
|
128
|
-
|
|
129
|
-
# Run built output
|
|
130
|
-
npm start
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
## MCP Registry
|
|
134
|
-
|
|
135
|
-
This server is published to npm as `@unclick/mcp-server` and can be added to any MCP registry that supports npx-based servers.
|
|
136
|
-
|
|
137
|
-
## License
|
|
138
|
-
|
|
139
|
-
MIT
|
|
1
|
+
# @unclick/mcp-server
|
|
2
|
+
|
|
3
|
+
**MCP server for the [UnClick](https://unclick.world) tool marketplace.**
|
|
4
|
+
|
|
5
|
+
Lets any MCP-compatible AI agent (Claude, Cursor, etc.) discover and use every tool in the UnClick marketplace — URL shortening, QR codes, image processing, hashing, CSV/JSON, regex, cron, color utilities, key-value storage, and more.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
### Claude Desktop
|
|
10
|
+
|
|
11
|
+
Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
{
|
|
15
|
+
"mcpServers": {
|
|
16
|
+
"unclick": {
|
|
17
|
+
"command": "npx",
|
|
18
|
+
"args": ["-y", "@unclick/mcp-server"],
|
|
19
|
+
"env": {
|
|
20
|
+
"UNCLICK_API_KEY": "your_api_key_here"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Get your API key at [unclick.world](https://unclick.world).
|
|
28
|
+
|
|
29
|
+
### Local / Development
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
UNCLICK_API_KEY=unck_... npx @unclick/mcp-server
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Configuration
|
|
36
|
+
|
|
37
|
+
| Environment Variable | Default | Description |
|
|
38
|
+
|---|---|---|
|
|
39
|
+
| `UNCLICK_API_KEY` | *(required)* | Your UnClick API key |
|
|
40
|
+
| `UNCLICK_BASE_URL` | `https://api.unclick.world` | Override API base URL (for self-hosted) |
|
|
41
|
+
|
|
42
|
+
## Tools Exposed
|
|
43
|
+
|
|
44
|
+
### Discovery (Meta Tools)
|
|
45
|
+
|
|
46
|
+
These tools let agents explore the full marketplace dynamically.
|
|
47
|
+
|
|
48
|
+
| Tool | Description |
|
|
49
|
+
|---|---|
|
|
50
|
+
| `unclick_search` | Search for tools by keyword. "I need to resize an image" → returns the image tool with endpoints and schemas. |
|
|
51
|
+
| `unclick_browse` | Browse all tools, optionally filtered by category (text, data, media, time, network, generation, storage). |
|
|
52
|
+
| `unclick_tool_info` | Get full details on a specific tool: all endpoints, required params, and response shapes. |
|
|
53
|
+
| `unclick_call` | Universal caller — specify any `endpoint_id` and `params`, the server routes the call. |
|
|
54
|
+
|
|
55
|
+
**Discovery flow for an agent:**
|
|
56
|
+
1. `unclick_search` → "what tool handles X?"
|
|
57
|
+
2. `unclick_tool_info` → "what are the exact params for that tool?"
|
|
58
|
+
3. `unclick_call` → call it
|
|
59
|
+
|
|
60
|
+
### Direct Tools (Zero Friction)
|
|
61
|
+
|
|
62
|
+
The most-used tools are exposed as first-class MCP tools for immediate use without discovery:
|
|
63
|
+
|
|
64
|
+
| Tool | What it does |
|
|
65
|
+
|---|---|
|
|
66
|
+
| `unclick_shorten_url` | Shorten a URL |
|
|
67
|
+
| `unclick_generate_qr` | Generate a QR code (PNG/SVG) |
|
|
68
|
+
| `unclick_hash` | Hash text with MD5/SHA1/SHA256/SHA512 |
|
|
69
|
+
| `unclick_transform_text` | Change text case (camel, snake, kebab, title, etc.) |
|
|
70
|
+
| `unclick_validate_email` | Validate an email address |
|
|
71
|
+
| `unclick_validate_url` | Validate a URL (+ optional reachability check) |
|
|
72
|
+
| `unclick_resize_image` | Resize a base64-encoded image |
|
|
73
|
+
| `unclick_parse_csv` | Parse CSV to JSON |
|
|
74
|
+
| `unclick_json_format` | Pretty-print JSON |
|
|
75
|
+
| `unclick_encode` | Encode/decode base64, URL, HTML, or hex |
|
|
76
|
+
| `unclick_generate_uuid` | Generate UUIDs |
|
|
77
|
+
| `unclick_random_password` | Generate a secure password |
|
|
78
|
+
| `unclick_cron_parse` | Parse a cron expression + show next occurrences |
|
|
79
|
+
| `unclick_ip_parse` | Parse an IP address |
|
|
80
|
+
| `unclick_color_convert` | Convert color between hex/RGB/HSL/HSV |
|
|
81
|
+
| `unclick_regex_test` | Test a regex and get all matches |
|
|
82
|
+
| `unclick_timestamp_convert` | Convert timestamps between formats |
|
|
83
|
+
| `unclick_diff_text` | Line-by-line diff of two strings |
|
|
84
|
+
| `unclick_kv_set` | Store a value in the key-value store |
|
|
85
|
+
| `unclick_kv_get` | Retrieve a value from the key-value store |
|
|
86
|
+
|
|
87
|
+
## Full Tool Catalog
|
|
88
|
+
|
|
89
|
+
The marketplace currently includes 23 tool groups spanning:
|
|
90
|
+
|
|
91
|
+
- **Text** — transform (case, slug, count), encode/decode (base64, URL, HTML, hex), hash/HMAC, regex, markdown, diff
|
|
92
|
+
- **Data** — JSON utilities, CSV processing, input validation (email, URL, phone, credit card, IP, color)
|
|
93
|
+
- **Media** — image processing (resize, convert, crop, rotate, compress, grayscale), QR code generation, color utilities
|
|
94
|
+
- **Time** — timestamp conversion, cron parsing/building
|
|
95
|
+
- **Network** — URL shortening, IP utilities (parse, subnet, CIDR)
|
|
96
|
+
- **Generation** — UUID v4, random (numbers, strings, passwords, picks, shuffles, colors)
|
|
97
|
+
- **Storage** — key-value store (with TTL), webhook bins
|
|
98
|
+
|
|
99
|
+
All tools are accessible via `unclick_call` with the appropriate `endpoint_id`.
|
|
100
|
+
|
|
101
|
+
## Example Usage
|
|
102
|
+
|
|
103
|
+
**Agent discovers and uses a tool:**
|
|
104
|
+
```
|
|
105
|
+
Agent: I need to hash a password before storing it.
|
|
106
|
+
|
|
107
|
+
1. unclick_search({ query: "hash password" })
|
|
108
|
+
→ Returns: hash tool (slug: hash, endpoints: hash.compute, hash.verify, hash.hmac)
|
|
109
|
+
|
|
110
|
+
2. unclick_call({ endpoint_id: "hash.compute", params: { text: "my-secret", algorithm: "sha256" } })
|
|
111
|
+
→ { algorithm: "sha256", hash: "abc123...", length: 64 }
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Direct tool usage:**
|
|
115
|
+
```
|
|
116
|
+
Agent: unclick_generate_qr({ text: "https://example.com", format: "png", size: 400 })
|
|
117
|
+
→ { binary: true, content_type: "image/png", data: "<base64>" }
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Development
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Run locally with tsx (no build step)
|
|
124
|
+
UNCLICK_API_KEY=unck_... npm run dev
|
|
125
|
+
|
|
126
|
+
# Build
|
|
127
|
+
npm run build
|
|
128
|
+
|
|
129
|
+
# Run built output
|
|
130
|
+
npm start
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## MCP Registry
|
|
134
|
+
|
|
135
|
+
This server is published to npm as `@unclick/mcp-server` and can be added to any MCP registry that supports npx-based servers.
|
|
136
|
+
|
|
137
|
+
## License
|
|
138
|
+
|
|
139
|
+
MIT
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function algoliaSearch(args: Record<string, unknown>): Promise<unknown>;
|
|
2
|
+
export declare function algoliaGetObject(args: Record<string, unknown>): Promise<unknown>;
|
|
3
|
+
export declare function algoliaListIndices(args: Record<string, unknown>): Promise<unknown>;
|
|
4
|
+
export declare function algoliaBrowseIndex(args: Record<string, unknown>): Promise<unknown>;
|
|
5
|
+
//# sourceMappingURL=algolia-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"algolia-tool.d.ts","sourceRoot":"","sources":["../src/algolia-tool.ts"],"names":[],"mappings":"AAuDA,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAyBnF;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAOtF;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CASxF;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAqBxF"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// Algolia Search API integration for the UnClick MCP server.
|
|
2
|
+
// Uses the Algolia REST API via fetch - no external dependencies.
|
|
3
|
+
// Users must supply an Application ID and API Key from algolia.com.
|
|
4
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
5
|
+
function requireCreds(args) {
|
|
6
|
+
const appId = String(args.app_id ?? "").trim();
|
|
7
|
+
const apiKey = String(args.api_key ?? "").trim();
|
|
8
|
+
if (!appId)
|
|
9
|
+
throw new Error("app_id is required (Algolia Application ID from algolia.com).");
|
|
10
|
+
if (!apiKey)
|
|
11
|
+
throw new Error("api_key is required (Algolia API Key from algolia.com).");
|
|
12
|
+
return { appId, apiKey };
|
|
13
|
+
}
|
|
14
|
+
function baseUrl(appId) {
|
|
15
|
+
return `https://${appId}-dsn.algolia.net/1`;
|
|
16
|
+
}
|
|
17
|
+
async function algoGet(appId, apiKey, path, params) {
|
|
18
|
+
const url = new URL(`${baseUrl(appId)}${path}`);
|
|
19
|
+
if (params)
|
|
20
|
+
Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v));
|
|
21
|
+
const res = await fetch(url.toString(), {
|
|
22
|
+
headers: {
|
|
23
|
+
"X-Algolia-Application-Id": appId,
|
|
24
|
+
"X-Algolia-API-Key": apiKey,
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
const data = await res.json();
|
|
28
|
+
if (!res.ok) {
|
|
29
|
+
const msg = data.message ?? `HTTP ${res.status}`;
|
|
30
|
+
throw new Error(`Algolia error (${res.status}): ${msg}`);
|
|
31
|
+
}
|
|
32
|
+
return data;
|
|
33
|
+
}
|
|
34
|
+
async function algoPost(appId, apiKey, path, body) {
|
|
35
|
+
const res = await fetch(`${baseUrl(appId)}${path}`, {
|
|
36
|
+
method: "POST",
|
|
37
|
+
headers: {
|
|
38
|
+
"X-Algolia-Application-Id": appId,
|
|
39
|
+
"X-Algolia-API-Key": apiKey,
|
|
40
|
+
"Content-Type": "application/json",
|
|
41
|
+
},
|
|
42
|
+
body: JSON.stringify(body),
|
|
43
|
+
});
|
|
44
|
+
const data = await res.json();
|
|
45
|
+
if (!res.ok) {
|
|
46
|
+
const msg = data.message ?? `HTTP ${res.status}`;
|
|
47
|
+
throw new Error(`Algolia error (${res.status}): ${msg}`);
|
|
48
|
+
}
|
|
49
|
+
return data;
|
|
50
|
+
}
|
|
51
|
+
// ─── Operations ───────────────────────────────────────────────────────────────
|
|
52
|
+
export async function algoliaSearch(args) {
|
|
53
|
+
const { appId, apiKey } = requireCreds(args);
|
|
54
|
+
const index = String(args.index ?? "").trim();
|
|
55
|
+
const query = String(args.query ?? "");
|
|
56
|
+
if (!index)
|
|
57
|
+
throw new Error("index is required (Algolia index name).");
|
|
58
|
+
const body = { query };
|
|
59
|
+
if (args.filters)
|
|
60
|
+
body.filters = String(args.filters);
|
|
61
|
+
if (args.hits_per_page)
|
|
62
|
+
body.hitsPerPage = Number(args.hits_per_page);
|
|
63
|
+
if (args.page !== undefined)
|
|
64
|
+
body.page = Number(args.page);
|
|
65
|
+
if (args.facets)
|
|
66
|
+
body.facets = args.facets;
|
|
67
|
+
if (args.attributes_to_retrieve)
|
|
68
|
+
body.attributesToRetrieve = args.attributes_to_retrieve;
|
|
69
|
+
const data = await algoPost(appId, apiKey, `/indexes/${encodeURIComponent(index)}/query`, body);
|
|
70
|
+
return {
|
|
71
|
+
index,
|
|
72
|
+
query,
|
|
73
|
+
total_hits: data.nbHits,
|
|
74
|
+
page: data.page,
|
|
75
|
+
total_pages: data.nbPages,
|
|
76
|
+
processing_ms: data.processingTimeMS,
|
|
77
|
+
hits: data.hits,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
export async function algoliaGetObject(args) {
|
|
81
|
+
const { appId, apiKey } = requireCreds(args);
|
|
82
|
+
const index = String(args.index ?? "").trim();
|
|
83
|
+
const objectId = String(args.object_id ?? "").trim();
|
|
84
|
+
if (!index)
|
|
85
|
+
throw new Error("index is required.");
|
|
86
|
+
if (!objectId)
|
|
87
|
+
throw new Error("object_id is required.");
|
|
88
|
+
return algoGet(appId, apiKey, `/indexes/${encodeURIComponent(index)}/${encodeURIComponent(objectId)}`);
|
|
89
|
+
}
|
|
90
|
+
export async function algoliaListIndices(args) {
|
|
91
|
+
const { appId, apiKey } = requireCreds(args);
|
|
92
|
+
const data = await algoGet(appId, apiKey, "/indexes");
|
|
93
|
+
return {
|
|
94
|
+
count: data.items?.length ?? 0,
|
|
95
|
+
indices: data.items ?? [],
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
export async function algoliaBrowseIndex(args) {
|
|
99
|
+
const { appId, apiKey } = requireCreds(args);
|
|
100
|
+
const index = String(args.index ?? "").trim();
|
|
101
|
+
if (!index)
|
|
102
|
+
throw new Error("index is required.");
|
|
103
|
+
const body = {};
|
|
104
|
+
if (args.filters)
|
|
105
|
+
body.filters = String(args.filters);
|
|
106
|
+
if (args.attributes_to_retrieve)
|
|
107
|
+
body.attributesToRetrieve = args.attributes_to_retrieve;
|
|
108
|
+
if (args.hits_per_page)
|
|
109
|
+
body.hitsPerPage = Number(args.hits_per_page);
|
|
110
|
+
if (args.cursor)
|
|
111
|
+
body.cursor = String(args.cursor);
|
|
112
|
+
const data = await algoPost(appId, apiKey, `/indexes/${encodeURIComponent(index)}/browse`, body);
|
|
113
|
+
return {
|
|
114
|
+
index,
|
|
115
|
+
hits: data.hits,
|
|
116
|
+
count: data.hits.length,
|
|
117
|
+
cursor: data.cursor ?? null,
|
|
118
|
+
has_more: !!data.cursor,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=algolia-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"algolia-tool.js","sourceRoot":"","sources":["../src/algolia-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function assemblyaiTranscribe(args: Record<string, unknown>): Promise<unknown>;
|
|
2
|
+
export declare function assemblyaiGetTranscript(args: Record<string, unknown>): Promise<unknown>;
|
|
3
|
+
export declare function assemblyaiListTranscripts(args: Record<string, unknown>): Promise<unknown>;
|
|
4
|
+
export declare function assemblyaiGetSentences(args: Record<string, unknown>): Promise<unknown>;
|
|
5
|
+
export declare function assemblyaiGetParagraphs(args: Record<string, unknown>): Promise<unknown>;
|
|
6
|
+
export declare function assemblyaiSummarize(args: Record<string, unknown>): Promise<unknown>;
|
|
7
|
+
//# sourceMappingURL=assemblyai-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assemblyai-tool.d.ts","sourceRoot":"","sources":["../src/assemblyai-tool.ts"],"names":[],"mappings":"AA4CA,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CA0B1F;AAED,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAK7F;AAED,wBAAsB,yBAAyB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAQ/F;AAED,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAM5F;AAED,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAM7F;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAQzF"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// AssemblyAI Speech-to-Text API integration for the UnClick MCP server.
|
|
2
|
+
// Uses the AssemblyAI REST API via fetch - no external dependencies.
|
|
3
|
+
// Users must supply an API key from assemblyai.com.
|
|
4
|
+
const AAI_BASE = "https://api.assemblyai.com/v2";
|
|
5
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
6
|
+
function requireKey(args) {
|
|
7
|
+
const key = String(args.api_key ?? "").trim();
|
|
8
|
+
if (!key)
|
|
9
|
+
throw new Error("api_key is required. Get one at assemblyai.com/dashboard.");
|
|
10
|
+
return key;
|
|
11
|
+
}
|
|
12
|
+
async function aaiGet(apiKey, path, params) {
|
|
13
|
+
const url = new URL(`${AAI_BASE}${path}`);
|
|
14
|
+
if (params)
|
|
15
|
+
Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v));
|
|
16
|
+
const res = await fetch(url.toString(), {
|
|
17
|
+
headers: { Authorization: apiKey },
|
|
18
|
+
});
|
|
19
|
+
const data = await res.json();
|
|
20
|
+
if (!res.ok) {
|
|
21
|
+
const msg = data.error ?? `HTTP ${res.status}`;
|
|
22
|
+
throw new Error(`AssemblyAI error (${res.status}): ${msg}`);
|
|
23
|
+
}
|
|
24
|
+
return data;
|
|
25
|
+
}
|
|
26
|
+
async function aaiPost(apiKey, path, body) {
|
|
27
|
+
const res = await fetch(`${AAI_BASE}${path}`, {
|
|
28
|
+
method: "POST",
|
|
29
|
+
headers: { Authorization: apiKey, "Content-Type": "application/json" },
|
|
30
|
+
body: JSON.stringify(body),
|
|
31
|
+
});
|
|
32
|
+
const data = await res.json();
|
|
33
|
+
if (!res.ok) {
|
|
34
|
+
const msg = data.error ?? `HTTP ${res.status}`;
|
|
35
|
+
throw new Error(`AssemblyAI error (${res.status}): ${msg}`);
|
|
36
|
+
}
|
|
37
|
+
return data;
|
|
38
|
+
}
|
|
39
|
+
// ─── Operations ───────────────────────────────────────────────────────────────
|
|
40
|
+
export async function assemblyaiTranscribe(args) {
|
|
41
|
+
const apiKey = requireKey(args);
|
|
42
|
+
const audioUrl = String(args.audio_url ?? "").trim();
|
|
43
|
+
if (!audioUrl)
|
|
44
|
+
throw new Error("audio_url is required (publicly accessible URL of the audio/video file).");
|
|
45
|
+
const body = { audio_url: audioUrl };
|
|
46
|
+
if (args.language_code)
|
|
47
|
+
body.language_code = String(args.language_code);
|
|
48
|
+
if (args.language_detection !== undefined)
|
|
49
|
+
body.language_detection = Boolean(args.language_detection);
|
|
50
|
+
if (args.punctuate !== undefined)
|
|
51
|
+
body.punctuate = Boolean(args.punctuate);
|
|
52
|
+
if (args.format_text !== undefined)
|
|
53
|
+
body.format_text = Boolean(args.format_text);
|
|
54
|
+
if (args.dual_channel !== undefined)
|
|
55
|
+
body.dual_channel = Boolean(args.dual_channel);
|
|
56
|
+
if (args.speaker_labels !== undefined)
|
|
57
|
+
body.speaker_labels = Boolean(args.speaker_labels);
|
|
58
|
+
if (args.auto_chapters !== undefined)
|
|
59
|
+
body.auto_chapters = Boolean(args.auto_chapters);
|
|
60
|
+
if (args.entity_detection !== undefined)
|
|
61
|
+
body.entity_detection = Boolean(args.entity_detection);
|
|
62
|
+
if (args.sentiment_analysis !== undefined)
|
|
63
|
+
body.sentiment_analysis = Boolean(args.sentiment_analysis);
|
|
64
|
+
if (args.summarization !== undefined)
|
|
65
|
+
body.summarization = Boolean(args.summarization);
|
|
66
|
+
if (args.summary_model)
|
|
67
|
+
body.summary_model = String(args.summary_model);
|
|
68
|
+
if (args.summary_type)
|
|
69
|
+
body.summary_type = String(args.summary_type);
|
|
70
|
+
if (args.webhook_url)
|
|
71
|
+
body.webhook_url = String(args.webhook_url);
|
|
72
|
+
const data = await aaiPost(apiKey, "/transcript", body);
|
|
73
|
+
return {
|
|
74
|
+
transcript_id: data.id,
|
|
75
|
+
status: data.status,
|
|
76
|
+
note: "Use get_transcript with the transcript_id to poll for completion.",
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export async function assemblyaiGetTranscript(args) {
|
|
80
|
+
const apiKey = requireKey(args);
|
|
81
|
+
const id = String(args.transcript_id ?? "").trim();
|
|
82
|
+
if (!id)
|
|
83
|
+
throw new Error("transcript_id is required.");
|
|
84
|
+
return aaiGet(apiKey, `/transcript/${encodeURIComponent(id)}`);
|
|
85
|
+
}
|
|
86
|
+
export async function assemblyaiListTranscripts(args) {
|
|
87
|
+
const apiKey = requireKey(args);
|
|
88
|
+
const params = {};
|
|
89
|
+
if (args.limit)
|
|
90
|
+
params.limit = String(Math.min(200, Math.max(1, Number(args.limit ?? 10))));
|
|
91
|
+
if (args.status)
|
|
92
|
+
params.status = String(args.status);
|
|
93
|
+
if (args.after_id)
|
|
94
|
+
params.after_id = String(args.after_id);
|
|
95
|
+
if (args.before_id)
|
|
96
|
+
params.before_id = String(args.before_id);
|
|
97
|
+
return aaiGet(apiKey, "/transcript", params);
|
|
98
|
+
}
|
|
99
|
+
export async function assemblyaiGetSentences(args) {
|
|
100
|
+
const apiKey = requireKey(args);
|
|
101
|
+
const id = String(args.transcript_id ?? "").trim();
|
|
102
|
+
if (!id)
|
|
103
|
+
throw new Error("transcript_id is required.");
|
|
104
|
+
const data = await aaiGet(apiKey, `/transcript/${encodeURIComponent(id)}/sentences`);
|
|
105
|
+
return { transcript_id: id, count: data.sentences?.length ?? 0, sentences: data.sentences ?? [] };
|
|
106
|
+
}
|
|
107
|
+
export async function assemblyaiGetParagraphs(args) {
|
|
108
|
+
const apiKey = requireKey(args);
|
|
109
|
+
const id = String(args.transcript_id ?? "").trim();
|
|
110
|
+
if (!id)
|
|
111
|
+
throw new Error("transcript_id is required.");
|
|
112
|
+
const data = await aaiGet(apiKey, `/transcript/${encodeURIComponent(id)}/paragraphs`);
|
|
113
|
+
return { transcript_id: id, count: data.paragraphs?.length ?? 0, paragraphs: data.paragraphs ?? [] };
|
|
114
|
+
}
|
|
115
|
+
export async function assemblyaiSummarize(args) {
|
|
116
|
+
const apiKey = requireKey(args);
|
|
117
|
+
const id = String(args.transcript_id ?? "").trim();
|
|
118
|
+
if (!id)
|
|
119
|
+
throw new Error("transcript_id is required (transcript must already be completed with summarization enabled).");
|
|
120
|
+
const data = await aaiGet(apiKey, `/transcript/${encodeURIComponent(id)}`);
|
|
121
|
+
if (data.error)
|
|
122
|
+
throw new Error(`Transcript error: ${data.error}`);
|
|
123
|
+
if (data.status !== "completed")
|
|
124
|
+
return { transcript_id: id, status: data.status, note: "Transcript not yet completed. Poll get_transcript until status is completed." };
|
|
125
|
+
return { transcript_id: id, status: data.status, summary: data.summary ?? null };
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=assemblyai-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assemblyai-tool.js","sourceRoot":"","sources":["../src/assemblyai-tool.ts"],"names":[],"mappings":"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"}
|
package/dist/catalog.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,CAAC;IACtB,8CAA8C;IAC9C,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,WAAW,EAAE,CAAC;CAC1B;AAED,eAAO,MAAM,UAAU,4FASb,CAAC;AAEX,eAAO,MAAM,OAAO,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,CAAC;IACtB,8CAA8C;IAC9C,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,WAAW,EAAE,CAAC;CAC1B;AAED,eAAO,MAAM,UAAU,4FASb,CAAC;AAEX,eAAO,MAAM,OAAO,EAAE,OAAO,EAulE5B,CAAC;AAEF,qDAAqD;AACrD,eAAO,MAAM,YAAY;UAA2B,OAAO;cAAY,WAAW;EAAK,CAAC;AAOxF,iCAAiC;AACjC,eAAO,MAAM,QAAQ,sBAEpB,CAAC"}
|