#
tokens: 9066/50000 5/5 files
lines: on (toggle) GitHub
raw markdown copy reset
# 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); 
```