@unclick/mcp-server 0.2.3 → 0.2.4
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 -153
- package/dist/airtable-tool.d.ts +2 -0
- package/dist/airtable-tool.d.ts.map +1 -0
- package/dist/airtable-tool.js +154 -0
- package/dist/airtable-tool.js.map +1 -0
- package/dist/anthropic-tool.d.ts +3 -0
- package/dist/anthropic-tool.d.ts.map +1 -0
- package/dist/anthropic-tool.js +123 -0
- package/dist/anthropic-tool.js.map +1 -0
- package/dist/asana-tool.d.ts +8 -0
- package/dist/asana-tool.d.ts.map +1 -0
- package/dist/asana-tool.js +218 -0
- package/dist/asana-tool.js.map +1 -0
- package/dist/calendly-tool.d.ts +6 -0
- package/dist/calendly-tool.d.ts.map +1 -0
- package/dist/calendly-tool.js +182 -0
- package/dist/calendly-tool.js.map +1 -0
- package/dist/clickup-tool.d.ts +2 -0
- package/dist/clickup-tool.d.ts.map +1 -0
- package/dist/clickup-tool.js +153 -0
- package/dist/clickup-tool.js.map +1 -0
- package/dist/connectors/figma.d.ts +3 -0
- package/dist/connectors/figma.d.ts.map +1 -0
- package/dist/connectors/figma.js +18 -0
- package/dist/connectors/figma.js.map +1 -0
- package/dist/connectors/index.d.ts +3 -1
- package/dist/connectors/index.d.ts.map +1 -1
- package/dist/connectors/index.js +5 -1
- package/dist/connectors/index.js.map +1 -1
- package/dist/connectors/line.d.ts +3 -0
- package/dist/connectors/line.d.ts.map +1 -0
- package/dist/connectors/line.js +18 -0
- package/dist/connectors/line.js.map +1 -0
- package/dist/ebay-tool.d.ts +5 -0
- package/dist/ebay-tool.d.ts.map +1 -0
- package/dist/ebay-tool.js +179 -0
- package/dist/ebay-tool.js.map +1 -0
- package/dist/elevenlabs-tool.d.ts +6 -0
- package/dist/elevenlabs-tool.d.ts.map +1 -0
- package/dist/elevenlabs-tool.js +166 -0
- package/dist/elevenlabs-tool.js.map +1 -0
- package/dist/etsy-tool.d.ts +6 -0
- package/dist/etsy-tool.d.ts.map +1 -0
- package/dist/etsy-tool.js +125 -0
- package/dist/etsy-tool.js.map +1 -0
- package/dist/exchangerate-tool.d.ts +5 -0
- package/dist/exchangerate-tool.d.ts.map +1 -0
- package/dist/exchangerate-tool.js +139 -0
- package/dist/exchangerate-tool.js.map +1 -0
- package/dist/figma-tool.d.ts +8 -0
- package/dist/figma-tool.d.ts.map +1 -0
- package/dist/figma-tool.js +231 -0
- package/dist/figma-tool.js.map +1 -0
- package/dist/gdelt-tool.d.ts +5 -0
- package/dist/gdelt-tool.d.ts.map +1 -0
- package/dist/gdelt-tool.js +177 -0
- package/dist/gdelt-tool.js.map +1 -0
- package/dist/github-tool.d.ts +2 -0
- package/dist/github-tool.d.ts.map +1 -0
- package/dist/github-tool.js +165 -0
- package/dist/github-tool.js.map +1 -0
- package/dist/gitlab-tool.d.ts +2 -0
- package/dist/gitlab-tool.d.ts.map +1 -0
- package/dist/gitlab-tool.js +127 -0
- package/dist/gitlab-tool.js.map +1 -0
- package/dist/igdb-tool.d.ts +6 -0
- package/dist/igdb-tool.d.ts.map +1 -0
- package/dist/igdb-tool.js +140 -0
- package/dist/igdb-tool.js.map +1 -0
- package/dist/line-tool.d.ts +7 -0
- package/dist/line-tool.d.ts.map +1 -0
- package/dist/line-tool.js +188 -0
- package/dist/line-tool.js.map +1 -0
- package/dist/linear-tool.d.ts +2 -0
- package/dist/linear-tool.d.ts.map +1 -0
- package/dist/linear-tool.js +186 -0
- package/dist/linear-tool.js.map +1 -0
- package/dist/monday-tool.d.ts +7 -0
- package/dist/monday-tool.d.ts.map +1 -0
- package/dist/monday-tool.js +206 -0
- package/dist/monday-tool.js.map +1 -0
- package/dist/openai-tool.d.ts +6 -0
- package/dist/openai-tool.d.ts.map +1 -0
- package/dist/openai-tool.js +227 -0
- package/dist/openai-tool.js.map +1 -0
- package/dist/paypal-tool.d.ts +3 -0
- package/dist/paypal-tool.d.ts.map +1 -0
- package/dist/paypal-tool.js +157 -0
- package/dist/paypal-tool.js.map +1 -0
- package/dist/pinterest-tool.d.ts +7 -0
- package/dist/pinterest-tool.d.ts.map +1 -0
- package/dist/pinterest-tool.js +219 -0
- package/dist/pinterest-tool.js.map +1 -0
- package/dist/plaid-tool.d.ts +6 -0
- package/dist/plaid-tool.d.ts.map +1 -0
- package/dist/plaid-tool.js +149 -0
- package/dist/plaid-tool.js.map +1 -0
- package/dist/postman-tool.d.ts +2 -0
- package/dist/postman-tool.d.ts.map +1 -0
- package/dist/postman-tool.js +92 -0
- package/dist/postman-tool.js.map +1 -0
- package/dist/pushover-tool.d.ts +6 -0
- package/dist/pushover-tool.d.ts.map +1 -0
- package/dist/pushover-tool.js +146 -0
- package/dist/pushover-tool.js.map +1 -0
- package/dist/quickbooks-tool.d.ts +5 -0
- package/dist/quickbooks-tool.d.ts.map +1 -0
- package/dist/quickbooks-tool.js +160 -0
- package/dist/quickbooks-tool.js.map +1 -0
- package/dist/replicate-tool.d.ts +7 -0
- package/dist/replicate-tool.d.ts.map +1 -0
- package/dist/replicate-tool.js +172 -0
- package/dist/replicate-tool.js.map +1 -0
- package/dist/sentry-tool.d.ts +2 -0
- package/dist/sentry-tool.d.ts.map +1 -0
- package/dist/sentry-tool.js +123 -0
- package/dist/sentry-tool.js.map +1 -0
- package/dist/speedrun-tool.d.ts +6 -0
- package/dist/speedrun-tool.d.ts.map +1 -0
- package/dist/speedrun-tool.js +192 -0
- package/dist/speedrun-tool.js.map +1 -0
- package/dist/spotify-tool.d.ts +8 -0
- package/dist/spotify-tool.d.ts.map +1 -0
- package/dist/spotify-tool.js +274 -0
- package/dist/spotify-tool.js.map +1 -0
- package/dist/square-tool.d.ts +5 -0
- package/dist/square-tool.d.ts.map +1 -0
- package/dist/square-tool.js +133 -0
- package/dist/square-tool.js.map +1 -0
- package/dist/stability-tool.d.ts +5 -0
- package/dist/stability-tool.d.ts.map +1 -0
- package/dist/stability-tool.js +190 -0
- package/dist/stability-tool.js.map +1 -0
- package/dist/steam-tool.d.ts +6 -0
- package/dist/steam-tool.d.ts.map +1 -0
- package/dist/steam-tool.js +222 -0
- package/dist/steam-tool.js.map +1 -0
- package/dist/stripe-tool.d.ts +7 -0
- package/dist/stripe-tool.d.ts.map +1 -0
- package/dist/stripe-tool.js +181 -0
- package/dist/stripe-tool.js.map +1 -0
- package/dist/tiktok-tool.d.ts +4 -0
- package/dist/tiktok-tool.d.ts.map +1 -0
- package/dist/tiktok-tool.js +129 -0
- package/dist/tiktok-tool.js.map +1 -0
- package/dist/toilets-tool.js +2 -2
- package/dist/tool-wiring.d.ts +4066 -18
- package/dist/tool-wiring.d.ts.map +1 -1
- package/dist/tool-wiring.js +2601 -18
- package/dist/tool-wiring.js.map +1 -1
- package/dist/trello-tool.d.ts +2 -0
- package/dist/trello-tool.d.ts.map +1 -0
- package/dist/trello-tool.js +166 -0
- package/dist/trello-tool.js.map +1 -0
- package/dist/twilio-tool.d.ts +8 -0
- package/dist/twilio-tool.d.ts.map +1 -0
- package/dist/twilio-tool.js +243 -0
- package/dist/twilio-tool.js.map +1 -0
- package/dist/whatsapp-tool.d.ts +6 -0
- package/dist/whatsapp-tool.d.ts.map +1 -0
- package/dist/whatsapp-tool.js +200 -0
- package/dist/whatsapp-tool.js.map +1 -0
- package/dist/woocommerce-tool.d.ts +4 -0
- package/dist/woocommerce-tool.d.ts.map +1 -0
- package/dist/woocommerce-tool.js +140 -0
- package/dist/woocommerce-tool.js.map +1 -0
- package/dist/youtube-tool.d.ts +7 -0
- package/dist/youtube-tool.d.ts.map +1 -0
- package/dist/youtube-tool.js +196 -0
- package/dist/youtube-tool.js.map +1 -0
- package/package.json +1 -1
- package/server.json +37 -37
- package/LICENSE +0 -216
- package/dist/cloudflare-worker.d.ts +0 -12
- package/dist/cloudflare-worker.d.ts.map +0 -1
- package/dist/cloudflare-worker.js +0 -50
- package/dist/cloudflare-worker.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,153 +1,139 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
##
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
- **DNS verification** - For proving ownership of a domain and its subdomains
|
|
141
|
-
- **HTTP verification** - For proving ownership of a domain
|
|
142
|
-
|
|
143
|
-
The registry validates namespace ownership when publishing. E.g. to publish...:
|
|
144
|
-
- `io.github.domdomegg/my-cool-mcp` you must login to GitHub as `domdomegg`, or be in a GitHub Action on domdomegg's repos
|
|
145
|
-
- `me.adamjones/my-cool-mcp` you must prove ownership of `adamjones.me` via DNS or HTTP challenge
|
|
146
|
-
|
|
147
|
-
## Community Projects
|
|
148
|
-
|
|
149
|
-
Check out [community projects](docs/community-projects.md) to explore notable registry-related work created by the community.
|
|
150
|
-
|
|
151
|
-
## More documentation
|
|
152
|
-
|
|
153
|
-
See the [documentation](./docs) for more details if your question has not been answered here!
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"airtable-tool.d.ts","sourceRoot":"","sources":["../src/airtable-tool.ts"],"names":[],"mappings":"AAwIA,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,IAAI,EAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,OAAO,CAAC,CAoBlB"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// ── Airtable REST API tool ─────────────────────────────────────────────────
|
|
2
|
+
// Wraps the Airtable REST API via fetch.
|
|
3
|
+
// Auth: personal access token (PAT) passed as access_token.
|
|
4
|
+
// No external dependencies.
|
|
5
|
+
const AIRTABLE_META_API = "https://api.airtable.com/v0/meta";
|
|
6
|
+
const AIRTABLE_DATA_API = "https://api.airtable.com/v0";
|
|
7
|
+
// ── Fetch helper ───────────────────────────────────────────────────────────────
|
|
8
|
+
async function airtableFetch(token, method, url, body) {
|
|
9
|
+
const headers = {
|
|
10
|
+
Authorization: `Bearer ${token}`,
|
|
11
|
+
"User-Agent": "UnClick-MCP/1.0",
|
|
12
|
+
};
|
|
13
|
+
if (body !== undefined)
|
|
14
|
+
headers["Content-Type"] = "application/json";
|
|
15
|
+
let response;
|
|
16
|
+
try {
|
|
17
|
+
response = await fetch(url, {
|
|
18
|
+
method,
|
|
19
|
+
headers,
|
|
20
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
return { error: `Network error reaching Airtable API: ${err instanceof Error ? err.message : String(err)}` };
|
|
25
|
+
}
|
|
26
|
+
const text = await response.text();
|
|
27
|
+
let data;
|
|
28
|
+
try {
|
|
29
|
+
data = JSON.parse(text);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
data = { raw: text };
|
|
33
|
+
}
|
|
34
|
+
if (response.status === 401)
|
|
35
|
+
return { error: "Airtable token is invalid or expired. Check your access_token.", status: 401 };
|
|
36
|
+
if (response.status === 403)
|
|
37
|
+
return { error: "Insufficient permissions for this Airtable resource.", status: 403 };
|
|
38
|
+
if (response.status === 404)
|
|
39
|
+
return { error: "Base, table, or record not found.", status: 404 };
|
|
40
|
+
if (response.status === 422)
|
|
41
|
+
return { error: `Airtable validation error: ${data?.error ?? text}`, status: 422 };
|
|
42
|
+
if (response.status === 429)
|
|
43
|
+
return { error: "Airtable rate limit exceeded. Please wait and retry.", status: 429 };
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
const detail = data?.error ?? text;
|
|
46
|
+
return { error: `Airtable API error ${response.status}: ${detail}`, status: response.status };
|
|
47
|
+
}
|
|
48
|
+
return data;
|
|
49
|
+
}
|
|
50
|
+
// ── Action implementations ─────────────────────────────────────────────────────
|
|
51
|
+
async function listBases(token) {
|
|
52
|
+
return airtableFetch(token, "GET", `${AIRTABLE_META_API}/bases`);
|
|
53
|
+
}
|
|
54
|
+
async function listRecords(token, args) {
|
|
55
|
+
const baseId = String(args.base_id ?? "").trim();
|
|
56
|
+
const tableName = String(args.table_name ?? "").trim();
|
|
57
|
+
if (!baseId)
|
|
58
|
+
return { error: "base_id is required." };
|
|
59
|
+
if (!tableName)
|
|
60
|
+
return { error: "table_name is required." };
|
|
61
|
+
const url = new URL(`${AIRTABLE_DATA_API}/${encodeURIComponent(baseId)}/${encodeURIComponent(tableName)}`);
|
|
62
|
+
if (args.max_records)
|
|
63
|
+
url.searchParams.set("maxRecords", String(args.max_records));
|
|
64
|
+
if (args.page_size)
|
|
65
|
+
url.searchParams.set("pageSize", String(args.page_size));
|
|
66
|
+
if (args.offset)
|
|
67
|
+
url.searchParams.set("offset", String(args.offset));
|
|
68
|
+
if (args.view)
|
|
69
|
+
url.searchParams.set("view", String(args.view));
|
|
70
|
+
if (args.sort)
|
|
71
|
+
url.searchParams.set("sort", JSON.stringify(args.sort));
|
|
72
|
+
if (args.fields)
|
|
73
|
+
url.searchParams.set("fields", JSON.stringify(args.fields));
|
|
74
|
+
return airtableFetch(token, "GET", url.toString());
|
|
75
|
+
}
|
|
76
|
+
async function getRecord(token, args) {
|
|
77
|
+
const baseId = String(args.base_id ?? "").trim();
|
|
78
|
+
const tableName = String(args.table_name ?? "").trim();
|
|
79
|
+
const recordId = String(args.record_id ?? "").trim();
|
|
80
|
+
if (!baseId)
|
|
81
|
+
return { error: "base_id is required." };
|
|
82
|
+
if (!tableName)
|
|
83
|
+
return { error: "table_name is required." };
|
|
84
|
+
if (!recordId)
|
|
85
|
+
return { error: "record_id is required." };
|
|
86
|
+
return airtableFetch(token, "GET", `${AIRTABLE_DATA_API}/${encodeURIComponent(baseId)}/${encodeURIComponent(tableName)}/${encodeURIComponent(recordId)}`);
|
|
87
|
+
}
|
|
88
|
+
async function createRecord(token, args) {
|
|
89
|
+
const baseId = String(args.base_id ?? "").trim();
|
|
90
|
+
const tableName = String(args.table_name ?? "").trim();
|
|
91
|
+
if (!baseId)
|
|
92
|
+
return { error: "base_id is required." };
|
|
93
|
+
if (!tableName)
|
|
94
|
+
return { error: "table_name is required." };
|
|
95
|
+
if (!args.fields || typeof args.fields !== "object")
|
|
96
|
+
return { error: "fields (object) is required." };
|
|
97
|
+
return airtableFetch(token, "POST", `${AIRTABLE_DATA_API}/${encodeURIComponent(baseId)}/${encodeURIComponent(tableName)}`, { records: [{ fields: args.fields }] });
|
|
98
|
+
}
|
|
99
|
+
async function updateRecord(token, args) {
|
|
100
|
+
const baseId = String(args.base_id ?? "").trim();
|
|
101
|
+
const tableName = String(args.table_name ?? "").trim();
|
|
102
|
+
const recordId = String(args.record_id ?? "").trim();
|
|
103
|
+
if (!baseId)
|
|
104
|
+
return { error: "base_id is required." };
|
|
105
|
+
if (!tableName)
|
|
106
|
+
return { error: "table_name is required." };
|
|
107
|
+
if (!recordId)
|
|
108
|
+
return { error: "record_id is required." };
|
|
109
|
+
if (!args.fields || typeof args.fields !== "object")
|
|
110
|
+
return { error: "fields (object) is required." };
|
|
111
|
+
return airtableFetch(token, "PATCH", `${AIRTABLE_DATA_API}/${encodeURIComponent(baseId)}/${encodeURIComponent(tableName)}`, { records: [{ id: recordId, fields: args.fields }] });
|
|
112
|
+
}
|
|
113
|
+
async function searchRecords(token, args) {
|
|
114
|
+
const baseId = String(args.base_id ?? "").trim();
|
|
115
|
+
const tableName = String(args.table_name ?? "").trim();
|
|
116
|
+
const formula = String(args.formula ?? "").trim();
|
|
117
|
+
if (!baseId)
|
|
118
|
+
return { error: "base_id is required." };
|
|
119
|
+
if (!tableName)
|
|
120
|
+
return { error: "table_name is required." };
|
|
121
|
+
if (!formula)
|
|
122
|
+
return { error: "formula is required (Airtable formula filter string)." };
|
|
123
|
+
const url = new URL(`${AIRTABLE_DATA_API}/${encodeURIComponent(baseId)}/${encodeURIComponent(tableName)}`);
|
|
124
|
+
url.searchParams.set("filterByFormula", formula);
|
|
125
|
+
if (args.max_records)
|
|
126
|
+
url.searchParams.set("maxRecords", String(args.max_records));
|
|
127
|
+
if (args.fields)
|
|
128
|
+
url.searchParams.set("fields", JSON.stringify(args.fields));
|
|
129
|
+
return airtableFetch(token, "GET", url.toString());
|
|
130
|
+
}
|
|
131
|
+
// ── Public dispatcher ──────────────────────────────────────────────────────────
|
|
132
|
+
export async function airtableAction(action, args) {
|
|
133
|
+
const token = String(args.access_token ?? "").trim();
|
|
134
|
+
if (!token)
|
|
135
|
+
return { error: "access_token is required." };
|
|
136
|
+
try {
|
|
137
|
+
switch (action) {
|
|
138
|
+
case "list_bases": return listBases(token);
|
|
139
|
+
case "list_records": return listRecords(token, args);
|
|
140
|
+
case "get_record": return getRecord(token, args);
|
|
141
|
+
case "create_record": return createRecord(token, args);
|
|
142
|
+
case "update_record": return updateRecord(token, args);
|
|
143
|
+
case "search_records": return searchRecords(token, args);
|
|
144
|
+
default:
|
|
145
|
+
return {
|
|
146
|
+
error: `Unknown Airtable action: "${action}". Valid actions: list_bases, list_records, get_record, create_record, update_record, search_records.`,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
return { error: err instanceof Error ? err.message : String(err) };
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=airtable-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"airtable-tool.js","sourceRoot":"","sources":["../src/airtable-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic-tool.d.ts","sourceRoot":"","sources":["../src/anthropic-tool.ts"],"names":[],"mappings":"AA4FA,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAmD5F;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAezF"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// Anthropic Messages API integration for the UnClick MCP server.
|
|
2
|
+
// Uses the Anthropic REST API via fetch - no external dependencies.
|
|
3
|
+
// Users must supply an API key from console.anthropic.com.
|
|
4
|
+
// This tool is useful for agents that need to call Claude (or other models)
|
|
5
|
+
// programmatically, compare model outputs, or chain model calls.
|
|
6
|
+
const ANTHROPIC_API_BASE = "https://api.anthropic.com/v1";
|
|
7
|
+
const ANTHROPIC_VERSION = "2023-06-01";
|
|
8
|
+
// ─── Auth validation ──────────────────────────────────────────────────────────
|
|
9
|
+
function requireKey(args) {
|
|
10
|
+
const key = String(args.api_key ?? "").trim();
|
|
11
|
+
if (!key)
|
|
12
|
+
throw new Error("api_key is required. Get one at console.anthropic.com/settings/keys.");
|
|
13
|
+
return key;
|
|
14
|
+
}
|
|
15
|
+
// ─── API helpers ──────────────────────────────────────────────────────────────
|
|
16
|
+
async function anthropicPost(apiKey, path, body) {
|
|
17
|
+
const res = await fetch(`${ANTHROPIC_API_BASE}${path}`, {
|
|
18
|
+
method: "POST",
|
|
19
|
+
headers: {
|
|
20
|
+
"x-api-key": apiKey,
|
|
21
|
+
"anthropic-version": ANTHROPIC_VERSION,
|
|
22
|
+
"Content-Type": "application/json",
|
|
23
|
+
},
|
|
24
|
+
body: JSON.stringify(body),
|
|
25
|
+
});
|
|
26
|
+
const data = await res.json();
|
|
27
|
+
if (!res.ok) {
|
|
28
|
+
const err = data.error;
|
|
29
|
+
const msg = err?.message ?? `HTTP ${res.status}`;
|
|
30
|
+
const type = err?.type ? ` [${err.type}]` : "";
|
|
31
|
+
throw new Error(`Anthropic API error${type}: ${msg}`);
|
|
32
|
+
}
|
|
33
|
+
return data;
|
|
34
|
+
}
|
|
35
|
+
async function anthropicGet(apiKey, path) {
|
|
36
|
+
const res = await fetch(`${ANTHROPIC_API_BASE}${path}`, {
|
|
37
|
+
headers: {
|
|
38
|
+
"x-api-key": apiKey,
|
|
39
|
+
"anthropic-version": ANTHROPIC_VERSION,
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
const data = await res.json();
|
|
43
|
+
if (!res.ok) {
|
|
44
|
+
const err = data.error;
|
|
45
|
+
const msg = err?.message ?? `HTTP ${res.status}`;
|
|
46
|
+
throw new Error(`Anthropic API error: ${msg}`);
|
|
47
|
+
}
|
|
48
|
+
return data;
|
|
49
|
+
}
|
|
50
|
+
// ─── Operations ───────────────────────────────────────────────────────────────
|
|
51
|
+
export async function anthropicCreateMessage(args) {
|
|
52
|
+
const apiKey = requireKey(args);
|
|
53
|
+
const model = String(args.model ?? "claude-sonnet-4-6");
|
|
54
|
+
const maxTokens = Math.min(8192, Math.max(1, Number(args.max_tokens ?? 1024)));
|
|
55
|
+
// Parse messages
|
|
56
|
+
let messages;
|
|
57
|
+
if (Array.isArray(args.messages)) {
|
|
58
|
+
messages = args.messages;
|
|
59
|
+
}
|
|
60
|
+
else if (typeof args.messages === "string") {
|
|
61
|
+
try {
|
|
62
|
+
messages = JSON.parse(args.messages);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
throw new Error("messages must be a JSON array of {role, content} objects.");
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else if (args.prompt) {
|
|
69
|
+
// Convenience: single user message via 'prompt'
|
|
70
|
+
messages = [{ role: "user", content: String(args.prompt) }];
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
throw new Error("Either messages (array) or prompt (string) is required.");
|
|
74
|
+
}
|
|
75
|
+
if (messages.length === 0)
|
|
76
|
+
throw new Error("messages array must not be empty.");
|
|
77
|
+
const body = { model, max_tokens: maxTokens, messages };
|
|
78
|
+
if (args.system)
|
|
79
|
+
body.system = String(args.system);
|
|
80
|
+
if (args.temperature !== undefined)
|
|
81
|
+
body.temperature = Number(args.temperature);
|
|
82
|
+
if (args.top_p !== undefined)
|
|
83
|
+
body.top_p = Number(args.top_p);
|
|
84
|
+
if (args.top_k !== undefined)
|
|
85
|
+
body.top_k = Number(args.top_k);
|
|
86
|
+
if (args.stop_sequences)
|
|
87
|
+
body.stop_sequences = args.stop_sequences;
|
|
88
|
+
if (args.metadata)
|
|
89
|
+
body.metadata = args.metadata;
|
|
90
|
+
const result = await anthropicPost(apiKey, "/messages", body);
|
|
91
|
+
// Extract text content blocks
|
|
92
|
+
const textBlocks = result.content
|
|
93
|
+
.filter((b) => b.type === "text")
|
|
94
|
+
.map((b) => b.text ?? "");
|
|
95
|
+
return {
|
|
96
|
+
id: result.id,
|
|
97
|
+
model: result.model,
|
|
98
|
+
role: result.role,
|
|
99
|
+
content: textBlocks.join("\n"),
|
|
100
|
+
content_blocks: result.content.map((b) => ({
|
|
101
|
+
type: b.type,
|
|
102
|
+
text: b.text ?? null,
|
|
103
|
+
tool_name: b.name ?? null,
|
|
104
|
+
tool_input: b.input ?? null,
|
|
105
|
+
})),
|
|
106
|
+
stop_reason: result.stop_reason,
|
|
107
|
+
usage: result.usage,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
export async function anthropicListModels(args) {
|
|
111
|
+
const apiKey = requireKey(args);
|
|
112
|
+
const data = await anthropicGet(apiKey, "/models");
|
|
113
|
+
return {
|
|
114
|
+
count: data.data.length,
|
|
115
|
+
has_more: data.has_more,
|
|
116
|
+
models: data.data.map((m) => ({
|
|
117
|
+
id: m.id,
|
|
118
|
+
display_name: m.display_name,
|
|
119
|
+
created_at: m.created_at,
|
|
120
|
+
})),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=anthropic-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic-tool.js","sourceRoot":"","sources":["../src/anthropic-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function listAsanaWorkspaces(args: Record<string, unknown>): Promise<unknown>;
|
|
2
|
+
export declare function listAsanaProjects(args: Record<string, unknown>): Promise<unknown>;
|
|
3
|
+
export declare function listAsanaTasks(args: Record<string, unknown>): Promise<unknown>;
|
|
4
|
+
export declare function createAsanaTask(args: Record<string, unknown>): Promise<unknown>;
|
|
5
|
+
export declare function updateAsanaTask(args: Record<string, unknown>): Promise<unknown>;
|
|
6
|
+
export declare function getAsanaTask(args: Record<string, unknown>): Promise<unknown>;
|
|
7
|
+
export declare function searchAsanaTasks(args: Record<string, unknown>): Promise<unknown>;
|
|
8
|
+
//# sourceMappingURL=asana-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asana-tool.d.ts","sourceRoot":"","sources":["../src/asana-tool.ts"],"names":[],"mappings":"AAoEA,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAYzF;AAGD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAiBvF;AAGD,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAiBpF;AAGD,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAmBrF;AAGD,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAkBrF;AAGD,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAYlF;AAGD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAqBtF"}
|