@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.
Files changed (177) hide show
  1. package/README.md +139 -153
  2. package/dist/airtable-tool.d.ts +2 -0
  3. package/dist/airtable-tool.d.ts.map +1 -0
  4. package/dist/airtable-tool.js +154 -0
  5. package/dist/airtable-tool.js.map +1 -0
  6. package/dist/anthropic-tool.d.ts +3 -0
  7. package/dist/anthropic-tool.d.ts.map +1 -0
  8. package/dist/anthropic-tool.js +123 -0
  9. package/dist/anthropic-tool.js.map +1 -0
  10. package/dist/asana-tool.d.ts +8 -0
  11. package/dist/asana-tool.d.ts.map +1 -0
  12. package/dist/asana-tool.js +218 -0
  13. package/dist/asana-tool.js.map +1 -0
  14. package/dist/calendly-tool.d.ts +6 -0
  15. package/dist/calendly-tool.d.ts.map +1 -0
  16. package/dist/calendly-tool.js +182 -0
  17. package/dist/calendly-tool.js.map +1 -0
  18. package/dist/clickup-tool.d.ts +2 -0
  19. package/dist/clickup-tool.d.ts.map +1 -0
  20. package/dist/clickup-tool.js +153 -0
  21. package/dist/clickup-tool.js.map +1 -0
  22. package/dist/connectors/figma.d.ts +3 -0
  23. package/dist/connectors/figma.d.ts.map +1 -0
  24. package/dist/connectors/figma.js +18 -0
  25. package/dist/connectors/figma.js.map +1 -0
  26. package/dist/connectors/index.d.ts +3 -1
  27. package/dist/connectors/index.d.ts.map +1 -1
  28. package/dist/connectors/index.js +5 -1
  29. package/dist/connectors/index.js.map +1 -1
  30. package/dist/connectors/line.d.ts +3 -0
  31. package/dist/connectors/line.d.ts.map +1 -0
  32. package/dist/connectors/line.js +18 -0
  33. package/dist/connectors/line.js.map +1 -0
  34. package/dist/ebay-tool.d.ts +5 -0
  35. package/dist/ebay-tool.d.ts.map +1 -0
  36. package/dist/ebay-tool.js +179 -0
  37. package/dist/ebay-tool.js.map +1 -0
  38. package/dist/elevenlabs-tool.d.ts +6 -0
  39. package/dist/elevenlabs-tool.d.ts.map +1 -0
  40. package/dist/elevenlabs-tool.js +166 -0
  41. package/dist/elevenlabs-tool.js.map +1 -0
  42. package/dist/etsy-tool.d.ts +6 -0
  43. package/dist/etsy-tool.d.ts.map +1 -0
  44. package/dist/etsy-tool.js +125 -0
  45. package/dist/etsy-tool.js.map +1 -0
  46. package/dist/exchangerate-tool.d.ts +5 -0
  47. package/dist/exchangerate-tool.d.ts.map +1 -0
  48. package/dist/exchangerate-tool.js +139 -0
  49. package/dist/exchangerate-tool.js.map +1 -0
  50. package/dist/figma-tool.d.ts +8 -0
  51. package/dist/figma-tool.d.ts.map +1 -0
  52. package/dist/figma-tool.js +231 -0
  53. package/dist/figma-tool.js.map +1 -0
  54. package/dist/gdelt-tool.d.ts +5 -0
  55. package/dist/gdelt-tool.d.ts.map +1 -0
  56. package/dist/gdelt-tool.js +177 -0
  57. package/dist/gdelt-tool.js.map +1 -0
  58. package/dist/github-tool.d.ts +2 -0
  59. package/dist/github-tool.d.ts.map +1 -0
  60. package/dist/github-tool.js +165 -0
  61. package/dist/github-tool.js.map +1 -0
  62. package/dist/gitlab-tool.d.ts +2 -0
  63. package/dist/gitlab-tool.d.ts.map +1 -0
  64. package/dist/gitlab-tool.js +127 -0
  65. package/dist/gitlab-tool.js.map +1 -0
  66. package/dist/igdb-tool.d.ts +6 -0
  67. package/dist/igdb-tool.d.ts.map +1 -0
  68. package/dist/igdb-tool.js +140 -0
  69. package/dist/igdb-tool.js.map +1 -0
  70. package/dist/line-tool.d.ts +7 -0
  71. package/dist/line-tool.d.ts.map +1 -0
  72. package/dist/line-tool.js +188 -0
  73. package/dist/line-tool.js.map +1 -0
  74. package/dist/linear-tool.d.ts +2 -0
  75. package/dist/linear-tool.d.ts.map +1 -0
  76. package/dist/linear-tool.js +186 -0
  77. package/dist/linear-tool.js.map +1 -0
  78. package/dist/monday-tool.d.ts +7 -0
  79. package/dist/monday-tool.d.ts.map +1 -0
  80. package/dist/monday-tool.js +206 -0
  81. package/dist/monday-tool.js.map +1 -0
  82. package/dist/openai-tool.d.ts +6 -0
  83. package/dist/openai-tool.d.ts.map +1 -0
  84. package/dist/openai-tool.js +227 -0
  85. package/dist/openai-tool.js.map +1 -0
  86. package/dist/paypal-tool.d.ts +3 -0
  87. package/dist/paypal-tool.d.ts.map +1 -0
  88. package/dist/paypal-tool.js +157 -0
  89. package/dist/paypal-tool.js.map +1 -0
  90. package/dist/pinterest-tool.d.ts +7 -0
  91. package/dist/pinterest-tool.d.ts.map +1 -0
  92. package/dist/pinterest-tool.js +219 -0
  93. package/dist/pinterest-tool.js.map +1 -0
  94. package/dist/plaid-tool.d.ts +6 -0
  95. package/dist/plaid-tool.d.ts.map +1 -0
  96. package/dist/plaid-tool.js +149 -0
  97. package/dist/plaid-tool.js.map +1 -0
  98. package/dist/postman-tool.d.ts +2 -0
  99. package/dist/postman-tool.d.ts.map +1 -0
  100. package/dist/postman-tool.js +92 -0
  101. package/dist/postman-tool.js.map +1 -0
  102. package/dist/pushover-tool.d.ts +6 -0
  103. package/dist/pushover-tool.d.ts.map +1 -0
  104. package/dist/pushover-tool.js +146 -0
  105. package/dist/pushover-tool.js.map +1 -0
  106. package/dist/quickbooks-tool.d.ts +5 -0
  107. package/dist/quickbooks-tool.d.ts.map +1 -0
  108. package/dist/quickbooks-tool.js +160 -0
  109. package/dist/quickbooks-tool.js.map +1 -0
  110. package/dist/replicate-tool.d.ts +7 -0
  111. package/dist/replicate-tool.d.ts.map +1 -0
  112. package/dist/replicate-tool.js +172 -0
  113. package/dist/replicate-tool.js.map +1 -0
  114. package/dist/sentry-tool.d.ts +2 -0
  115. package/dist/sentry-tool.d.ts.map +1 -0
  116. package/dist/sentry-tool.js +123 -0
  117. package/dist/sentry-tool.js.map +1 -0
  118. package/dist/speedrun-tool.d.ts +6 -0
  119. package/dist/speedrun-tool.d.ts.map +1 -0
  120. package/dist/speedrun-tool.js +192 -0
  121. package/dist/speedrun-tool.js.map +1 -0
  122. package/dist/spotify-tool.d.ts +8 -0
  123. package/dist/spotify-tool.d.ts.map +1 -0
  124. package/dist/spotify-tool.js +274 -0
  125. package/dist/spotify-tool.js.map +1 -0
  126. package/dist/square-tool.d.ts +5 -0
  127. package/dist/square-tool.d.ts.map +1 -0
  128. package/dist/square-tool.js +133 -0
  129. package/dist/square-tool.js.map +1 -0
  130. package/dist/stability-tool.d.ts +5 -0
  131. package/dist/stability-tool.d.ts.map +1 -0
  132. package/dist/stability-tool.js +190 -0
  133. package/dist/stability-tool.js.map +1 -0
  134. package/dist/steam-tool.d.ts +6 -0
  135. package/dist/steam-tool.d.ts.map +1 -0
  136. package/dist/steam-tool.js +222 -0
  137. package/dist/steam-tool.js.map +1 -0
  138. package/dist/stripe-tool.d.ts +7 -0
  139. package/dist/stripe-tool.d.ts.map +1 -0
  140. package/dist/stripe-tool.js +181 -0
  141. package/dist/stripe-tool.js.map +1 -0
  142. package/dist/tiktok-tool.d.ts +4 -0
  143. package/dist/tiktok-tool.d.ts.map +1 -0
  144. package/dist/tiktok-tool.js +129 -0
  145. package/dist/tiktok-tool.js.map +1 -0
  146. package/dist/toilets-tool.js +2 -2
  147. package/dist/tool-wiring.d.ts +4066 -18
  148. package/dist/tool-wiring.d.ts.map +1 -1
  149. package/dist/tool-wiring.js +2601 -18
  150. package/dist/tool-wiring.js.map +1 -1
  151. package/dist/trello-tool.d.ts +2 -0
  152. package/dist/trello-tool.d.ts.map +1 -0
  153. package/dist/trello-tool.js +166 -0
  154. package/dist/trello-tool.js.map +1 -0
  155. package/dist/twilio-tool.d.ts +8 -0
  156. package/dist/twilio-tool.d.ts.map +1 -0
  157. package/dist/twilio-tool.js +243 -0
  158. package/dist/twilio-tool.js.map +1 -0
  159. package/dist/whatsapp-tool.d.ts +6 -0
  160. package/dist/whatsapp-tool.d.ts.map +1 -0
  161. package/dist/whatsapp-tool.js +200 -0
  162. package/dist/whatsapp-tool.js.map +1 -0
  163. package/dist/woocommerce-tool.d.ts +4 -0
  164. package/dist/woocommerce-tool.d.ts.map +1 -0
  165. package/dist/woocommerce-tool.js +140 -0
  166. package/dist/woocommerce-tool.js.map +1 -0
  167. package/dist/youtube-tool.d.ts +7 -0
  168. package/dist/youtube-tool.d.ts.map +1 -0
  169. package/dist/youtube-tool.js +196 -0
  170. package/dist/youtube-tool.js.map +1 -0
  171. package/package.json +1 -1
  172. package/server.json +37 -37
  173. package/LICENSE +0 -216
  174. package/dist/cloudflare-worker.d.ts +0 -12
  175. package/dist/cloudflare-worker.d.ts.map +0 -1
  176. package/dist/cloudflare-worker.js +0 -50
  177. package/dist/cloudflare-worker.js.map +0 -1
