# Directory Structure
```
├── .gitignore
├── LICENSE
├── package.json
├── README.md
├── src
│ └── server.ts
└── tsconfig.json
```
# Files
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
```
1 | # Dependencies
2 | node_modules/
3 | yarn.lock
4 | package-lock.json
5 |
6 | # Build output
7 | dist/
8 | build/
9 | *.tsbuildinfo
10 |
11 | # Environment variables and secrets
12 | .env
13 | .env.*
14 | .cursor/mcp.json
15 |
16 | # IDE and editor files
17 | .idea/
18 | .vscode/
19 | *.swp
20 | *.swo
21 | .DS_Store
22 | Thumbs.db
23 |
24 | # Logs
25 | logs/
26 | *.log
27 | npm-debug.log*
28 | yarn-debug.log*
29 | yarn-error.log*
30 |
31 | # Testing
32 | coverage/
33 | .nyc_output/
34 |
35 | # Temporary files
36 | tmp/
37 | temp/
38 |
39 | # Workato specific
40 | .workato-token
41 | workato.config.json
```
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
```markdown
1 | 🤖 Workato MCP Server
2 | Welcome to your Workato API integration toolkit, designed as a Model Context Protocol (MCP) server for Cursor or Claude! This project provides seamless interaction with Workato's API through custom AI tools.
3 |
4 | ✨ Features
5 | 🔄 Recipe Management
6 | - List, create, start, and stop recipes
7 | - Monitor recipe execution jobs
8 | - Manage recipe folders and projects
9 |
10 | 🔌 Connection Management
11 | - List and create connections
12 | - View connection details and status
13 | - Manage connection configurations
14 |
15 | 🔍 Connector Discovery
16 | - List available connectors and their capabilities
17 | - View connector metadata and supported operations
18 | - Browse all platform connectors
19 |
20 | 📂 Folder & Project Organization
21 | - Create and manage folders
22 | - Organize recipes and connections
23 | - Handle project-level configurations
24 |
25 | 📊 Activity Logs
26 | - Track all activities within your workspace
27 | - Filter logs by time range, users, and event types
28 | - Monitor resource changes and user actions
29 | - Support for multiple environments (dev, sandbox, prod, etc.)
30 | - Advanced filtering by resource and event types
31 |
32 |
33 | 🔖 Tag Management
34 | - Create, update, and delete tags in your workspace
35 | - List and retrieve available tags with advanced filtering options
36 | - Apply or remove tags from assets (recipes and connections)
37 | - Supports batch operations for multiple assets and tags
38 | - Filter tags by title, description, author, and usage
39 | - Sort tags by various criteria (title, usage count, etc.)
40 | - Customize tag appearance with color options
41 |
42 |
43 | 🚀 Getting Started
44 | 2. Installation
45 | ```bash
46 | npm install
47 | # or
48 | yarn install
49 | ```
50 |
51 | 3. Build the Server
52 | ```bash
53 | npm run build
54 | ```
55 |
56 | 4. Adding to Cursor
57 | This project is designed to be used as an MCP server in Cursor. Here's how to set it up:
58 |
59 | 1. Open Cursor
60 | 2. Go to Cursor Settings > Features > MCP
61 | 3. Click + Add New MCP Server
62 | 4. Fill out the form:
63 | - Name: Workato MCP Server
64 | - Type: stdio
65 | - Command: node /path/to/your/project/dist/server.js
66 | - Environment Variables:
67 | - Click "Add Environment Variable"
68 | - Name: WORKATO_API_TOKEN
69 | - Value: your_token_here
70 |
71 | 📘 Pro Tip: Use the full path to your project's built server.js file.
72 |
73 | Alternative Configuration:
74 | You can also configure the MCP server using a `.cursor/mcp.json` file in your project:
75 |
76 | ```json
77 | {
78 | "mcpServers": {
79 | "workato-tools": {
80 | "command": "node",
81 | "args": ["/path/to/your/project/dist/server.js"],
82 | "env": {
83 | "WORKATO_API_TOKEN": "your_token_here"
84 | }
85 | }
86 | }
87 | }
88 | ```
89 |
90 | Using with Claude Desktop:
91 | If you're using Claude Desktop instead of Cursor, you can configure the MCP server by editing the Claude desktop configuration:
92 |
93 | 1. Open or create the configuration file:
94 | ```bash
95 | # On macOS
96 | ~/Library/Application Support/Claude/claude_desktop_config.json
97 | # On Windows
98 | %APPDATA%\Claude\claude_desktop_config.json
99 | # On Linux
100 | ~/.config/Claude/claude_desktop_config.json
101 | ```
102 |
103 | 2. Add your MCP server configuration:
104 | ```json
105 | {
106 | "mcp_servers": {
107 | "workato-tools": {
108 | "command": "node",
109 | "args": ["/path/to/your/project/dist/server.js"],
110 | "env": {
111 | "WORKATO_API_TOKEN": "your_token_here"
112 | }
113 | }
114 | }
115 | }
116 | ```
117 |
118 | 3. Save the file and restart Claude Desktop for the changes to take effect
119 |
120 | This method allows you to:
121 | - Version control your MCP configuration
122 | - Include environment variables directly in the config
123 | - Share the same configuration across team members (excluding sensitive values)
124 | - Automatically load the server when opening the project in Cursor
125 |
126 | 🛠️ Available Tools
127 |
128 | Recipe Management:
129 | - list-recipes: List all recipes with filtering options
130 | - create-recipe: Create a new recipe
131 | - start-recipe: Start a specific recipe
132 | - stop-recipe: Stop a running recipe
133 |
134 | Connection Management:
135 | - list-connections: List all connections
136 | - create-connection: Create a new connection
137 |
138 | Connector Tools:
139 | - list-connectors: Get metadata for specific connectors
140 | - list-all-connectors: List all available connectors
141 |
142 | Organization Tools:
143 | - list-folders: List all folders
144 | - create-folder: Create a new folder
145 | - update-folder: Modify folder properties
146 | - list-projects: List all projects
147 | - update-project: Update project details
148 |
149 | API Management:
150 | - list-api-endpoints: List all API endpoints with optional filtering by collection
151 |
152 | Activity Monitoring:
153 | - list-activity-logs: Retrieve detailed activity logs with advanced filtering options
154 | - Filter by time range, users, and event types
155 | - Include or exclude specific resource types
156 | - Track changes across different environments
157 | - Monitor user actions and system events
158 |
159 | Tag Management:
160 | - list-tags: List and filter available tags in your workspace with advanced query options
161 | - create-tag: Create a new tag with custom title, description, and color
162 | - update-tag: Modify an existing tag's properties
163 | - delete-tag: Remove a tag from your workspace
164 | - manage-tags: Apply or remove tags from recipes and connections
165 |
166 | Job Management:
167 | - list-recipe-jobs: View jobs for a specific recipe
168 | - get-job: Get detailed job information
169 | - resume-job: Resume a paused job
170 |
171 | 🤝 Contributing Contributions welcome! Please feel free to submit a Pull Request.
172 |
173 | 📝 License This project is licensed under the MIT License - see the LICENSE file for details.
174 |
175 | 🐛 Issues & Support Found a bug or need help? Open an issue with:
176 |
177 | What you were trying to do
178 | What happened instead
179 | Steps to reproduce
180 | Your environment details
181 |
182 | Made with ❤️ by Jacob Goren, for Workato automation
```
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
```json
1 | {
2 | "compilerOptions": {
3 | "target": "es2022",
4 | "module": "es2022",
5 | "moduleResolution": "node",
6 | "esModuleInterop": true,
7 | "strict": true,
8 | "outDir": "./dist",
9 | "rootDir": "./src",
10 | "declaration": true,
11 | "skipLibCheck": true
12 | },
13 | "include": ["src/**/*"],
14 | "exclude": ["node_modules", "dist"]
15 | }
```
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
```json
1 | {
2 | "name": "workato-mpc-server",
3 | "version": "1.0.0",
4 | "type": "module",
5 | "main": "dist/server.js",
6 | "scripts": {
7 | "build": "yarn tsc",
8 | "start": "node dist/server.js",
9 | "dev": "yarn build && yarn start"
10 | },
11 | "repository": {
12 | "type": "git",
13 | "url": "git+https://github.com/jacobgoren-sb/workato-mpc-server.git"
14 | },
15 | "keywords": [],
16 | "author": "",
17 | "license": "ISC",
18 | "bugs": {
19 | "url": "https://github.com/jacobgoren-sb/workato-mpc-server/issues"
20 | },
21 | "homepage": "https://github.com/jacobgoren-sb/workato-mpc-server#readme",
22 | "description": "",
23 | "dependencies": {
24 | "@modelcontextprotocol/sdk": "^1.7.0",
25 | "@types/node": "^20.11.24",
26 | "typescript": "^5.3.3",
27 | "zod": "^3.22.4"
28 | }
29 | }
30 |
```
--------------------------------------------------------------------------------
/src/server.ts:
--------------------------------------------------------------------------------
```typescript
1 | import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
2 | import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3 | import { z } from "zod";
4 |
5 | // Create an MCP server
6 | const server = new McpServer({
7 | name: "workato-mcp-server",
8 | version: "1.0.0"
9 | });
10 |
11 | // Add list-recipes tool
12 | server.tool(
13 | "list-recipes",
14 | {
15 | adapter_names_all: z.string().optional(),
16 | adapter_names_any: z.string().optional(),
17 | folder_id: z.string().optional(),
18 | order: z.enum(["activity", "default"]).optional(),
19 | page: z.number().int().min(1).optional().default(1),
20 | per_page: z.number().int().min(1).max(100).optional().default(100),
21 | running: z.boolean().optional(),
22 | since_id: z.number().int().optional(),
23 | stopped_after: z.string().regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/).optional(),
24 | stop_cause: z.enum(["trigger_errors_limit", "action_quota_limit", "trial_expired", "txn_quota_limit"]).optional(),
25 | updated_after: z.string().regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/).optional(),
26 | includes: z.array(z.string()).optional()
27 | },
28 | async (params) => {
29 | // Construct query parameters
30 | const queryParams = new URLSearchParams();
31 | Object.entries(params).forEach(([key, value]) => {
32 | if (value !== undefined) {
33 | if (Array.isArray(value)) {
34 | value.forEach(v => queryParams.append(`${key}[]`, v));
35 | } else {
36 | queryParams.append(key, String(value));
37 | }
38 | }
39 | });
40 |
41 | // Make API call to Workato
42 | const response = await fetch(`https://www.workato.com/api/recipes?${queryParams.toString()}`, {
43 | headers: {
44 | 'Authorization': 'Bearer ' + process.env.WORKATO_API_TOKEN
45 | }
46 | });
47 |
48 | const data = await response.json();
49 | return {
50 | content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
51 | };
52 | }
53 | );
54 |
55 | // Add create-recipe tool
56 | server.tool(
57 | "create-recipe",
58 | {
59 | recipe: z.object({
60 | name: z.string().optional(),
61 | code: z.string(),
62 | config: z.string().optional(),
63 | folder_id: z.string().optional(),
64 | description: z.string().optional()
65 | })
66 | },
67 | async (params) => {
68 | // Make API call to Workato
69 | const response = await fetch('https://www.workato.com/api/recipes', {
70 | method: 'POST',
71 | headers: {
72 | 'Authorization': 'Bearer ' + process.env.WORKATO_API_TOKEN,
73 | 'Content-Type': 'application/json'
74 | },
75 | body: JSON.stringify(params)
76 | });
77 |
78 | const data = await response.json();
79 | return {
80 | content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
81 | };
82 | }
83 | );
84 |
85 | // Add start-recipe tool
86 | server.tool(
87 | "start-recipe",
88 | {
89 | id: z.number().int()
90 | },
91 | async (params) => {
92 | // Make API call to Workato
93 | const response = await fetch(`https://www.workato.com/api/recipes/${params.id}/start`, {
94 | method: 'PUT',
95 | headers: {
96 | 'Authorization': 'Bearer ' + process.env.WORKATO_API_TOKEN
97 | }
98 | });
99 |
100 | const data = await response.json();
101 | return {
102 | content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
103 | };
104 | }
105 | );
106 |
107 | // Add stop-recipe tool
108 | server.tool(
109 | "stop-recipe",
110 | {
111 | id: z.number().int()
112 | },
113 | async (params) => {
114 | // Make API call to Workato
115 | const response = await fetch(`https://www.workato.com/api/recipes/${params.id}/stop`, {
116 | method: 'PUT',
117 | headers: {
118 | 'Authorization': 'Bearer ' + process.env.WORKATO_API_TOKEN
119 | }
120 | });
121 |
122 | const data = await response.json();
123 | return {
124 | content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
125 | };
126 | }
127 | );
128 |
129 | // Add list-connections tool
130 | server.tool(
131 | "list-connections",
132 | {
133 | folder_id: z.string().optional(),
134 | parent_id: z.string().optional(),
135 | external_id: z.string().optional(),
136 | include_runtime_connections: z.string().optional(),
137 | includes: z.array(z.string()).optional()
138 | },
139 | async (params) => {
140 | // Construct query parameters
141 | const queryParams = new URLSearchParams();
142 | Object.entries(params).forEach(([key, value]) => {
143 | if (value !== undefined) {
144 | if (Array.isArray(value)) {
145 | value.forEach(v => queryParams.append(`${key}[]`, v));
146 | } else {
147 | queryParams.append(key, String(value));
148 | }
149 | }
150 | });
151 |
152 | // Make API call to Workato
153 | const response = await fetch(`https://www.workato.com/api/connections?${queryParams.toString()}`, {
154 | headers: {
155 | 'Authorization': 'Bearer ' + process.env.WORKATO_API_TOKEN
156 | }
157 | });
158 |
159 | const data = await response.json();
160 | return {
161 | content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
162 | };
163 | }
164 | );
165 |
166 | // Add create-connection tool
167 | server.tool(
168 | "create-connection",
169 | {
170 | name: z.string().optional(),
171 | provider: z.string().optional(),
172 | parent_id: z.string().optional(),
173 | folder_id: z.string().optional(),
174 | external_id: z.string().optional(),
175 | shell_connection: z.boolean().optional(),
176 | input: z.record(z.any()).optional()
177 | },
178 | async (params) => {
179 | // Make API call to Workato
180 | const response = await fetch('https://www.workato.com/api/connections', {
181 | method: 'POST',
182 | headers: {
183 | 'Authorization': 'Bearer ' + process.env.WORKATO_API_TOKEN,
184 | 'Content-Type': 'application/json'
185 | },
186 | body: JSON.stringify(params)
187 | });
188 |
189 | const data = await response.json();
190 | return {
191 | content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
192 | };
193 | }
194 | );
195 |
196 | // Add list-connectors tool
197 | server.tool(
198 | "list-connectors",
199 | {
200 | applications: z.string()
201 | },
202 | async (params) => {
203 | // Construct query parameters
204 | const queryParams = new URLSearchParams();
205 | queryParams.append('applications', params.applications);
206 |
207 | // Make API call to Workato
208 | const response = await fetch(`https://www.workato.com/api/integrations?${queryParams.toString()}`, {
209 | headers: {
210 | 'Authorization': 'Bearer ' + process.env.WORKATO_API_TOKEN
211 | }
212 | });
213 |
214 | const data = await response.json();
215 | return {
216 | content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
217 | };
218 | }
219 | );
220 |
221 | // Add list-all-connectors tool
222 | server.tool(
223 | "list-all-connectors",
224 | {
225 | page: z.number().int().min(1).optional().default(1),
226 | per_page: z.number().int().min(1).max(100).optional().default(100)
227 | },
228 | async (params) => {
229 | // Construct query parameters
230 | const queryParams = new URLSearchParams();
231 | Object.entries(params).forEach(([key, value]) => {
232 | if (value !== undefined) {
233 | queryParams.append(key, String(value));
234 | }
235 | });
236 |
237 | // Make API call to Workato
238 | const response = await fetch(`https://www.workato.com/api/integrations/all?${queryParams.toString()}`, {
239 | headers: {
240 | 'Authorization': 'Bearer ' + process.env.WORKATO_API_TOKEN
241 | }
242 | });
243 |
244 | const data = await response.json();
245 | return {
246 | content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
247 | };
248 | }
249 | );
250 |
251 | // Add list-folders tool
252 | server.tool(
253 | "list-folders",
254 | {
255 | parent_id: z.string().optional(),
256 | page: z.number().int().min(1).optional().default(1),
257 | per_page: z.number().int().min(1).max(100).optional().default(100)
258 | },
259 | async (params) => {
260 | // Construct query parameters
261 | const queryParams = new URLSearchParams();
262 | Object.entries(params).forEach(([key, value]) => {
263 | if (value !== undefined) {
264 | queryParams.append(key, String(value));
265 | }
266 | });
267 |
268 | // Make API call to Workato
269 | const response = await fetch(`https://www.workato.com/api/folders?${queryParams.toString()}`, {
270 | headers: {
271 | 'Authorization': 'Bearer ' + process.env.WORKATO_API_TOKEN
272 | }
273 | });
274 |
275 | const data = await response.json();
276 | return {
277 | content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
278 | };
279 | }
280 | );
281 |
282 | // Add list-projects tool
283 | server.tool(
284 | "list-projects",
285 | {
286 | page: z.number().int().min(1).optional().default(1),
287 | per_page: z.number().int().min(1).max(100).optional().default(100)
288 | },
289 | async (params) => {
290 | // Construct query parameters
291 | const queryParams = new URLSearchParams();
292 | Object.entries(params).forEach(([key, value]) => {
293 | if (value !== undefined) {
294 | queryParams.append(key, String(value));
295 | }
296 | });
297 |
298 | // Make API call to Workato
299 | const response = await fetch(`https://www.workato.com/api/projects?${queryParams.toString()}`, {
300 | headers: {
301 | 'Authorization': 'Bearer ' + process.env.WORKATO_API_TOKEN
302 | }
303 | });
304 |
305 | const data = await response.json();
306 | return {
307 | content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
308 | };
309 | }
310 | );
311 |
312 | // Add create-folder tool
313 | server.tool(
314 | "create-folder",
315 | {
316 | name: z.string(),
317 | parent_id: z.string().optional()
318 | },
319 | async (params) => {
320 | // Make API call to Workato
321 | const response = await fetch('https://www.workato.com/api/folders', {
322 | method: 'POST',
323 | headers: {
324 | 'Authorization': 'Bearer ' + process.env.WORKATO_API_TOKEN,
325 | 'Content-Type': 'application/json'
326 | },
327 | body: JSON.stringify(params)
328 | });
329 |
330 | const data = await response.json();
331 | return {
332 | content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
333 | };
334 | }
335 | );
336 |
337 | // Add update-folder tool
338 | server.tool(
339 | "update-folder",
340 | {
341 | folder_id: z.string(),
342 | name: z.string().optional(),
343 | parent_id: z.string().optional()
344 | },
345 | async (params) => {
346 | const { folder_id, ...updateParams } = params;
347 |
348 | // Make API call to Workato
349 | const response = await fetch(`https://www.workato.com/api/folders/${folder_id}`, {
350 | method: 'PUT',
351 | headers: {
352 | 'Authorization': 'Bearer ' + process.env.WORKATO_API_TOKEN,
353 | 'Content-Type': 'application/json'
354 | },
355 | body: JSON.stringify(updateParams)
356 | });
357 |
358 | const data = await response.json();
359 | return {
360 | content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
361 | };
362 | }
363 | );
364 |
365 | // Add update-project tool
366 | server.tool(
367 | "update-project",
368 | {
369 | project_id: z.string(),
370 | name: z.string(),
371 | description: z.string().optional()
372 | },
373 | async (params) => {
374 | const { project_id, ...updateParams } = params;
375 |
376 | // Make API call to Workato
377 | const response = await fetch(`https://www.workato.com/api/projects/${project_id}`, {
378 | method: 'PUT',
379 | headers: {
380 | 'Authorization': 'Bearer ' + process.env.WORKATO_API_TOKEN,
381 | 'Content-Type': 'application/json'
382 | },
383 | body: JSON.stringify(updateParams)
384 | });
385 |
386 | const data = await response.json();
387 | return {
388 | content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
389 | };
390 | }
391 | );
392 |
393 | // Add list-recipe-jobs tool
394 | server.tool(
395 | "list-recipe-jobs",
396 | {
397 | recipe_id: z.number().int(),
398 | offset_job_id: z.string().optional(),
399 | prev: z.boolean().optional().default(false),
400 | status: z.enum(["succeeded", "failed", "pending"]).optional(),
401 | rerun_only: z.boolean().optional()
402 | },
403 | async (params) => {
404 | // Construct query parameters
405 | const queryParams = new URLSearchParams();
406 | Object.entries(params).forEach(([key, value]) => {
407 | if (value !== undefined && key !== 'recipe_id') {
408 | queryParams.append(key, String(value));
409 | }
410 | });
411 |
412 | // Make API call to Workato
413 | const response = await fetch(`https://www.workato.com/api/recipes/${params.recipe_id}/jobs?${queryParams.toString()}`, {
414 | headers: {
415 | 'Authorization': 'Bearer ' + process.env.WORKATO_API_TOKEN
416 | }
417 | });
418 |
419 | const data = await response.json();
420 | return {
421 | content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
422 | };
423 | }
424 | );
425 |
426 | // Add get-job tool
427 | server.tool(
428 | "get-job",
429 | {
430 | recipe_id: z.number().int(),
431 | job_handle: z.string()
432 | },
433 | async (params) => {
434 | // Make API call to Workato
435 | const response = await fetch(`https://www.workato.com/api/recipes/${params.recipe_id}/jobs/${params.job_handle}`, {
436 | headers: {
437 | 'Authorization': 'Bearer ' + process.env.WORKATO_API_TOKEN
438 | }
439 | });
440 |
441 | const data = await response.json();
442 | return {
443 | content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
444 | };
445 | }
446 | );
447 |
448 | // Add resume-job tool
449 | server.tool(
450 | "resume-job",
451 | {
452 | token: z.string(),
453 | data: z.record(z.any()).optional()
454 | },
455 | async (params) => {
456 | // Make API call to Workato
457 | const response = await fetch('https://www.workato.com/api/job/resume', {
458 | method: 'POST',
459 | headers: {
460 | 'Authorization': 'Bearer ' + process.env.WORKATO_API_TOKEN,
461 | 'Content-Type': 'application/json'
462 | },
463 | body: JSON.stringify(params)
464 | });
465 |
466 | // Since this endpoint returns 204 with no content, we'll return a success message
467 | return {
468 | content: [{ type: "text", text: "Job resumed successfully" }]
469 | };
470 | }
471 | );
472 |
473 | // Add list-api-endpoints tool
474 | server.tool(
475 | "list-api-endpoints",
476 | {
477 | api_collection_id: z.string().optional(),
478 | per_page: z.number().int().min(1).max(100).optional().default(100),
479 | page: z.number().int().min(1).optional().default(1)
480 | },
481 | async (params) => {
482 | // Construct query parameters
483 | const queryParams = new URLSearchParams();
484 | Object.entries(params).forEach(([key, value]) => {
485 | if (value !== undefined) {
486 | queryParams.append(key, String(value));
487 | }
488 | });
489 |
490 | // Make API call to Workato
491 | const response = await fetch(`https://www.workato.com/api/api_endpoints?${queryParams.toString()}`, {
492 | headers: {
493 | 'Authorization': 'Bearer ' + process.env.WORKATO_API_TOKEN
494 | }
495 | });
496 |
497 | const data = await response.json();
498 | return {
499 | content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
500 | };
501 | }
502 | );
503 |
504 | // Add manage-tags tool
505 | server.tool(
506 | "manage-tags",
507 | {
508 | add_tags: z.array(z.string()).optional(),
509 | remove_tags: z.array(z.string()).optional(),
510 | recipe_ids: z.array(z.number()).optional(),
511 | connection_ids: z.array(z.number()).optional()
512 | },
513 | async (params) => {
514 | // Make API call to Workato
515 | const response = await fetch('https://www.workato.com/api/tags_assignments', {
516 | method: 'POST',
517 | headers: {
518 | 'Authorization': 'Bearer ' + process.env.WORKATO_API_TOKEN,
519 | 'Content-Type': 'application/json'
520 | },
521 | body: JSON.stringify(params)
522 | });
523 |
524 | const data = await response.json();
525 | return {
526 | content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
527 | };
528 | }
529 | );
530 |
531 | // Update list-tags tool with full parameters
532 | server.tool(
533 | "list-tags",
534 | {
535 | page: z.number().int().min(1).optional().default(1),
536 | per_page: z.number().int().min(1).max(100).optional().default(100),
537 | 'q[title_or_description_cont]': z.string().optional(),
538 | 'q[handle_in]': z.array(z.string()).optional(),
539 | 'q[author_id_eq]': z.number().optional(),
540 | 'q[recipe_id_eq]': z.number().optional(),
541 | 'q[connection_id_eq]': z.number().optional(),
542 | 'q[only_assigned]': z.boolean().optional(),
543 | 'sort_by[]': z.array(z.enum(['title', 'assignment_count', 'updated_at', 'last_assigned_at'])).optional(),
544 | 'sort_direction[]': z.array(z.enum(['asc', 'desc'])).optional(),
545 | 'includes[]': z.array(z.enum(['assignment_count', 'author'])).optional()
546 | },
547 | async (params) => {
548 | // Construct query parameters
549 | const queryParams = new URLSearchParams();
550 | Object.entries(params).forEach(([key, value]) => {
551 | if (value !== undefined) {
552 | if (Array.isArray(value)) {
553 | value.forEach(v => queryParams.append(key, String(v)));
554 | } else {
555 | queryParams.append(key, String(value));
556 | }
557 | }
558 | });
559 |
560 | // Make API call to Workato
561 | const response = await fetch(`https://www.workato.com/api/tags?${queryParams.toString()}`, {
562 | headers: {
563 | 'Authorization': 'Bearer ' + process.env.WORKATO_API_TOKEN
564 | }
565 | });
566 |
567 | const data = await response.json();
568 | return {
569 | content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
570 | };
571 | }
572 | );
573 |
574 | // Add create-tag tool
575 | server.tool(
576 | "create-tag",
577 | {
578 | title: z.string().max(30),
579 | description: z.string().max(150).optional(),
580 | color: z.enum(['blue', 'violet', 'green', 'red', 'orange', 'gold', 'indigo', 'brown', 'teal', 'plum', 'slate', 'neutral']).optional()
581 | },
582 | async (params) => {
583 | // Make API call to Workato
584 | const response = await fetch('https://www.workato.com/api/tags', {
585 | method: 'POST',
586 | headers: {
587 | 'Authorization': 'Bearer ' + process.env.WORKATO_API_TOKEN,
588 | 'Content-Type': 'application/json'
589 | },
590 | body: JSON.stringify(params)
591 | });
592 |
593 | const data = await response.json();
594 | return {
595 | content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
596 | };
597 | }
598 | );
599 |
600 | // Add update-tag tool
601 | server.tool(
602 | "update-tag",
603 | {
604 | handle: z.string(),
605 | title: z.string().max(30),
606 | description: z.string().max(150).optional(),
607 | color: z.enum(['blue', 'violet', 'green', 'red', 'orange', 'gold', 'indigo', 'brown', 'teal', 'plum', 'slate', 'neutral']).optional()
608 | },
609 | async (params) => {
610 | const { handle, ...updateParams } = params;
611 |
612 | // Make API call to Workato
613 | const response = await fetch(`https://www.workato.com/api/tags/${handle}`, {
614 | method: 'PUT',
615 | headers: {
616 | 'Authorization': 'Bearer ' + process.env.WORKATO_API_TOKEN,
617 | 'Content-Type': 'application/json'
618 | },
619 | body: JSON.stringify(updateParams)
620 | });
621 |
622 | const data = await response.json();
623 | return {
624 | content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
625 | };
626 | }
627 | );
628 |
629 | // Add delete-tag tool
630 | server.tool(
631 | "delete-tag",
632 | {
633 | handle: z.string()
634 | },
635 | async (params) => {
636 | // Make API call to Workato
637 | const response = await fetch(`https://www.workato.com/api/tags/${params.handle}`, {
638 | method: 'DELETE',
639 | headers: {
640 | 'Authorization': 'Bearer ' + process.env.WORKATO_API_TOKEN
641 | }
642 | });
643 |
644 | return {
645 | content: [{ type: "text", text: "Tag deleted successfully" }]
646 | };
647 | }
648 | );
649 |
650 | // Add list-activity-logs tool
651 | server.tool(
652 | "list-activity-logs",
653 | {
654 | 'page[after]': z.number().int().optional(),
655 | 'page[size]': z.number().int().min(1).max(100).optional().default(100),
656 | from: z.string().regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/).optional(),
657 | to: z.string().regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/).optional(),
658 | 'users_ids[]': z.array(z.number()).optional(),
659 | 'include_resource_types[]': z.array(z.string()).optional(),
660 | 'exclude_resource_types[]': z.array(z.string()).optional(),
661 | 'include_event_types[]': z.array(z.string()).optional(),
662 | 'exclude_event_types[]': z.array(z.string()).optional()
663 | },
664 | async (params) => {
665 | // Construct query parameters
666 | const queryParams = new URLSearchParams();
667 | Object.entries(params).forEach(([key, value]) => {
668 | if (value !== undefined) {
669 | if (Array.isArray(value)) {
670 | value.forEach(v => queryParams.append(key, String(v)));
671 | } else {
672 | queryParams.append(key, String(value));
673 | }
674 | }
675 | });
676 |
677 | // Make API call to Workato
678 | const response = await fetch(`https://www.workato.com/api/activity_logs?${queryParams.toString()}`, {
679 | headers: {
680 | 'Authorization': 'Bearer ' + process.env.WORKATO_API_TOKEN
681 | }
682 | });
683 |
684 | const data = await response.json();
685 | return {
686 | content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
687 | };
688 | }
689 | );
690 |
691 | // Start receiving messages on stdin and sending messages on stdout
692 | const transport = new StdioServerTransport();
693 | await server.connect(transport);
```