@aiconnect/agentjobs-mcp 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +11 -0
- package/README.md +311 -0
- package/build/cancel_job.js +71 -0
- package/build/config.js +6 -0
- package/build/create_job.js +151 -0
- package/build/get_job.js +62 -0
- package/build/index.js +83 -0
- package/build/list_jobs.js +88 -0
- package/docs/agent-jobs-api.md +336 -0
- package/docs/guidelines.md +267 -0
- package/package.json +68 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
import { config } from './config.js';
|
|
4
|
+
// Define the schema for job status based on docs/agent-jobs-api.md:246-251
|
|
5
|
+
const jobStatusSchema = z.enum([
|
|
6
|
+
"waiting",
|
|
7
|
+
"scheduled",
|
|
8
|
+
"running",
|
|
9
|
+
"completed",
|
|
10
|
+
"failed",
|
|
11
|
+
"canceled"
|
|
12
|
+
]);
|
|
13
|
+
export default (server) => {
|
|
14
|
+
server.tool("list_jobs", "Retrieves a list of agent jobs, with optional filters and pagination.", {
|
|
15
|
+
org_id: z.string().optional().describe("Filter by organization ID. If not provided, uses the default organization."),
|
|
16
|
+
status: jobStatusSchema.optional().describe("Filter by job status."),
|
|
17
|
+
scheduled_at: z.string().datetime().optional().describe("Filter by exact scheduled time (ISO 8601)."),
|
|
18
|
+
scheduled_at_gte: z.string().datetime().optional().describe("Filter by scheduled time greater than or equal to (ISO 8601)."),
|
|
19
|
+
scheduled_at_lte: z.string().datetime().optional().describe("Filter by scheduled time less than or equal to (ISO 8601)."),
|
|
20
|
+
created_at_gte: z.string().datetime().optional().describe("Filter by creation time greater than or equal to (ISO 8601)."),
|
|
21
|
+
created_at_lte: z.string().datetime().optional().describe("Filter by creation time less than or equal to (ISO 8601)."),
|
|
22
|
+
job_type_id: z.string().optional().describe("Filter by job type ID."),
|
|
23
|
+
channel_code: z.string().optional().describe("Filter by channel code."),
|
|
24
|
+
limit: z.number().int().positive().optional().describe("Maximum number of jobs to return."),
|
|
25
|
+
offset: z.number().int().nonnegative().optional().describe("Number of jobs to skip (for pagination)."),
|
|
26
|
+
sort: z.string().optional().describe("Sorting field and direction (e.g., created_at:desc)."),
|
|
27
|
+
}, async (params) => {
|
|
28
|
+
const apiUrl = config.AICONNECT_API_URL;
|
|
29
|
+
const apiKey = config.AICONNECT_API_KEY;
|
|
30
|
+
if (!apiUrl) {
|
|
31
|
+
return {
|
|
32
|
+
content: [{
|
|
33
|
+
type: "text",
|
|
34
|
+
text: "Error: API URL is not configured. Please set AICONNECT_API_URL environment variable."
|
|
35
|
+
}]
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (!apiKey) {
|
|
39
|
+
return {
|
|
40
|
+
content: [{
|
|
41
|
+
type: "text",
|
|
42
|
+
text: "Error: API Key is not configured. Please set AICONNECT_API_KEY environment variable."
|
|
43
|
+
}]
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const endpoint = `${apiUrl}/services/agent-jobs`;
|
|
47
|
+
const headers = {
|
|
48
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
49
|
+
};
|
|
50
|
+
// Build query parameters object from provided params
|
|
51
|
+
const queryParams = {};
|
|
52
|
+
for (const [key, value] of Object.entries(params)) {
|
|
53
|
+
if (value !== undefined) {
|
|
54
|
+
queryParams[key] = value;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
const response = await axios.get(endpoint, {
|
|
59
|
+
headers,
|
|
60
|
+
params: queryParams, // Axios uses 'params' for query parameters in GET requests
|
|
61
|
+
});
|
|
62
|
+
// Return the data part of the response, stringified as JSON text
|
|
63
|
+
// API docs show jobs under 'data' key, and meta for pagination
|
|
64
|
+
return {
|
|
65
|
+
content: [{
|
|
66
|
+
type: "text",
|
|
67
|
+
text: JSON.stringify(response.data, null, 2),
|
|
68
|
+
}]
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
let errorMessage = `Failed to list jobs.`;
|
|
73
|
+
if (axios.isAxiosError(error) && error.response) {
|
|
74
|
+
const apiError = error.response.data?.message || error.response.data?.error || JSON.stringify(error.response.data);
|
|
75
|
+
errorMessage = `API Error (${error.response.status}): ${apiError || error.message}`;
|
|
76
|
+
}
|
|
77
|
+
else if (error instanceof Error) {
|
|
78
|
+
errorMessage = `Error: ${error.message}`;
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
content: [{
|
|
82
|
+
type: "text",
|
|
83
|
+
text: errorMessage,
|
|
84
|
+
}]
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
};
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
# Agent Jobs API Endpoints
|
|
2
|
+
|
|
3
|
+
This document describes the REST API endpoints available for the Agent Jobs module. These endpoints allow you to create, retrieve, and manage agent jobs programmatically.
|
|
4
|
+
|
|
5
|
+
## Base URL
|
|
6
|
+
|
|
7
|
+
All endpoints are prefixed with `/services/agent-jobs`.
|
|
8
|
+
|
|
9
|
+
## Authentication
|
|
10
|
+
|
|
11
|
+
All endpoints require authentication using a valid app token with the appropriate access level:
|
|
12
|
+
|
|
13
|
+
- READ access to the SERVICES scope is required for GET operations
|
|
14
|
+
- WRITE access to the SERVICES scope is required for POST and DELETE operations
|
|
15
|
+
|
|
16
|
+
## Endpoints
|
|
17
|
+
|
|
18
|
+
### Create a Job
|
|
19
|
+
|
|
20
|
+
Creates a new agent job.
|
|
21
|
+
|
|
22
|
+
**Endpoint:** `POST /services/agent-jobs`
|
|
23
|
+
|
|
24
|
+
**Access Level Required:** WRITE access to SERVICES scope
|
|
25
|
+
|
|
26
|
+
**Request Body:**
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"target_channel": {
|
|
31
|
+
"org_id": "string",
|
|
32
|
+
"platform": "string",
|
|
33
|
+
"type": "string",
|
|
34
|
+
"code": "string",
|
|
35
|
+
"data": {}
|
|
36
|
+
},
|
|
37
|
+
"job_type_id": "string",
|
|
38
|
+
"config": {
|
|
39
|
+
"max_follow_ups": "number",
|
|
40
|
+
"max_task_retries": "number",
|
|
41
|
+
"task_retry_interval": "number",
|
|
42
|
+
"start_prompt": "string",
|
|
43
|
+
"max_time_to_complete": "number",
|
|
44
|
+
"profile_id": "string"
|
|
45
|
+
},
|
|
46
|
+
"params": {},
|
|
47
|
+
"scheduled_at": "string" // Optional ISO 8601 date string
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Query Parameters:**
|
|
52
|
+
|
|
53
|
+
- `delay` (optional): A non-negative integer representing the maximum random delay in minutes to add to the scheduled time
|
|
54
|
+
|
|
55
|
+
**Response:**
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"data": {
|
|
60
|
+
"job_id": "string",
|
|
61
|
+
"org_id": "string",
|
|
62
|
+
"channel_code": "string",
|
|
63
|
+
"job_type_id": "string",
|
|
64
|
+
"job_status": "string",
|
|
65
|
+
"created_at": "string",
|
|
66
|
+
"updated_at": "string",
|
|
67
|
+
"scheduled_at": "string",
|
|
68
|
+
"tasks": [],
|
|
69
|
+
"result": null,
|
|
70
|
+
"params": {},
|
|
71
|
+
"config": {}
|
|
72
|
+
},
|
|
73
|
+
"meta": {
|
|
74
|
+
"org_id": "string",
|
|
75
|
+
"id": "string"
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Status Codes:**
|
|
81
|
+
|
|
82
|
+
- 201: Job created successfully
|
|
83
|
+
- 400: Bad request (missing required fields or invalid format)
|
|
84
|
+
- 401: Authentication required
|
|
85
|
+
- 404: Job type or organization not found
|
|
86
|
+
|
|
87
|
+
### Get Jobs
|
|
88
|
+
|
|
89
|
+
Retrieves a list of jobs for the authenticated organization.
|
|
90
|
+
|
|
91
|
+
**Endpoint:** `GET /services/agent-jobs`
|
|
92
|
+
|
|
93
|
+
**Access Level Required:** READ access to SERVICES scope
|
|
94
|
+
|
|
95
|
+
**Query Parameters:**
|
|
96
|
+
|
|
97
|
+
- `status`: Filter by job status (WAITING, RUNNING, COMPLETED, FAILED, CANCELED)
|
|
98
|
+
- `scheduled_at`: Filter by scheduled time
|
|
99
|
+
- `scheduled_at_gte`: Filter by scheduled time greater than or equal to
|
|
100
|
+
- `scheduled_at_lte`: Filter by scheduled time less than or equal to
|
|
101
|
+
- `created_at_gte`: Filter by creation time greater than or equal to
|
|
102
|
+
- `created_at_lte`: Filter by creation time less than or equal to
|
|
103
|
+
- `job_type_id`: Filter by job type ID
|
|
104
|
+
- `channel_code`: Filter by channel code
|
|
105
|
+
- `limit`: Maximum number of jobs to return (pagination)
|
|
106
|
+
- `offset`: Number of jobs to skip (pagination)
|
|
107
|
+
- `sort`: Sorting field and direction (e.g., `created_at:desc`)
|
|
108
|
+
|
|
109
|
+
**Response:**
|
|
110
|
+
|
|
111
|
+
```json
|
|
112
|
+
{
|
|
113
|
+
"data": [
|
|
114
|
+
{
|
|
115
|
+
"job_id": "string",
|
|
116
|
+
"org_id": "string",
|
|
117
|
+
"channel_code": "string",
|
|
118
|
+
"job_type_id": "string",
|
|
119
|
+
"job_status": "string",
|
|
120
|
+
"created_at": "string",
|
|
121
|
+
"updated_at": "string",
|
|
122
|
+
"scheduled_at": "string",
|
|
123
|
+
"tasks": [],
|
|
124
|
+
"result": null,
|
|
125
|
+
"params": {},
|
|
126
|
+
"config": {}
|
|
127
|
+
}
|
|
128
|
+
],
|
|
129
|
+
"meta": {
|
|
130
|
+
"org_id": "string",
|
|
131
|
+
"limit": "number",
|
|
132
|
+
"offset": "number",
|
|
133
|
+
"total": "number",
|
|
134
|
+
"sort": [
|
|
135
|
+
{
|
|
136
|
+
"field": "string",
|
|
137
|
+
"direction": "string"
|
|
138
|
+
}
|
|
139
|
+
]
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Status Codes:**
|
|
145
|
+
|
|
146
|
+
- 200: Success
|
|
147
|
+
- 401: Authentication required
|
|
148
|
+
|
|
149
|
+
### Get Job by ID
|
|
150
|
+
|
|
151
|
+
Retrieves a specific job by its ID.
|
|
152
|
+
|
|
153
|
+
**Endpoint:** `GET /services/agent-jobs/:id`
|
|
154
|
+
|
|
155
|
+
**Access Level Required:** READ access to SERVICES scope
|
|
156
|
+
|
|
157
|
+
**URL Parameters:**
|
|
158
|
+
|
|
159
|
+
- `id`: The ID of the job to retrieve
|
|
160
|
+
|
|
161
|
+
**Response:**
|
|
162
|
+
|
|
163
|
+
```json
|
|
164
|
+
{
|
|
165
|
+
"data": {
|
|
166
|
+
"job_id": "string",
|
|
167
|
+
"org_id": "string",
|
|
168
|
+
"channel_code": "string",
|
|
169
|
+
"job_type_id": "string",
|
|
170
|
+
"job_status": "string",
|
|
171
|
+
"created_at": "string",
|
|
172
|
+
"updated_at": "string",
|
|
173
|
+
"scheduled_at": "string",
|
|
174
|
+
"tasks": [
|
|
175
|
+
{
|
|
176
|
+
"task_id": "string",
|
|
177
|
+
"created_at": "string",
|
|
178
|
+
"status": "string",
|
|
179
|
+
"result": "string"
|
|
180
|
+
}
|
|
181
|
+
],
|
|
182
|
+
"result": "string",
|
|
183
|
+
"params": {},
|
|
184
|
+
"config": {}
|
|
185
|
+
},
|
|
186
|
+
"meta": {
|
|
187
|
+
"org_id": "string",
|
|
188
|
+
"id": "string"
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Status Codes:**
|
|
194
|
+
|
|
195
|
+
- 200: Success
|
|
196
|
+
- 400: Bad request (missing job ID)
|
|
197
|
+
- 401: Authentication required
|
|
198
|
+
- 403: Forbidden (job belongs to a different organization)
|
|
199
|
+
- 404: Job not found
|
|
200
|
+
|
|
201
|
+
### Cancel Job
|
|
202
|
+
|
|
203
|
+
Cancels a job by changing its status to CANCELED.
|
|
204
|
+
|
|
205
|
+
**Endpoint:** `DELETE /services/agent-jobs/:id`
|
|
206
|
+
|
|
207
|
+
**Access Level Required:** WRITE access to SERVICES scope
|
|
208
|
+
|
|
209
|
+
**URL Parameters:**
|
|
210
|
+
|
|
211
|
+
- `id`: The ID of the job to cancel
|
|
212
|
+
|
|
213
|
+
**Request Body (optional):**
|
|
214
|
+
|
|
215
|
+
```json
|
|
216
|
+
{
|
|
217
|
+
"reason": "string" // Optional reason for cancellation
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
**Response:**
|
|
222
|
+
|
|
223
|
+
```json
|
|
224
|
+
{
|
|
225
|
+
"meta": {
|
|
226
|
+
"org_id": "string",
|
|
227
|
+
"job_id": "string"
|
|
228
|
+
},
|
|
229
|
+
"message": "Job with ID '{job_id}' successfully canceled"
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**Status Codes:**
|
|
234
|
+
|
|
235
|
+
- 200: Job successfully canceled
|
|
236
|
+
- 400: Bad request (missing job ID)
|
|
237
|
+
- 401: Authentication required
|
|
238
|
+
- 403: Forbidden (job belongs to a different organization)
|
|
239
|
+
- 404: Job not found
|
|
240
|
+
- 409: Conflict (job is already in a terminal state)
|
|
241
|
+
|
|
242
|
+
## Job Status Values
|
|
243
|
+
|
|
244
|
+
Jobs can have the following status values:
|
|
245
|
+
|
|
246
|
+
- `WAITING`: Job is waiting to be executed
|
|
247
|
+
- `SCHEDULED`: Job is scheduled for future execution
|
|
248
|
+
- `RUNNING`: Job is currently running
|
|
249
|
+
- `COMPLETED`: Job has completed successfully
|
|
250
|
+
- `FAILED`: Job has failed
|
|
251
|
+
- `CANCELED`: Job was canceled
|
|
252
|
+
|
|
253
|
+
## Examples
|
|
254
|
+
|
|
255
|
+
### Creating a Job for Immediate Execution
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
curl -X POST https://api.example.com/services/agent-jobs \
|
|
259
|
+
-H "Authorization: Bearer YOUR_TOKEN" \
|
|
260
|
+
-H "Content-Type: application/json" \
|
|
261
|
+
-d '{
|
|
262
|
+
"target_channel": {
|
|
263
|
+
"org_id": "org123",
|
|
264
|
+
"platform": "slack",
|
|
265
|
+
"type": "channel",
|
|
266
|
+
"code": "C123456",
|
|
267
|
+
"data": {
|
|
268
|
+
"channel_id": "C123456",
|
|
269
|
+
"team_id": "T123456"
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
"job_type_id": "daily-report",
|
|
273
|
+
"config": {
|
|
274
|
+
"max_follow_ups": 3,
|
|
275
|
+
"max_task_retries": 2,
|
|
276
|
+
"task_retry_interval": 5,
|
|
277
|
+
"max_time_to_complete": 60,
|
|
278
|
+
"profile_id": "profile123"
|
|
279
|
+
},
|
|
280
|
+
"params": {
|
|
281
|
+
"report_type": "daily",
|
|
282
|
+
"include_metrics": true
|
|
283
|
+
}
|
|
284
|
+
}'
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Creating a Scheduled Job
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
curl -X POST https://api.example.com/services/agent-jobs \
|
|
291
|
+
-H "Authorization: Bearer YOUR_TOKEN" \
|
|
292
|
+
-H "Content-Type: application/json" \
|
|
293
|
+
-d '{
|
|
294
|
+
"target_channel": {
|
|
295
|
+
"org_id": "org123",
|
|
296
|
+
"platform": "slack",
|
|
297
|
+
"type": "channel",
|
|
298
|
+
"code": "C123456",
|
|
299
|
+
"data": {
|
|
300
|
+
"channel_id": "C123456",
|
|
301
|
+
"team_id": "T123456"
|
|
302
|
+
}
|
|
303
|
+
},
|
|
304
|
+
"job_type_id": "daily-report",
|
|
305
|
+
"config": {
|
|
306
|
+
"max_follow_ups": 3,
|
|
307
|
+
"max_task_retries": 2,
|
|
308
|
+
"task_retry_interval": 5,
|
|
309
|
+
"max_time_to_complete": 60,
|
|
310
|
+
"profile_id": "profile123"
|
|
311
|
+
},
|
|
312
|
+
"params": {
|
|
313
|
+
"report_type": "daily",
|
|
314
|
+
"include_metrics": true
|
|
315
|
+
},
|
|
316
|
+
"scheduled_at": "2023-12-31T09:00:00Z"
|
|
317
|
+
}'
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Retrieving Jobs with Filtering
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
curl -X GET "https://api.example.com/services/agent-jobs?status=RUNNING&job_type_id=daily-report&limit=10&offset=0&sort=created_at:desc" \
|
|
324
|
+
-H "Authorization: Bearer YOUR_TOKEN"
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Canceling a Job
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
curl -X DELETE https://api.example.com/services/agent-jobs/job123 \
|
|
331
|
+
-H "Authorization: Bearer YOUR_TOKEN" \
|
|
332
|
+
-H "Content-Type: application/json" \
|
|
333
|
+
-d '{
|
|
334
|
+
"reason": "No longer needed"
|
|
335
|
+
}'
|
|
336
|
+
```
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# AI Connect MCP Server - Development Guidelines
|
|
2
|
+
|
|
3
|
+
This document outlines the development guidelines, standards, and best practices for the AI Connect MCP Server project.
|
|
4
|
+
|
|
5
|
+
This project is an MCP (Model Context Protocol) server that provides AI agents with the ability to interact with the AI Connect Jobs system from the AI Connect platform. It's built using Node.js, TypeScript, and follows the MCP specification from Anthropic.
|
|
6
|
+
|
|
7
|
+
## Environment Variables
|
|
8
|
+
|
|
9
|
+
Use the following environment variables for configuration:
|
|
10
|
+
|
|
11
|
+
- `AICONNECT_API_URL`: API endpoint URL (e.g., https://api.aiconnect.cloud/api/v0)
|
|
12
|
+
- `AICONNECT_API_KEY`: Your API authentication key
|
|
13
|
+
|
|
14
|
+
## Development Standards
|
|
15
|
+
|
|
16
|
+
### Code Style
|
|
17
|
+
|
|
18
|
+
- **Language**: TypeScript with strict mode enabled
|
|
19
|
+
- **Module System**: ES modules (ESM)
|
|
20
|
+
- **Code Formatting**: Use consistent indentation (2 spaces)
|
|
21
|
+
- **Naming Conventions**:
|
|
22
|
+
- Files: `snake_case.ts` for tools, `camelCase.ts` for utilities
|
|
23
|
+
- Functions: `camelCase`
|
|
24
|
+
- Constants: `UPPER_SNAKE_CASE`
|
|
25
|
+
- Types/Interfaces: `PascalCase`
|
|
26
|
+
|
|
27
|
+
### File Organization
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
src/
|
|
31
|
+
├── index.ts # Main server entry point
|
|
32
|
+
├── tools/ # MCP tools directory
|
|
33
|
+
│ ├── list_jobs.ts # Individual tool files
|
|
34
|
+
│ ├── get_job.ts
|
|
35
|
+
│ ├── create_job.ts
|
|
36
|
+
│ └── cancel_job.ts
|
|
37
|
+
├── types/ # Type definitions
|
|
38
|
+
├── utils/ # Utility functions
|
|
39
|
+
└── config/ # Configuration files
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Tool Development
|
|
43
|
+
|
|
44
|
+
#### Tool Structure
|
|
45
|
+
|
|
46
|
+
Each MCP tool should follow this pattern:
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import { z } from "zod";
|
|
50
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
51
|
+
|
|
52
|
+
export default (server: McpServer) => {
|
|
53
|
+
server.tool(
|
|
54
|
+
"tool_name",
|
|
55
|
+
"Clear description of what the tool does",
|
|
56
|
+
{
|
|
57
|
+
// Zod schema for parameters
|
|
58
|
+
param1: z.string({
|
|
59
|
+
description: "Description of parameter"
|
|
60
|
+
}),
|
|
61
|
+
param2: z.number().optional({
|
|
62
|
+
description: "Optional parameter description"
|
|
63
|
+
})
|
|
64
|
+
},
|
|
65
|
+
async (params) => {
|
|
66
|
+
try {
|
|
67
|
+
// Tool implementation
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
content: [{
|
|
71
|
+
type: "text",
|
|
72
|
+
text: "Response content"
|
|
73
|
+
}]
|
|
74
|
+
};
|
|
75
|
+
} catch (error) {
|
|
76
|
+
// Error handling
|
|
77
|
+
return {
|
|
78
|
+
content: [{
|
|
79
|
+
type: "text",
|
|
80
|
+
text: `Error: ${error.message}`
|
|
81
|
+
}],
|
|
82
|
+
isError: true
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
};
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
#### Tool Guidelines
|
|
91
|
+
|
|
92
|
+
1. **Single Responsibility**: Each tool should have one clear purpose
|
|
93
|
+
2. **Error Handling**: Always wrap tool logic in try-catch blocks
|
|
94
|
+
3. **Validation**: Use Zod schemas for parameter validation
|
|
95
|
+
4. **Documentation**: Provide clear descriptions for tools and parameters
|
|
96
|
+
5. **Response Format**: Return consistent response structures
|
|
97
|
+
|
|
98
|
+
### API Integration
|
|
99
|
+
|
|
100
|
+
#### HTTP Client Standards
|
|
101
|
+
|
|
102
|
+
- Use native `fetch` for HTTP requests
|
|
103
|
+
- Implement proper error handling for API calls
|
|
104
|
+
- Include appropriate headers (Authorization, Content-Type)
|
|
105
|
+
- Handle rate limiting and timeouts
|
|
106
|
+
|
|
107
|
+
#### Environment Variables
|
|
108
|
+
|
|
109
|
+
Required environment variables:
|
|
110
|
+
|
|
111
|
+
```env
|
|
112
|
+
DEFAULT_ORG_ID=<organization-id>
|
|
113
|
+
AICONNECT_API_KEY=<api-key>
|
|
114
|
+
AICONNECT_API_URL=<api-base-url>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Error Handling
|
|
118
|
+
|
|
119
|
+
#### Error Types
|
|
120
|
+
|
|
121
|
+
1. **Validation Errors**: Invalid parameters or missing required fields
|
|
122
|
+
2. **API Errors**: HTTP errors from AI Connect API
|
|
123
|
+
3. **Authentication Errors**: Invalid or expired API keys
|
|
124
|
+
4. **Network Errors**: Connection issues
|
|
125
|
+
|
|
126
|
+
#### Error Response Format
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
{
|
|
130
|
+
content: [{
|
|
131
|
+
type: "text",
|
|
132
|
+
text: "Error: [Category] - [Description]"
|
|
133
|
+
}],
|
|
134
|
+
isError: true
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Testing Guidelines
|
|
139
|
+
|
|
140
|
+
#### Test Structure
|
|
141
|
+
|
|
142
|
+
- Unit tests for individual tools
|
|
143
|
+
- Integration tests for API interactions
|
|
144
|
+
- Mock external dependencies
|
|
145
|
+
|
|
146
|
+
#### Test Files
|
|
147
|
+
|
|
148
|
+
- Place tests in `tests/` directory
|
|
149
|
+
- Name test files with `.test.ts` suffix
|
|
150
|
+
- Use descriptive test names
|
|
151
|
+
|
|
152
|
+
### Documentation
|
|
153
|
+
|
|
154
|
+
#### Code Documentation
|
|
155
|
+
|
|
156
|
+
- Use JSDoc comments for functions and classes
|
|
157
|
+
- Document complex logic with inline comments
|
|
158
|
+
- Keep documentation up to date with code changes
|
|
159
|
+
|
|
160
|
+
#### API Documentation
|
|
161
|
+
|
|
162
|
+
- Maintain API documentation in `docs/agent-jobs-api.md`
|
|
163
|
+
- Update tool documentation when adding new features
|
|
164
|
+
- Include usage examples
|
|
165
|
+
|
|
166
|
+
### Git Workflow
|
|
167
|
+
|
|
168
|
+
#### Branch Naming
|
|
169
|
+
|
|
170
|
+
- Feature branches: `feature/description`
|
|
171
|
+
- Bug fixes: `fix/description`
|
|
172
|
+
- Documentation: `docs/description`
|
|
173
|
+
|
|
174
|
+
#### Commit Messages
|
|
175
|
+
|
|
176
|
+
Follow conventional commit format:
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
type(scope): description
|
|
180
|
+
|
|
181
|
+
feat(tools): add list_jobs filtering capability
|
|
182
|
+
fix(api): handle timeout errors properly
|
|
183
|
+
docs(readme): update installation instructions
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
#### Pull Request Process
|
|
187
|
+
|
|
188
|
+
1. Create feature branch from `main`
|
|
189
|
+
2. Make changes with appropriate tests
|
|
190
|
+
3. Update documentation if needed
|
|
191
|
+
4. Submit PR with clear description
|
|
192
|
+
5. Address review feedback
|
|
193
|
+
6. Merge after approval
|
|
194
|
+
|
|
195
|
+
### Security
|
|
196
|
+
|
|
197
|
+
#### API Key Management
|
|
198
|
+
|
|
199
|
+
- Never commit API keys to version control
|
|
200
|
+
- Use environment variables for sensitive data
|
|
201
|
+
- Rotate API keys regularly
|
|
202
|
+
|
|
203
|
+
#### Input Validation
|
|
204
|
+
|
|
205
|
+
- Validate all user inputs using Zod schemas
|
|
206
|
+
- Sanitize data before API calls
|
|
207
|
+
- Implement proper authorization checks
|
|
208
|
+
|
|
209
|
+
### Performance
|
|
210
|
+
|
|
211
|
+
#### Best Practices
|
|
212
|
+
|
|
213
|
+
- Implement request caching where appropriate
|
|
214
|
+
- Use connection pooling for API calls
|
|
215
|
+
- Handle large datasets with pagination
|
|
216
|
+
- Optimize for minimal memory usage
|
|
217
|
+
|
|
218
|
+
### Deployment
|
|
219
|
+
|
|
220
|
+
#### Build Process
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
npm run build # Compile TypeScript
|
|
224
|
+
npm start # Run compiled server
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
#### Environment Setup
|
|
228
|
+
|
|
229
|
+
- Development: Use `.env` file
|
|
230
|
+
- Production: Set environment variables in deployment system
|
|
231
|
+
|
|
232
|
+
### Troubleshooting
|
|
233
|
+
|
|
234
|
+
#### Common Issues
|
|
235
|
+
|
|
236
|
+
1. **Connection Errors**: Check API URL and network connectivity
|
|
237
|
+
2. **Authentication Failures**: Verify API key and organization ID
|
|
238
|
+
3. **Tool Not Found**: Ensure tool is registered in `index.ts`
|
|
239
|
+
4. **Parameter Validation**: Check Zod schema definitions
|
|
240
|
+
|
|
241
|
+
#### Debugging
|
|
242
|
+
|
|
243
|
+
- Use console logging for development
|
|
244
|
+
- Implement structured logging for production
|
|
245
|
+
- Monitor API response times and error rates
|
|
246
|
+
|
|
247
|
+
## Contributing
|
|
248
|
+
|
|
249
|
+
### Code Review Checklist
|
|
250
|
+
|
|
251
|
+
- [ ] Code follows style guidelines
|
|
252
|
+
- [ ] All tests pass
|
|
253
|
+
- [ ] Documentation is updated
|
|
254
|
+
- [ ] Error handling is implemented
|
|
255
|
+
- [ ] Security considerations addressed
|
|
256
|
+
- [ ] Performance impact assessed
|
|
257
|
+
|
|
258
|
+
### Release Process
|
|
259
|
+
|
|
260
|
+
1. Update version in `package.json`
|
|
261
|
+
2. Update CHANGELOG.md
|
|
262
|
+
3. Create release tag
|
|
263
|
+
4. Deploy to production environment
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
For questions about these guidelines, please contact the development team or open an issue in the project repository.
|