package/README.md CHANGED
@@ -1,153 +1,139 @@
1
- # MCP Registry
2
-
3
- The MCP registry provides MCP clients with a list of MCP servers, like an app store for MCP servers.
4
-
5
- [**📤 Publish my MCP server**](docs/modelcontextprotocol-io/quickstart.mdx) | [**⚡️ Live API docs**](https://registry.modelcontextprotocol.io/docs) | [**👀 Ecosystem vision**](docs/design/ecosystem-vision.md) | 📖 **[Full documentation](./docs)**
6
-
7
- ## Development Status
8
-
9
- **2025-10-24 update**: The Registry API has entered an **API freeze (v0.1)** 🎉. For the next month or more, the API will remain stable with no breaking changes, allowing integrators to confidently implement support. This freeze applies to v0.1 while development continues on v0. We'll use this period to validate the API in real-world integrations and gather feedback to shape v1 for general availability. Thank you to everyone for your contributions and patience—your involvement has been key to getting us here!
10
-
11
- **2025-09-08 update**: The registry has launched in preview 🎉 ([announcement blog post](https://blog.modelcontextprotocol.io/posts/2025-09-08-mcp-registry-preview/)). While the system is now more stable, this is still a preview release and breaking changes or data resets may occur. A general availability (GA) release will follow later. We'd love your feedback in [GitHub discussions](https://github.com/modelcontextprotocol/registry/discussions/new?category=ideas) or in the [#registry-dev Discord](https://discord.com/channels/1358869848138059966/1369487942862504016) ([joining details here](https://modelcontextprotocol.io/community/communication)).
12
-
13
- Current key maintainers:
14
- - **Adam Jones** (Anthropic) [@domdomegg](https://github.com/domdomegg)
15
- - **Tadas Antanavicius** (PulseMCP) [@tadasant](https://github.com/tadasant)
16
- - **Toby Padilla** (GitHub) [@toby](https://github.com/toby)
17
- - **Radoslav (Rado) Dimitrov** (Stacklok) [@rdimitrov](https://github.com/rdimitrov)
18
-
19
- ## Contributing
20
-
21
- We use multiple channels for collaboration - see [modelcontextprotocol.io/community/communication](https://modelcontextprotocol.io/community/communication).
22
-
23
- Often (but not always) ideas flow through this pipeline:
24
-
25
- - **[Discord](https://modelcontextprotocol.io/community/communication)** - Real-time community discussions
26
- - **[Discussions](https://github.com/modelcontextprotocol/registry/discussions)** - Propose and discuss product/technical requirements
27
- - **[Issues](https://github.com/modelcontextprotocol/registry/issues)** - Track well-scoped technical work
28
- - **[Pull Requests](https://github.com/modelcontextprotocol/registry/pulls)** - Contribute work towards issues
29
-
30
- ### Quick start:
31
-
32
- #### Pre-requisites
33
-
34
- - **Docker**
35
- - **Go 1.24.x**
36
- - **ko** - Container image builder for Go ([installation instructions](https://ko.build/install/))
37
- - **golangci-lint v2.4.0**
38
-
39
- #### Running the server
40
-
41
- ```bash
42
- # Start full development environment
43
- make dev-compose
44
- ```
45
-
46
- This starts the registry at [`localhost:8080`](http://localhost:8080) with PostgreSQL. The database uses ephemeral storage and is reset each time you restart the containers, ensuring a clean state for development and testing.
47
-
48
- **Note:** The registry uses [ko](https://ko.build) to build container images. The `make dev-compose` command automatically builds the registry image with ko and loads it into your local Docker daemon before starting the services.
49
-
50
- By default, the registry seeds from the production API with a filtered subset of servers (to keep startup fast). This ensures your local environment mirrors production behavior and all seed data passes validation. For offline development you can seed from a file without validation with `MCP_REGISTRY_SEED_FROM=data/seed.json MCP_REGISTRY_ENABLE_REGISTRY_VALIDATION=false make dev-compose`.
51
-
52
- The setup can be configured with environment variables in [docker-compose.yml](./docker-compose.yml) - see [.env.example](./.env.example) for a reference.
53
-
54
- <details>
55
- <summary>Alternative: Running a pre-built Docker image</summary>
56
-
57
- Pre-built Docker images are automatically published to GitHub Container Registry:
58
-
59
- ```bash
60
- # Run latest stable release
61
- docker run -p 8080:8080 ghcr.io/modelcontextprotocol/registry:latest
62
-
63
- # Run latest from main branch (continuous deployment)
64
- docker run -p 8080:8080 ghcr.io/modelcontextprotocol/registry:main
65
-
66
- # Run specific release version
67
- docker run -p 8080:8080 ghcr.io/modelcontextprotocol/registry:v1.0.0
68
-
69
- # Run development build from main branch
70
- docker run -p 8080:8080 ghcr.io/modelcontextprotocol/registry:main-20250906-abc123d
71
- ```
72
-
73
- **Available tags:**
74
- - **Releases**: `latest`, `v1.0.0`, `v1.1.0`, etc.
75
- - **Continuous**: `main` (latest main branch build)
76
- - **Development**: `main-<date>-<sha>` (specific commit builds)
77
-
78
- </details>
79
-
80
- #### Publishing a server
81
-
82
- To publish a server, we've built a simple CLI. You can use it with:
83
-
84
- ```bash
85
- # Build the latest CLI
86
- make publisher
87
-
88
- # Use it!
89
- ./bin/mcp-publisher --help
90
- ```
91
-
92
- See [the publisher guide](./docs/modelcontextprotocol-io/quickstart.mdx) for more details.
93
-
94
- #### Other commands
95
-
96
- ```bash
97
- # Run lint, unit tests and integration tests
98
- make check
99
- ```
100
-
101
- There are also a few more helpful commands for development. Run `make help` to learn more, or look in [Makefile](./Makefile).
102
-
103
- <!--
104
- For Claude and other AI tools: Always prefer make targets over custom commands where possible.
105
- -->
106
-
107
- ## Architecture
108
-
109
- ### Project Structure
110
-
111
- ```
112
- ├── cmd/ # Application entry points
113
- │ └── publisher/ # Server publishing tool
114
- ├── data/ # Seed data
115
- ├── deploy/ # Deployment configuration (Pulumi)
116
- ├── docs/ # Documentation
117
- ├── internal/ # Private application code
118
- │ ├── api/ # HTTP handlers and routing
119
- │ ├── auth/ # Authentication (GitHub OAuth, JWT, namespace blocking)
120
- │ ├── config/ # Configuration management
121
- │ ├── database/ # Data persistence (PostgreSQL)
122
- │ ├── service/ # Business logic
123
- │ ├── telemetry/ # Metrics and monitoring
124
- │ └── validators/ # Input validation
125
- ├── pkg/ # Public packages
126
- │ ├── api/ # API types and structures
127
- │ │ └── v0/ # Version 0 API types
128
- │ └── model/ # Data models for server.json
129
- ├── scripts/ # Development and testing scripts
130
- ├── tests/ # Integration tests
131
- └── tools/ # CLI tools and utilities
132
- └── validate-*.sh # Schema validation tools
133
- ```
134
-
135
- ### Authentication
136
-
137
- Publishing supports multiple authentication methods:
138
- - **GitHub OAuth** - For publishing by logging into GitHub
139
- - **GitHub OIDC** - For publishing from GitHub Actions
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,2 @@
1
+ export declare function airtableAction(action: string, args: Record<string, unknown>): Promise<unknown>;
2
+ //# sourceMappingURL=airtable-tool.d.ts.map
@@ -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,3 @@
1
+ export declare function anthropicCreateMessage(args: Record<string, unknown>): Promise<unknown>;
2
+ export declare function anthropicListModels(args: Record<string, unknown>): Promise<unknown>;
3
+ //# sourceMappingURL=anthropic-tool.d.ts.map
@@ -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"}