@mondaydotcomorg/atp-client 0.17.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +397 -0
- package/dist/client.d.ts +125 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +129 -0
- package/dist/client.js.map +1 -0
- package/dist/core/api-operations.d.ts +37 -0
- package/dist/core/api-operations.d.ts.map +1 -0
- package/dist/core/api-operations.js +90 -0
- package/dist/core/api-operations.js.map +1 -0
- package/dist/core/execution-operations.d.ts +34 -0
- package/dist/core/execution-operations.d.ts.map +1 -0
- package/dist/core/execution-operations.js +237 -0
- package/dist/core/execution-operations.js.map +1 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +7 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/provenance-registry.d.ts +40 -0
- package/dist/core/provenance-registry.d.ts.map +1 -0
- package/dist/core/provenance-registry.js +108 -0
- package/dist/core/provenance-registry.js.map +1 -0
- package/dist/core/service-providers.d.ts +29 -0
- package/dist/core/service-providers.d.ts.map +1 -0
- package/dist/core/service-providers.js +139 -0
- package/dist/core/service-providers.js.map +1 -0
- package/dist/core/session.d.ts +50 -0
- package/dist/core/session.d.ts.map +1 -0
- package/dist/core/session.js +138 -0
- package/dist/core/session.js.map +1 -0
- package/dist/core/types.d.ts +73 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/errors.d.ts +22 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +25 -0
- package/dist/errors.js.map +1 -0
- package/dist/generator.d.ts +7 -0
- package/dist/generator.d.ts.map +1 -0
- package/dist/generator.js +12 -0
- package/dist/generator.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/execute-code.d.ts +20 -0
- package/dist/tools/execute-code.d.ts.map +1 -0
- package/dist/tools/execute-code.js +57 -0
- package/dist/tools/execute-code.js.map +1 -0
- package/dist/tools/explore-api.d.ts +14 -0
- package/dist/tools/explore-api.d.ts.map +1 -0
- package/dist/tools/explore-api.js +47 -0
- package/dist/tools/explore-api.js.map +1 -0
- package/dist/tools/fetch-all-apis.d.ts +14 -0
- package/dist/tools/fetch-all-apis.d.ts.map +1 -0
- package/dist/tools/fetch-all-apis.js +31 -0
- package/dist/tools/fetch-all-apis.js.map +1 -0
- package/dist/tools/index.d.ts +6 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +6 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/search-api.d.ts +14 -0
- package/dist/tools/search-api.d.ts.map +1 -0
- package/dist/tools/search-api.js +36 -0
- package/dist/tools/search-api.js.map +1 -0
- package/dist/tools/types.d.ts +23 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +7 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools.d.ts +8 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +14 -0
- package/dist/tools.js.map +1 -0
- package/package.json +46 -0
- package/src/client.ts +194 -0
- package/src/core/api-operations.ts +130 -0
- package/src/core/execution-operations.ts +301 -0
- package/src/core/index.ts +13 -0
- package/src/core/provenance-registry.ts +129 -0
- package/src/core/service-providers.ts +176 -0
- package/src/core/session.ts +180 -0
- package/src/core/types.ts +79 -0
- package/src/errors.ts +24 -0
- package/src/generator.ts +15 -0
- package/src/index.ts +10 -0
- package/src/tools/execute-code.ts +76 -0
- package/src/tools/explore-api.ts +63 -0
- package/src/tools/fetch-all-apis.ts +43 -0
- package/src/tools/index.ts +5 -0
- package/src/tools/search-api.ts +48 -0
- package/src/tools/types.ts +24 -0
- package/src/tools.ts +21 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import type { ClientHooks } from './types.js';
|
|
2
|
+
import type { ClientToolDefinition } from '@mondaydotcomorg/atp-protocol';
|
|
3
|
+
|
|
4
|
+
export class ClientSession {
|
|
5
|
+
private baseUrl: string;
|
|
6
|
+
private customHeaders: Record<string, string>;
|
|
7
|
+
private clientId?: string;
|
|
8
|
+
private clientToken?: string;
|
|
9
|
+
private initPromise?: Promise<void>;
|
|
10
|
+
private hooks?: ClientHooks;
|
|
11
|
+
|
|
12
|
+
constructor(baseUrl: string, headers?: Record<string, string>, hooks?: ClientHooks) {
|
|
13
|
+
this.baseUrl = baseUrl;
|
|
14
|
+
this.customHeaders = headers || {};
|
|
15
|
+
this.hooks = hooks;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Initializes the client session with the server.
|
|
20
|
+
* This MUST be called before any other operations.
|
|
21
|
+
* The server generates and returns a unique client ID and token.
|
|
22
|
+
* @param clientInfo - Optional client information
|
|
23
|
+
* @param tools - Optional client tool definitions to register with the server
|
|
24
|
+
*/
|
|
25
|
+
async init(
|
|
26
|
+
clientInfo?: { name?: string; version?: string; [key: string]: unknown },
|
|
27
|
+
tools?: ClientToolDefinition[]
|
|
28
|
+
): Promise<{
|
|
29
|
+
clientId: string;
|
|
30
|
+
token: string;
|
|
31
|
+
expiresAt: number;
|
|
32
|
+
tokenRotateAt: number;
|
|
33
|
+
}> {
|
|
34
|
+
if (this.initPromise) {
|
|
35
|
+
await this.initPromise;
|
|
36
|
+
return {
|
|
37
|
+
clientId: this.clientId!,
|
|
38
|
+
token: this.clientToken!,
|
|
39
|
+
expiresAt: 0,
|
|
40
|
+
tokenRotateAt: 0,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
this.initPromise = (async () => {
|
|
45
|
+
const url = `${this.baseUrl}/api/init`;
|
|
46
|
+
const body = JSON.stringify({
|
|
47
|
+
clientInfo,
|
|
48
|
+
tools: tools || [],
|
|
49
|
+
});
|
|
50
|
+
const headers = await this.prepareHeaders('POST', url, body);
|
|
51
|
+
|
|
52
|
+
const response = await fetch(url, {
|
|
53
|
+
method: 'POST',
|
|
54
|
+
headers,
|
|
55
|
+
body,
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
if (!response.ok) {
|
|
59
|
+
throw new Error(`Client initialization failed: ${response.status} ${response.statusText}`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const data = (await response.json()) as {
|
|
63
|
+
clientId: string;
|
|
64
|
+
token: string;
|
|
65
|
+
expiresAt: number;
|
|
66
|
+
tokenRotateAt: number;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
this.clientId = data.clientId;
|
|
70
|
+
this.clientToken = data.token;
|
|
71
|
+
})();
|
|
72
|
+
|
|
73
|
+
await this.initPromise;
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
clientId: this.clientId!,
|
|
77
|
+
token: this.clientToken!,
|
|
78
|
+
expiresAt: 0,
|
|
79
|
+
tokenRotateAt: 0,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Gets the unique client ID.
|
|
85
|
+
*/
|
|
86
|
+
getClientId(): string {
|
|
87
|
+
if (!this.clientId) {
|
|
88
|
+
throw new Error('Client not initialized. Call init() first.');
|
|
89
|
+
}
|
|
90
|
+
return this.clientId;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Ensures the client is initialized before making requests.
|
|
95
|
+
*/
|
|
96
|
+
async ensureInitialized(): Promise<void> {
|
|
97
|
+
if (!this.clientId) {
|
|
98
|
+
throw new Error('Client not initialized. Call init() first.');
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Creates HTTP headers for requests.
|
|
104
|
+
*/
|
|
105
|
+
getHeaders(): Record<string, string> {
|
|
106
|
+
const headers: Record<string, string> = {
|
|
107
|
+
'Content-Type': 'application/json',
|
|
108
|
+
...this.customHeaders,
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
if (this.clientId) {
|
|
112
|
+
headers['X-Client-ID'] = this.clientId;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (this.clientToken) {
|
|
116
|
+
headers['Authorization'] = `Bearer ${this.clientToken}`;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return headers;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
getBaseUrl(): string {
|
|
123
|
+
return this.baseUrl;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Updates the client token from response headers (token refresh).
|
|
128
|
+
*/
|
|
129
|
+
updateToken(response: Response): void {
|
|
130
|
+
const newToken = response.headers.get('X-ATP-Token');
|
|
131
|
+
if (newToken) {
|
|
132
|
+
this.clientToken = newToken;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Prepares headers for a request, calling preRequest hook if configured
|
|
138
|
+
*/
|
|
139
|
+
async prepareHeaders(
|
|
140
|
+
method: string,
|
|
141
|
+
url: string,
|
|
142
|
+
body?: unknown
|
|
143
|
+
): Promise<Record<string, string>> {
|
|
144
|
+
let headers: Record<string, string> = {
|
|
145
|
+
'Content-Type': 'application/json',
|
|
146
|
+
...this.customHeaders,
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
if (this.clientId) {
|
|
150
|
+
headers['X-Client-ID'] = this.clientId;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (this.clientToken) {
|
|
154
|
+
headers['Authorization'] = `Bearer ${this.clientToken}`;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (this.hooks?.preRequest) {
|
|
158
|
+
try {
|
|
159
|
+
const result = await this.hooks.preRequest({
|
|
160
|
+
url,
|
|
161
|
+
method,
|
|
162
|
+
currentHeaders: headers,
|
|
163
|
+
body,
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
if (result.abort) {
|
|
167
|
+
throw new Error(result.abortReason || 'Request aborted by preRequest hook');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (result.headers) {
|
|
171
|
+
headers = result.headers;
|
|
172
|
+
}
|
|
173
|
+
} catch (error) {
|
|
174
|
+
throw error;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return headers;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export interface PreRequestContext {
|
|
2
|
+
/** Request URL */
|
|
3
|
+
url: string;
|
|
4
|
+
/** HTTP method */
|
|
5
|
+
method: string;
|
|
6
|
+
/** Current headers that will be sent */
|
|
7
|
+
currentHeaders: Record<string, string>;
|
|
8
|
+
/** Request body (if any) */
|
|
9
|
+
body?: unknown;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface PreRequestResult {
|
|
13
|
+
/** Updated headers to use for this request */
|
|
14
|
+
headers?: Record<string, string>;
|
|
15
|
+
/** If true, abort the request and throw an error */
|
|
16
|
+
abort?: boolean;
|
|
17
|
+
/** Optional error message if aborting */
|
|
18
|
+
abortReason?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Hook called before every HTTP request to the ATP server
|
|
23
|
+
*
|
|
24
|
+
* Use this to:
|
|
25
|
+
* - Refresh short-lived tokens
|
|
26
|
+
* - Add tracing/correlation headers
|
|
27
|
+
* - Log requests
|
|
28
|
+
* - Implement custom authentication flows
|
|
29
|
+
* - Conditionally abort requests
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* const preRequest = async (context) => {
|
|
34
|
+
* // Refresh token before each request
|
|
35
|
+
* const token = await auth.getAccessToken();
|
|
36
|
+
*
|
|
37
|
+
* // Log the request
|
|
38
|
+
* console.log(`[ATP] ${context.method} ${context.url}`);
|
|
39
|
+
*
|
|
40
|
+
* return {
|
|
41
|
+
* headers: {
|
|
42
|
+
* ...context.currentHeaders,
|
|
43
|
+
* Authorization: `Bearer ${token}`,
|
|
44
|
+
* 'X-Trace-Id': generateTraceId()
|
|
45
|
+
* }
|
|
46
|
+
* };
|
|
47
|
+
* };
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export type PreRequestHook = (context: PreRequestContext) => Promise<PreRequestResult>;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Client hooks for intercepting and modifying behavior
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```typescript
|
|
57
|
+
* const hooks: ClientHooks = {
|
|
58
|
+
* preRequest: async (context) => {
|
|
59
|
+
* const token = await auth.getAccessToken();
|
|
60
|
+
* return {
|
|
61
|
+
* headers: {
|
|
62
|
+
* ...context.currentHeaders,
|
|
63
|
+
* Authorization: `Bearer ${token}`
|
|
64
|
+
* }
|
|
65
|
+
* };
|
|
66
|
+
* }
|
|
67
|
+
* };
|
|
68
|
+
*
|
|
69
|
+
* const client = new AgentToolProtocolClient(serverUrl, {}, undefined, hooks);
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export interface ClientHooks {
|
|
73
|
+
/** Hook called before every HTTP request */
|
|
74
|
+
preRequest?: PreRequestHook;
|
|
75
|
+
// Future hooks can be added here without breaking changes:
|
|
76
|
+
// postRequest?: PostRequestHook;
|
|
77
|
+
// onError?: ErrorHook;
|
|
78
|
+
// onRetry?: RetryHook;
|
|
79
|
+
}
|
package/src/errors.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base error class for exceptions thrown by client callbacks that should
|
|
3
|
+
* be propagated through the execution flow rather than being caught and
|
|
4
|
+
* converted to error results.
|
|
5
|
+
*
|
|
6
|
+
* Use this when client-side service providers need to interrupt normal
|
|
7
|
+
* execution flow (e.g., for human-in-the-loop workflows, custom control flow).
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* class CustomInterruptException extends ClientCallbackError {
|
|
12
|
+
* constructor(message: string, public data: any) {
|
|
13
|
+
* super(message);
|
|
14
|
+
* this.name = 'CustomInterruptException';
|
|
15
|
+
* }
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export class ClientCallbackError extends Error {
|
|
20
|
+
constructor(message: string) {
|
|
21
|
+
super(message);
|
|
22
|
+
this.name = 'ClientCallbackError';
|
|
23
|
+
}
|
|
24
|
+
}
|
package/src/generator.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { AgentToolProtocolClient } from './client.js';
|
|
2
|
+
|
|
3
|
+
export class CodeGenerator {
|
|
4
|
+
private client: AgentToolProtocolClient;
|
|
5
|
+
|
|
6
|
+
constructor(client: AgentToolProtocolClient) {
|
|
7
|
+
this.client = client;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async generateCode(intent: string, parameters?: unknown): Promise<string> {
|
|
11
|
+
const types = this.client.getTypeDefinitions();
|
|
12
|
+
console.log('Generating code for intent:', intent, parameters, types);
|
|
13
|
+
return '// Generated code';
|
|
14
|
+
}
|
|
15
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from './client.js';
|
|
2
|
+
export * from './generator.js';
|
|
3
|
+
export * from './tools.js';
|
|
4
|
+
export * from './core/types.js';
|
|
5
|
+
export * from './errors.js';
|
|
6
|
+
|
|
7
|
+
export { ExecutionStatus } from '@mondaydotcomorg/atp-protocol';
|
|
8
|
+
export type { Tool, ToolName } from './tools/types.js';
|
|
9
|
+
export { ToolNames } from './tools/types.js';
|
|
10
|
+
export type { AgentToolProtocolClientOptions } from './client.js';
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
3
|
+
import { ExecutionStatus } from '@mondaydotcomorg/atp-protocol';
|
|
4
|
+
import type { AgentToolProtocolClient } from '../client.js';
|
|
5
|
+
import { ToolNames, type Tool } from './types';
|
|
6
|
+
|
|
7
|
+
const executeCodeInputSchema = z.object({
|
|
8
|
+
code: z.string().describe('The JavaScript/TypeScript code to execute'),
|
|
9
|
+
timeout: z.number().optional().describe('Execution timeout in milliseconds (default: 30000)'),
|
|
10
|
+
maxMemory: z.number().optional().describe('Maximum memory in bytes (default: 128MB)'),
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
type ExecuteCodeInput = z.infer<typeof executeCodeInputSchema>;
|
|
14
|
+
|
|
15
|
+
export function createExecuteCodeTool(client: AgentToolProtocolClient): Tool<ExecuteCodeInput> {
|
|
16
|
+
return {
|
|
17
|
+
name: ToolNames.EXECUTE_CODE,
|
|
18
|
+
description:
|
|
19
|
+
"Execute JavaScript/TypeScript code to call APIs. IMPORTANT: Code MUST use 'return' statement to see results. Examples: 'return api.groupName.functionName({})' or 'const result = api.group.func({}); return result'. Use bracket notation for dynamic names: api['groupName']['functionName']({}).",
|
|
20
|
+
inputSchema: zodToJsonSchema(executeCodeInputSchema) as any,
|
|
21
|
+
func: async (input: ExecuteCodeInput) => {
|
|
22
|
+
try {
|
|
23
|
+
const result = await client.execute(input.code, {
|
|
24
|
+
timeout: input.timeout,
|
|
25
|
+
maxMemory: input.maxMemory,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
if (result.status === ExecutionStatus.COMPLETED) {
|
|
29
|
+
return JSON.stringify(
|
|
30
|
+
{
|
|
31
|
+
success: true,
|
|
32
|
+
result: result.result,
|
|
33
|
+
stats: {
|
|
34
|
+
duration: result.stats.duration,
|
|
35
|
+
memoryUsed: result.stats.memoryUsed,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
null,
|
|
39
|
+
2
|
|
40
|
+
);
|
|
41
|
+
} else if (result.status === ExecutionStatus.FAILED) {
|
|
42
|
+
return JSON.stringify(
|
|
43
|
+
{
|
|
44
|
+
success: false,
|
|
45
|
+
error: result.error?.message || 'Execution failed',
|
|
46
|
+
stack: result.error?.stack,
|
|
47
|
+
message: 'Code execution failed. Check syntax and fix errors.',
|
|
48
|
+
},
|
|
49
|
+
null,
|
|
50
|
+
2
|
|
51
|
+
);
|
|
52
|
+
} else {
|
|
53
|
+
return JSON.stringify(
|
|
54
|
+
{
|
|
55
|
+
success: false,
|
|
56
|
+
error: 'Execution timed out',
|
|
57
|
+
message: 'Code took too long. Simplify or optimize.',
|
|
58
|
+
},
|
|
59
|
+
null,
|
|
60
|
+
2
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
} catch (error: any) {
|
|
64
|
+
return JSON.stringify(
|
|
65
|
+
{
|
|
66
|
+
success: false,
|
|
67
|
+
error: error.message,
|
|
68
|
+
message: 'Failed to execute code',
|
|
69
|
+
},
|
|
70
|
+
null,
|
|
71
|
+
2
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
3
|
+
import type { AgentToolProtocolClient } from '../client.js';
|
|
4
|
+
import { ToolNames, type Tool } from './types.js';
|
|
5
|
+
|
|
6
|
+
const exploreApiInputSchema = z.object({
|
|
7
|
+
path: z
|
|
8
|
+
.string()
|
|
9
|
+
.describe('Path to explore (e.g., "/", "/openapi/github", "/mcp/filesystem/read_file")'),
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
type ExploreApiInput = z.infer<typeof exploreApiInputSchema>;
|
|
13
|
+
|
|
14
|
+
export function createExploreApiTool(client: AgentToolProtocolClient): Tool<ExploreApiInput> {
|
|
15
|
+
return {
|
|
16
|
+
name: ToolNames.EXPLORE_API,
|
|
17
|
+
description:
|
|
18
|
+
'Explore APIs using filesystem-like navigation. Navigate through directories to discover available functions. Provide path as string like "/", "/openapi", "/openapi/github", or "/openapi/github/repos/createRepo" to see functions.',
|
|
19
|
+
inputSchema: zodToJsonSchema(exploreApiInputSchema) as any,
|
|
20
|
+
zodSchema: exploreApiInputSchema,
|
|
21
|
+
func: async (input: ExploreApiInput) => {
|
|
22
|
+
try {
|
|
23
|
+
const result = await client.exploreAPI(input.path);
|
|
24
|
+
|
|
25
|
+
if (result.type === 'directory') {
|
|
26
|
+
return JSON.stringify(
|
|
27
|
+
{
|
|
28
|
+
success: true,
|
|
29
|
+
type: 'directory',
|
|
30
|
+
path: result.path,
|
|
31
|
+
items: result.items,
|
|
32
|
+
},
|
|
33
|
+
null,
|
|
34
|
+
2
|
|
35
|
+
);
|
|
36
|
+
} else {
|
|
37
|
+
return JSON.stringify(
|
|
38
|
+
{
|
|
39
|
+
success: true,
|
|
40
|
+
type: 'function',
|
|
41
|
+
name: result.name,
|
|
42
|
+
description: result.description,
|
|
43
|
+
definition: result.definition,
|
|
44
|
+
group: result.group,
|
|
45
|
+
path: result.path,
|
|
46
|
+
},
|
|
47
|
+
null,
|
|
48
|
+
2
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
} catch (error: any) {
|
|
52
|
+
return JSON.stringify(
|
|
53
|
+
{
|
|
54
|
+
success: false,
|
|
55
|
+
error: error.message,
|
|
56
|
+
},
|
|
57
|
+
null,
|
|
58
|
+
2
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
3
|
+
import type { AgentToolProtocolClient } from '../client.js';
|
|
4
|
+
import { ToolNames, type Tool } from './types';
|
|
5
|
+
|
|
6
|
+
const fetchAllApisInputSchema = z.object({
|
|
7
|
+
apiGroups: z.array(z.string()).optional().describe('Optional: Specific API groups to include'),
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
type FetchAllApisInput = z.infer<typeof fetchAllApisInputSchema>;
|
|
11
|
+
|
|
12
|
+
export function createFetchAllApisTool(client: AgentToolProtocolClient): Tool<FetchAllApisInput> {
|
|
13
|
+
return {
|
|
14
|
+
name: ToolNames.FETCH_ALL_APIS,
|
|
15
|
+
description:
|
|
16
|
+
'Get TypeScript definitions of all available APIs. Returns code showing api.add, api.getTodo, etc.',
|
|
17
|
+
inputSchema: zodToJsonSchema(fetchAllApisInputSchema) as any,
|
|
18
|
+
zodSchema: fetchAllApisInputSchema,
|
|
19
|
+
func: async (_input: FetchAllApisInput) => {
|
|
20
|
+
try {
|
|
21
|
+
const typescript = client.getTypeDefinitions();
|
|
22
|
+
return JSON.stringify(
|
|
23
|
+
{
|
|
24
|
+
success: true,
|
|
25
|
+
typescript,
|
|
26
|
+
message: 'Use this TypeScript to understand available api.* functions',
|
|
27
|
+
},
|
|
28
|
+
null,
|
|
29
|
+
2
|
|
30
|
+
);
|
|
31
|
+
} catch (error: any) {
|
|
32
|
+
return JSON.stringify(
|
|
33
|
+
{
|
|
34
|
+
success: false,
|
|
35
|
+
error: error.message,
|
|
36
|
+
},
|
|
37
|
+
null,
|
|
38
|
+
2
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
3
|
+
import type { AgentToolProtocolClient } from '../client.js';
|
|
4
|
+
import { ToolNames, type Tool } from './types';
|
|
5
|
+
|
|
6
|
+
const searchApiInputSchema = z.object({
|
|
7
|
+
query: z.string().describe('Search query string'),
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
type SearchApiInput = z.infer<typeof searchApiInputSchema>;
|
|
11
|
+
|
|
12
|
+
export function createSearchApiTool(client: AgentToolProtocolClient): Tool<SearchApiInput> {
|
|
13
|
+
return {
|
|
14
|
+
name: ToolNames.SEARCH_API,
|
|
15
|
+
description:
|
|
16
|
+
'Search for APIs by keyword. Provide search term as string like "add", "math", "user", etc.',
|
|
17
|
+
inputSchema: zodToJsonSchema(searchApiInputSchema) as any,
|
|
18
|
+
zodSchema: searchApiInputSchema,
|
|
19
|
+
func: async (input: SearchApiInput) => {
|
|
20
|
+
try {
|
|
21
|
+
const results = await client.searchAPI(input.query);
|
|
22
|
+
return JSON.stringify(
|
|
23
|
+
{
|
|
24
|
+
success: true,
|
|
25
|
+
results: results.map((r) => ({
|
|
26
|
+
apiGroup: r.apiGroup,
|
|
27
|
+
functionName: r.functionName,
|
|
28
|
+
description: r.description,
|
|
29
|
+
signature: r.signature,
|
|
30
|
+
})),
|
|
31
|
+
count: results.length,
|
|
32
|
+
},
|
|
33
|
+
null,
|
|
34
|
+
2
|
|
35
|
+
);
|
|
36
|
+
} catch (error: any) {
|
|
37
|
+
return JSON.stringify(
|
|
38
|
+
{
|
|
39
|
+
success: false,
|
|
40
|
+
error: error.message,
|
|
41
|
+
},
|
|
42
|
+
null,
|
|
43
|
+
2
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export const ToolNames = {
|
|
2
|
+
SEARCH_API: 'search_api',
|
|
3
|
+
FETCH_ALL_APIS: 'fetch_all_apis',
|
|
4
|
+
EXECUTE_CODE: 'execute_code',
|
|
5
|
+
EXPLORE_API: 'explore_api',
|
|
6
|
+
} as const;
|
|
7
|
+
|
|
8
|
+
export type ToolName = (typeof ToolNames)[keyof typeof ToolNames];
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Tool definition following MCP (Model Context Protocol) convention
|
|
12
|
+
* with added execution function
|
|
13
|
+
*/
|
|
14
|
+
export interface Tool<TInput = any> {
|
|
15
|
+
name: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
inputSchema: {
|
|
18
|
+
type: string;
|
|
19
|
+
properties?: Record<string, unknown>;
|
|
20
|
+
required?: string[];
|
|
21
|
+
};
|
|
22
|
+
zodSchema?: any;
|
|
23
|
+
func: (input: TInput) => Promise<string>;
|
|
24
|
+
}
|
package/src/tools.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { AgentToolProtocolClient } from './client.js';
|
|
2
|
+
import {
|
|
3
|
+
type Tool,
|
|
4
|
+
createSearchApiTool,
|
|
5
|
+
createFetchAllApisTool,
|
|
6
|
+
createExecuteCodeTool,
|
|
7
|
+
createExploreApiTool,
|
|
8
|
+
} from './tools/index.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Creates MCP-compliant tool definitions with execution handlers
|
|
12
|
+
* These tools work with any LLM/agent framework
|
|
13
|
+
*/
|
|
14
|
+
export function createToolsFromATPClient(client: AgentToolProtocolClient): Tool[] {
|
|
15
|
+
return [
|
|
16
|
+
createSearchApiTool(client),
|
|
17
|
+
createFetchAllApisTool(client),
|
|
18
|
+
createExecuteCodeTool(client),
|
|
19
|
+
createExploreApiTool(client),
|
|
20
|
+
];
|
|
21
|
+
}
|