@kelpi/mcp 0.1.0
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 +312 -0
- package/bin/kelpi-mcp +3 -0
- package/dist/__tests__/integration-api/fixtures.d.ts +382 -0
- package/dist/__tests__/integration-api/fixtures.d.ts.map +1 -0
- package/dist/__tests__/integration-api/fixtures.js +478 -0
- package/dist/__tests__/integration-api/fixtures.js.map +1 -0
- package/dist/__tests__/integration-api/index.d.ts +19 -0
- package/dist/__tests__/integration-api/index.d.ts.map +1 -0
- package/dist/__tests__/integration-api/index.js +33 -0
- package/dist/__tests__/integration-api/index.js.map +1 -0
- package/dist/__tests__/integration-api/setup.d.ts +176 -0
- package/dist/__tests__/integration-api/setup.d.ts.map +1 -0
- package/dist/__tests__/integration-api/setup.js +329 -0
- package/dist/__tests__/integration-api/setup.js.map +1 -0
- package/dist/__tests__/setup.d.ts +2 -0
- package/dist/__tests__/setup.d.ts.map +1 -0
- package/dist/__tests__/setup.js +11 -0
- package/dist/__tests__/setup.js.map +1 -0
- package/dist/__tests__/unit/test-utils.d.ts +46 -0
- package/dist/__tests__/unit/test-utils.d.ts.map +1 -0
- package/dist/__tests__/unit/test-utils.js +50 -0
- package/dist/__tests__/unit/test-utils.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api-client.d.ts +17 -0
- package/dist/lib/api-client.d.ts.map +1 -0
- package/dist/lib/api-client.js +169 -0
- package/dist/lib/api-client.js.map +1 -0
- package/dist/lib/auth-state.d.ts +54 -0
- package/dist/lib/auth-state.d.ts.map +1 -0
- package/dist/lib/auth-state.js +131 -0
- package/dist/lib/auth-state.js.map +1 -0
- package/dist/lib/config.d.ts +39 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +170 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/error-formatter.d.ts +40 -0
- package/dist/lib/error-formatter.d.ts.map +1 -0
- package/dist/lib/error-formatter.js +149 -0
- package/dist/lib/error-formatter.js.map +1 -0
- package/dist/lib/errors.d.ts +44 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +56 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/tool-helpers.d.ts +49 -0
- package/dist/lib/tool-helpers.d.ts.map +1 -0
- package/dist/lib/tool-helpers.js +101 -0
- package/dist/lib/tool-helpers.js.map +1 -0
- package/dist/lib/tool-registry.d.ts +111 -0
- package/dist/lib/tool-registry.d.ts.map +1 -0
- package/dist/lib/tool-registry.js +112 -0
- package/dist/lib/tool-registry.js.map +1 -0
- package/dist/lib/version.d.ts +13 -0
- package/dist/lib/version.d.ts.map +1 -0
- package/dist/lib/version.js +13 -0
- package/dist/lib/version.js.map +1 -0
- package/dist/prompts/flow-generator.d.ts +45 -0
- package/dist/prompts/flow-generator.d.ts.map +1 -0
- package/dist/prompts/flow-generator.js +177 -0
- package/dist/prompts/flow-generator.js.map +1 -0
- package/dist/prompts/index.d.ts +7 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +7 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/server.d.ts +66 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +140 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/auth/index.d.ts +18 -0
- package/dist/tools/auth/index.d.ts.map +1 -0
- package/dist/tools/auth/index.js +50 -0
- package/dist/tools/auth/index.js.map +1 -0
- package/dist/tools/auth/login.d.ts +37 -0
- package/dist/tools/auth/login.d.ts.map +1 -0
- package/dist/tools/auth/login.js +257 -0
- package/dist/tools/auth/login.js.map +1 -0
- package/dist/tools/auth/schemas.d.ts +69 -0
- package/dist/tools/auth/schemas.d.ts.map +1 -0
- package/dist/tools/auth/schemas.js +36 -0
- package/dist/tools/auth/schemas.js.map +1 -0
- package/dist/tools/auth/status.d.ts +11 -0
- package/dist/tools/auth/status.d.ts.map +1 -0
- package/dist/tools/auth/status.js +50 -0
- package/dist/tools/auth/status.js.map +1 -0
- package/dist/tools/contacts/create.d.ts +11 -0
- package/dist/tools/contacts/create.d.ts.map +1 -0
- package/dist/tools/contacts/create.js +47 -0
- package/dist/tools/contacts/create.js.map +1 -0
- package/dist/tools/contacts/index.d.ts +10 -0
- package/dist/tools/contacts/index.d.ts.map +1 -0
- package/dist/tools/contacts/index.js +40 -0
- package/dist/tools/contacts/index.js.map +1 -0
- package/dist/tools/contacts/schemas.d.ts +37 -0
- package/dist/tools/contacts/schemas.d.ts.map +1 -0
- package/dist/tools/contacts/schemas.js +15 -0
- package/dist/tools/contacts/schemas.js.map +1 -0
- package/dist/tools/events/index.d.ts +10 -0
- package/dist/tools/events/index.d.ts.map +1 -0
- package/dist/tools/events/index.js +42 -0
- package/dist/tools/events/index.js.map +1 -0
- package/dist/tools/events/schemas.d.ts +37 -0
- package/dist/tools/events/schemas.d.ts.map +1 -0
- package/dist/tools/events/schemas.js +17 -0
- package/dist/tools/events/schemas.js.map +1 -0
- package/dist/tools/events/track.d.ts +11 -0
- package/dist/tools/events/track.d.ts.map +1 -0
- package/dist/tools/events/track.js +41 -0
- package/dist/tools/events/track.js.map +1 -0
- package/dist/tools/flows/activate.d.ts +11 -0
- package/dist/tools/flows/activate.d.ts.map +1 -0
- package/dist/tools/flows/activate.js +46 -0
- package/dist/tools/flows/activate.js.map +1 -0
- package/dist/tools/flows/create.d.ts +11 -0
- package/dist/tools/flows/create.d.ts.map +1 -0
- package/dist/tools/flows/create.js +72 -0
- package/dist/tools/flows/create.js.map +1 -0
- package/dist/tools/flows/index.d.ts +24 -0
- package/dist/tools/flows/index.d.ts.map +1 -0
- package/dist/tools/flows/index.js +183 -0
- package/dist/tools/flows/index.js.map +1 -0
- package/dist/tools/flows/list.d.ts +11 -0
- package/dist/tools/flows/list.d.ts.map +1 -0
- package/dist/tools/flows/list.js +34 -0
- package/dist/tools/flows/list.js.map +1 -0
- package/dist/tools/flows/schemas.d.ts +621 -0
- package/dist/tools/flows/schemas.d.ts.map +1 -0
- package/dist/tools/flows/schemas.js +135 -0
- package/dist/tools/flows/schemas.js.map +1 -0
- package/dist/tools/flows/transform.d.ts +39 -0
- package/dist/tools/flows/transform.d.ts.map +1 -0
- package/dist/tools/flows/transform.js +139 -0
- package/dist/tools/flows/transform.js.map +1 -0
- package/dist/tools/index.d.ts +34 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +46 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/sdk/index.d.ts +18 -0
- package/dist/tools/sdk/index.d.ts.map +1 -0
- package/dist/tools/sdk/index.js +69 -0
- package/dist/tools/sdk/index.js.map +1 -0
- package/dist/tools/sdk/public-key.d.ts +11 -0
- package/dist/tools/sdk/public-key.d.ts.map +1 -0
- package/dist/tools/sdk/public-key.js +24 -0
- package/dist/tools/sdk/public-key.js.map +1 -0
- package/dist/tools/sdk/schemas.d.ts +48 -0
- package/dist/tools/sdk/schemas.d.ts.map +1 -0
- package/dist/tools/sdk/schemas.js +35 -0
- package/dist/tools/sdk/schemas.js.map +1 -0
- package/dist/tools/sdk/snippet.d.ts +11 -0
- package/dist/tools/sdk/snippet.d.ts.map +1 -0
- package/dist/tools/sdk/snippet.js +50 -0
- package/dist/tools/sdk/snippet.js.map +1 -0
- package/dist/tools/sdk/templates/index.d.ts +5 -0
- package/dist/tools/sdk/templates/index.d.ts.map +1 -0
- package/dist/tools/sdk/templates/index.js +5 -0
- package/dist/tools/sdk/templates/index.js.map +1 -0
- package/dist/tools/sdk/templates/nextjs.d.ts +5 -0
- package/dist/tools/sdk/templates/nextjs.d.ts.map +1 -0
- package/dist/tools/sdk/templates/nextjs.js +71 -0
- package/dist/tools/sdk/templates/nextjs.js.map +1 -0
- package/dist/tools/sdk/templates/node.d.ts +9 -0
- package/dist/tools/sdk/templates/node.d.ts.map +1 -0
- package/dist/tools/sdk/templates/node.js +170 -0
- package/dist/tools/sdk/templates/node.js.map +1 -0
- package/dist/tools/sdk/templates/react.d.ts +5 -0
- package/dist/tools/sdk/templates/react.d.ts.map +1 -0
- package/dist/tools/sdk/templates/react.js +54 -0
- package/dist/tools/sdk/templates/react.js.map +1 -0
- package/dist/tools/sdk/templates/vanilla.d.ts +5 -0
- package/dist/tools/sdk/templates/vanilla.d.ts.map +1 -0
- package/dist/tools/sdk/templates/vanilla.js +61 -0
- package/dist/tools/sdk/templates/vanilla.js.map +1 -0
- package/dist/tools/templates/create.d.ts +11 -0
- package/dist/tools/templates/create.d.ts.map +1 -0
- package/dist/tools/templates/create.js +39 -0
- package/dist/tools/templates/create.js.map +1 -0
- package/dist/tools/templates/index.d.ts +17 -0
- package/dist/tools/templates/index.d.ts.map +1 -0
- package/dist/tools/templates/index.js +68 -0
- package/dist/tools/templates/index.js.map +1 -0
- package/dist/tools/templates/list.d.ts +11 -0
- package/dist/tools/templates/list.d.ts.map +1 -0
- package/dist/tools/templates/list.js +31 -0
- package/dist/tools/templates/list.js.map +1 -0
- package/dist/tools/templates/schemas.d.ts +90 -0
- package/dist/tools/templates/schemas.d.ts.map +1 -0
- package/dist/tools/templates/schemas.js +37 -0
- package/dist/tools/templates/schemas.js.map +1 -0
- package/dist/types.d.ts +55 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +76 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { loginInputSchema, statusInputSchema } from './schemas.js';
|
|
2
|
+
import { loginHandler } from './login.js';
|
|
3
|
+
import { statusHandler } from './status.js';
|
|
4
|
+
/**
|
|
5
|
+
* kelpi_login tool definition and handler
|
|
6
|
+
*
|
|
7
|
+
* Initiates browser-based authentication using device code flow.
|
|
8
|
+
* Returns verification URL and user code for the user to complete authentication.
|
|
9
|
+
*/
|
|
10
|
+
export const kelpiLogin = {
|
|
11
|
+
definition: {
|
|
12
|
+
name: 'kelpi_login',
|
|
13
|
+
description: `Authenticate with Kelpi using browser-based login.
|
|
14
|
+
|
|
15
|
+
This tool initiates the device code authentication flow:
|
|
16
|
+
1. Creates an authentication session
|
|
17
|
+
2. Returns a verification URL and code
|
|
18
|
+
3. Polls for completion while you authenticate in the browser
|
|
19
|
+
4. Saves the API key to config on success
|
|
20
|
+
|
|
21
|
+
After running this tool, open the provided URL in your browser and enter the code to complete authentication.`,
|
|
22
|
+
inputSchema: loginInputSchema,
|
|
23
|
+
},
|
|
24
|
+
handler: loginHandler,
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* kelpi_status tool definition and handler
|
|
28
|
+
*
|
|
29
|
+
* Checks current authentication status and returns workspace information.
|
|
30
|
+
*/
|
|
31
|
+
export const kelpiStatus = {
|
|
32
|
+
definition: {
|
|
33
|
+
name: 'kelpi_status',
|
|
34
|
+
description: `Check current authentication status and display workspace information.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
- authenticated: whether you are currently logged in
|
|
38
|
+
- workspace_id: ID of the current workspace
|
|
39
|
+
- workspace_name: name of the current workspace
|
|
40
|
+
- key_type: whether using a public or secret API key`,
|
|
41
|
+
inputSchema: statusInputSchema,
|
|
42
|
+
},
|
|
43
|
+
handler: statusHandler,
|
|
44
|
+
};
|
|
45
|
+
// Re-export schemas
|
|
46
|
+
export * from './schemas.js';
|
|
47
|
+
// Re-export handler factories for testing
|
|
48
|
+
export { createLoginHandler, validateVerificationUrl } from './login.js';
|
|
49
|
+
export { createStatusHandler } from './status.js';
|
|
50
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/auth/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,UAAU,GAAoB;IACzC,UAAU,EAAE;QACV,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE;;;;;;;;8GAQ6F;QAC1G,WAAW,EAAE,gBAAgB;KAC9B;IACD,OAAO,EAAE,YAAY;CACtB,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAoB;IAC1C,UAAU,EAAE;QACV,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE;;;;;;qDAMoC;QACjD,WAAW,EAAE,iBAAiB;KAC/B;IACD,OAAO,EAAE,aAAa;CACvB,CAAC;AAEF,oBAAoB;AACpB,cAAc,cAAc,CAAC;AAE7B,0CAA0C;AAC1C,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { ToolHandler } from '../../lib/tool-registry.js';
|
|
2
|
+
/**
|
|
3
|
+
* Options for the login handler
|
|
4
|
+
*/
|
|
5
|
+
export interface LoginHandlerOptions {
|
|
6
|
+
apiUrl?: string;
|
|
7
|
+
maxPollAttempts?: number;
|
|
8
|
+
pollIntervalMs?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Validate a verification URL for security.
|
|
12
|
+
*
|
|
13
|
+
* Security checks:
|
|
14
|
+
* 1. Only allow http/https protocols
|
|
15
|
+
* 2. Reject URLs that are too long (potential buffer overflow)
|
|
16
|
+
* 3. Reject empty or whitespace-only URLs
|
|
17
|
+
* 4. Ensure URL has a valid hostname
|
|
18
|
+
*
|
|
19
|
+
* Note: We use spawn() with array arguments to open the browser,
|
|
20
|
+
* which bypasses shell interpretation entirely, so shell metacharacters
|
|
21
|
+
* are not a security concern here.
|
|
22
|
+
*
|
|
23
|
+
* @param url - The URL to validate
|
|
24
|
+
* @returns true if the URL is safe to open in a browser, false otherwise
|
|
25
|
+
*/
|
|
26
|
+
export declare function validateVerificationUrl(url: string): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Creates a login handler with the specified options.
|
|
29
|
+
* This factory function allows for dependency injection in tests.
|
|
30
|
+
*/
|
|
31
|
+
export declare function createLoginHandler(options?: LoginHandlerOptions): ToolHandler;
|
|
32
|
+
/**
|
|
33
|
+
* Default login handler that uses configured API URL
|
|
34
|
+
* Supports KELPI_API_URL environment variable for local development
|
|
35
|
+
*/
|
|
36
|
+
export declare const loginHandler: ToolHandler;
|
|
37
|
+
//# sourceMappingURL=login.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/tools/auth/login.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,4BAA4B,CAAC;AAoC1E;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAqC5D;AA0CD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,mBAAwB,GAAG,WAAW,CA0KjF;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,WAI1B,CAAC"}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import { saveConfig, getApiUrl } from '../../lib/config.js';
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import { MCP_VERSION } from '../../lib/version.js';
|
|
4
|
+
/**
|
|
5
|
+
* Default API URL for Kelpi
|
|
6
|
+
*/
|
|
7
|
+
const DEFAULT_API_URL = 'https://api.kelpi.ai';
|
|
8
|
+
/**
|
|
9
|
+
* Maximum allowed URL length to prevent buffer overflow attacks
|
|
10
|
+
*/
|
|
11
|
+
const MAX_URL_LENGTH = 2048;
|
|
12
|
+
/**
|
|
13
|
+
* Validate a verification URL for security.
|
|
14
|
+
*
|
|
15
|
+
* Security checks:
|
|
16
|
+
* 1. Only allow http/https protocols
|
|
17
|
+
* 2. Reject URLs that are too long (potential buffer overflow)
|
|
18
|
+
* 3. Reject empty or whitespace-only URLs
|
|
19
|
+
* 4. Ensure URL has a valid hostname
|
|
20
|
+
*
|
|
21
|
+
* Note: We use spawn() with array arguments to open the browser,
|
|
22
|
+
* which bypasses shell interpretation entirely, so shell metacharacters
|
|
23
|
+
* are not a security concern here.
|
|
24
|
+
*
|
|
25
|
+
* @param url - The URL to validate
|
|
26
|
+
* @returns true if the URL is safe to open in a browser, false otherwise
|
|
27
|
+
*/
|
|
28
|
+
export function validateVerificationUrl(url) {
|
|
29
|
+
// Reject null, undefined, or non-string values
|
|
30
|
+
if (url === null || url === undefined || typeof url !== 'string') {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
// Reject empty or whitespace-only URLs
|
|
34
|
+
const trimmedUrl = url.trim();
|
|
35
|
+
if (trimmedUrl.length === 0) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
// Reject URLs that are too long
|
|
39
|
+
if (url.length > MAX_URL_LENGTH) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
// Parse the URL to validate protocol and structure
|
|
43
|
+
let parsedUrl;
|
|
44
|
+
try {
|
|
45
|
+
parsedUrl = new URL(url);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// Invalid URL format
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
// Only allow http and https protocols
|
|
52
|
+
if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
// Ensure the URL has a hostname
|
|
56
|
+
if (!parsedUrl.hostname) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Open a URL in the user's default browser.
|
|
63
|
+
* Cross-platform implementation for macOS, Linux, and Windows.
|
|
64
|
+
*
|
|
65
|
+
* Uses spawn() with array arguments instead of exec() with shell strings
|
|
66
|
+
* to prevent command injection attacks. The URL is passed directly to
|
|
67
|
+
* the browser command without shell interpretation.
|
|
68
|
+
*
|
|
69
|
+
* @param url - The URL to open
|
|
70
|
+
*/
|
|
71
|
+
function openBrowser(url) {
|
|
72
|
+
const platform = process.platform;
|
|
73
|
+
const [command, args] = platform === 'darwin'
|
|
74
|
+
? ['open', [url]]
|
|
75
|
+
: platform === 'win32'
|
|
76
|
+
? ['cmd', ['/c', 'start', '', url]]
|
|
77
|
+
: ['xdg-open', [url]];
|
|
78
|
+
const child = spawn(command, args, {
|
|
79
|
+
detached: true,
|
|
80
|
+
stdio: 'ignore',
|
|
81
|
+
});
|
|
82
|
+
child.on('error', (err) => {
|
|
83
|
+
// Don't fail the whole flow if browser opening fails
|
|
84
|
+
// User can still manually open the URL
|
|
85
|
+
console.error('Failed to open browser:', err);
|
|
86
|
+
});
|
|
87
|
+
child.unref();
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Sleep helper for polling interval
|
|
91
|
+
*/
|
|
92
|
+
function sleep(ms) {
|
|
93
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Creates a login handler with the specified options.
|
|
97
|
+
* This factory function allows for dependency injection in tests.
|
|
98
|
+
*/
|
|
99
|
+
export function createLoginHandler(options = {}) {
|
|
100
|
+
const { apiUrl = DEFAULT_API_URL, maxPollAttempts = 60, // Default: poll for up to 5 minutes (60 * 5 seconds)
|
|
101
|
+
pollIntervalMs = 5000, // Default: 5 seconds
|
|
102
|
+
} = options;
|
|
103
|
+
return async () => {
|
|
104
|
+
// Step 1: Create a CLI auth session
|
|
105
|
+
let session;
|
|
106
|
+
try {
|
|
107
|
+
const response = await fetch(`${apiUrl}/api/cli/auth/session`, {
|
|
108
|
+
method: 'POST',
|
|
109
|
+
headers: {
|
|
110
|
+
'Content-Type': 'application/json',
|
|
111
|
+
'User-Agent': `kelpi-mcp/${MCP_VERSION}`,
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
if (!response.ok) {
|
|
115
|
+
const errorBody = await response.json().catch(() => ({ error: 'Unknown error' }));
|
|
116
|
+
throw new Error(errorBody.error || `HTTP ${response.status}`);
|
|
117
|
+
}
|
|
118
|
+
session = await response.json();
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
return {
|
|
122
|
+
content: [
|
|
123
|
+
{
|
|
124
|
+
type: 'text',
|
|
125
|
+
text: JSON.stringify({
|
|
126
|
+
error: 'Failed to create authentication session',
|
|
127
|
+
details: err instanceof Error ? err.message : 'Unknown error',
|
|
128
|
+
instructions: 'Check your network connection and try again.',
|
|
129
|
+
}, null, 2),
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
isError: true,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
// Step 2: Validate the verification URL from server
|
|
136
|
+
if (!validateVerificationUrl(session.verification_url)) {
|
|
137
|
+
return {
|
|
138
|
+
content: [
|
|
139
|
+
{
|
|
140
|
+
type: 'text',
|
|
141
|
+
text: JSON.stringify({
|
|
142
|
+
error: 'Invalid verification URL received from server',
|
|
143
|
+
details: 'The verification URL did not pass security validation.',
|
|
144
|
+
}, null, 2),
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
isError: true,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
// Step 3: Open the verification URL in the user's browser
|
|
151
|
+
openBrowser(session.verification_url);
|
|
152
|
+
// Step 4: Poll for completion
|
|
153
|
+
const pollInterval = session.interval ? session.interval * 1000 : pollIntervalMs;
|
|
154
|
+
let pollResult = 'pending';
|
|
155
|
+
let apiKey;
|
|
156
|
+
for (let attempt = 0; attempt < maxPollAttempts; attempt++) {
|
|
157
|
+
await sleep(pollInterval);
|
|
158
|
+
try {
|
|
159
|
+
const pollResponse = await fetch(`${apiUrl}/api/cli/auth/session/poll/${session.device_code}`, {
|
|
160
|
+
method: 'GET',
|
|
161
|
+
headers: {
|
|
162
|
+
'User-Agent': `kelpi-mcp/${MCP_VERSION}`,
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
if (!pollResponse.ok) {
|
|
166
|
+
// Session might have expired (404/410) or other error
|
|
167
|
+
if (pollResponse.status === 404 || pollResponse.status === 410) {
|
|
168
|
+
pollResult = 'expired';
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
// Other errors - continue polling
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
const status = await pollResponse.json();
|
|
175
|
+
if (status.status === 'completed' && status.api_key) {
|
|
176
|
+
pollResult = 'success';
|
|
177
|
+
apiKey = status.api_key;
|
|
178
|
+
// Save the API key to config
|
|
179
|
+
await saveConfig({
|
|
180
|
+
api_key: status.api_key,
|
|
181
|
+
api_url: apiUrl,
|
|
182
|
+
});
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
if (status.status === 'expired') {
|
|
186
|
+
pollResult = 'expired';
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
// Still pending - continue polling
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
// Network error - continue polling
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// Step 5: Return result based on poll outcome
|
|
196
|
+
if (pollResult === 'success') {
|
|
197
|
+
return {
|
|
198
|
+
content: [
|
|
199
|
+
{
|
|
200
|
+
type: 'text',
|
|
201
|
+
text: JSON.stringify({
|
|
202
|
+
status: 'success',
|
|
203
|
+
message: 'Authentication successful! You are now logged in to Kelpi.',
|
|
204
|
+
api_key: apiKey ? `${apiKey.substring(0, 15)}...` : undefined,
|
|
205
|
+
}, null, 2),
|
|
206
|
+
},
|
|
207
|
+
],
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
if (pollResult === 'expired') {
|
|
211
|
+
return {
|
|
212
|
+
content: [
|
|
213
|
+
{
|
|
214
|
+
type: 'text',
|
|
215
|
+
text: JSON.stringify({
|
|
216
|
+
error: 'Authentication session expired',
|
|
217
|
+
instructions: 'Please run kelpi_login again to start a new session.',
|
|
218
|
+
}, null, 2),
|
|
219
|
+
},
|
|
220
|
+
],
|
|
221
|
+
isError: true,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
// Still pending after max attempts - return instructions for manual completion
|
|
225
|
+
return {
|
|
226
|
+
content: [
|
|
227
|
+
{
|
|
228
|
+
type: 'text',
|
|
229
|
+
text: JSON.stringify({
|
|
230
|
+
status: 'pending',
|
|
231
|
+
instructions: `To complete authentication:
|
|
232
|
+
|
|
233
|
+
1. Open this URL in your browser:
|
|
234
|
+
${session.verification_url}
|
|
235
|
+
|
|
236
|
+
2. Enter this code when prompted:
|
|
237
|
+
${session.user_code}
|
|
238
|
+
|
|
239
|
+
3. After completing authentication in the browser, run kelpi_status to verify.`,
|
|
240
|
+
verification_url: session.verification_url,
|
|
241
|
+
user_code: session.user_code,
|
|
242
|
+
}, null, 2),
|
|
243
|
+
},
|
|
244
|
+
],
|
|
245
|
+
};
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Default login handler that uses configured API URL
|
|
250
|
+
* Supports KELPI_API_URL environment variable for local development
|
|
251
|
+
*/
|
|
252
|
+
export const loginHandler = async (input) => {
|
|
253
|
+
const apiUrl = await getApiUrl();
|
|
254
|
+
const handler = createLoginHandler({ apiUrl });
|
|
255
|
+
return handler(input);
|
|
256
|
+
};
|
|
257
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/tools/auth/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Schema for kelpi_login tool input.
|
|
4
|
+
* The login tool has no input parameters - authentication is browser-based.
|
|
5
|
+
*/
|
|
6
|
+
export declare const loginInputSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
|
|
7
|
+
/**
|
|
8
|
+
* Schema for kelpi_login tool output.
|
|
9
|
+
* Returns verification URL and user code for browser authentication,
|
|
10
|
+
* and optionally the result of polling.
|
|
11
|
+
*/
|
|
12
|
+
export declare const loginOutputSchema: z.ZodObject<{
|
|
13
|
+
verification_url: z.ZodString;
|
|
14
|
+
user_code: z.ZodString;
|
|
15
|
+
instructions: z.ZodString;
|
|
16
|
+
poll_result: z.ZodOptional<z.ZodEnum<["pending", "success", "expired", "error"]>>;
|
|
17
|
+
api_key: z.ZodOptional<z.ZodString>;
|
|
18
|
+
workspace_id: z.ZodOptional<z.ZodString>;
|
|
19
|
+
}, "strip", z.ZodTypeAny, {
|
|
20
|
+
verification_url: string;
|
|
21
|
+
user_code: string;
|
|
22
|
+
instructions: string;
|
|
23
|
+
poll_result?: "error" | "pending" | "success" | "expired" | undefined;
|
|
24
|
+
api_key?: string | undefined;
|
|
25
|
+
workspace_id?: string | undefined;
|
|
26
|
+
}, {
|
|
27
|
+
verification_url: string;
|
|
28
|
+
user_code: string;
|
|
29
|
+
instructions: string;
|
|
30
|
+
poll_result?: "error" | "pending" | "success" | "expired" | undefined;
|
|
31
|
+
api_key?: string | undefined;
|
|
32
|
+
workspace_id?: string | undefined;
|
|
33
|
+
}>;
|
|
34
|
+
/**
|
|
35
|
+
* Schema for kelpi_status tool input.
|
|
36
|
+
* The status tool has no input parameters.
|
|
37
|
+
*/
|
|
38
|
+
export declare const statusInputSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
|
|
39
|
+
/**
|
|
40
|
+
* Schema for kelpi_status tool output.
|
|
41
|
+
* Returns current authentication state and workspace info.
|
|
42
|
+
*/
|
|
43
|
+
export declare const statusOutputSchema: z.ZodObject<{
|
|
44
|
+
authenticated: z.ZodBoolean;
|
|
45
|
+
workspace_id: z.ZodOptional<z.ZodString>;
|
|
46
|
+
workspace_name: z.ZodOptional<z.ZodString>;
|
|
47
|
+
key_type: z.ZodOptional<z.ZodEnum<["public", "secret"]>>;
|
|
48
|
+
error: z.ZodOptional<z.ZodString>;
|
|
49
|
+
}, "strip", z.ZodTypeAny, {
|
|
50
|
+
authenticated: boolean;
|
|
51
|
+
error?: string | undefined;
|
|
52
|
+
workspace_id?: string | undefined;
|
|
53
|
+
workspace_name?: string | undefined;
|
|
54
|
+
key_type?: "public" | "secret" | undefined;
|
|
55
|
+
}, {
|
|
56
|
+
authenticated: boolean;
|
|
57
|
+
error?: string | undefined;
|
|
58
|
+
workspace_id?: string | undefined;
|
|
59
|
+
workspace_name?: string | undefined;
|
|
60
|
+
key_type?: "public" | "secret" | undefined;
|
|
61
|
+
}>;
|
|
62
|
+
/**
|
|
63
|
+
* Type aliases for convenience
|
|
64
|
+
*/
|
|
65
|
+
export type LoginInput = z.infer<typeof loginInputSchema>;
|
|
66
|
+
export type LoginOutput = z.infer<typeof loginOutputSchema>;
|
|
67
|
+
export type StatusInput = z.infer<typeof statusInputSchema>;
|
|
68
|
+
export type StatusOutput = z.infer<typeof statusOutputSchema>;
|
|
69
|
+
//# sourceMappingURL=schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../../src/tools/auth/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,eAAO,MAAM,gBAAgB,gDAAe,CAAC;AAE7C;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;EAO5B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,iBAAiB,gDAAe,CAAC;AAE9C;;;GAGG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;EAM7B,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC1D,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Schema for kelpi_login tool input.
|
|
4
|
+
* The login tool has no input parameters - authentication is browser-based.
|
|
5
|
+
*/
|
|
6
|
+
export const loginInputSchema = z.object({});
|
|
7
|
+
/**
|
|
8
|
+
* Schema for kelpi_login tool output.
|
|
9
|
+
* Returns verification URL and user code for browser authentication,
|
|
10
|
+
* and optionally the result of polling.
|
|
11
|
+
*/
|
|
12
|
+
export const loginOutputSchema = z.object({
|
|
13
|
+
verification_url: z.string().url(),
|
|
14
|
+
user_code: z.string(),
|
|
15
|
+
instructions: z.string(),
|
|
16
|
+
poll_result: z.enum(['pending', 'success', 'expired', 'error']).optional(),
|
|
17
|
+
api_key: z.string().optional(),
|
|
18
|
+
workspace_id: z.string().optional(),
|
|
19
|
+
});
|
|
20
|
+
/**
|
|
21
|
+
* Schema for kelpi_status tool input.
|
|
22
|
+
* The status tool has no input parameters.
|
|
23
|
+
*/
|
|
24
|
+
export const statusInputSchema = z.object({});
|
|
25
|
+
/**
|
|
26
|
+
* Schema for kelpi_status tool output.
|
|
27
|
+
* Returns current authentication state and workspace info.
|
|
28
|
+
*/
|
|
29
|
+
export const statusOutputSchema = z.object({
|
|
30
|
+
authenticated: z.boolean(),
|
|
31
|
+
workspace_id: z.string().optional(),
|
|
32
|
+
workspace_name: z.string().optional(),
|
|
33
|
+
key_type: z.enum(['public', 'secret']).optional(),
|
|
34
|
+
error: z.string().optional(),
|
|
35
|
+
});
|
|
36
|
+
//# sourceMappingURL=schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../../src/tools/auth/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAE7C;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IAClC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC1E,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACpC,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAE9C;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE;IAC1B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACnC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACrC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE;IACjD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC7B,CAAC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ToolHandler } from '../../lib/tool-registry.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a status handler.
|
|
4
|
+
* This factory function allows for dependency injection in tests.
|
|
5
|
+
*/
|
|
6
|
+
export declare function createStatusHandler(): ToolHandler;
|
|
7
|
+
/**
|
|
8
|
+
* Default status handler
|
|
9
|
+
*/
|
|
10
|
+
export declare const statusHandler: ToolHandler;
|
|
11
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/tools/auth/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,4BAA4B,CAAC;AAwB1E;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,WAAW,CA8BjD;AAED;;GAEG;AACH,eAAO,MAAM,aAAa,aAAwB,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { loadConfig, getApiUrl } from '../../lib/config.js';
|
|
2
|
+
import { createApiClient } from '../../lib/api-client.js';
|
|
3
|
+
import { successResponse } from '../../lib/tool-helpers.js';
|
|
4
|
+
/**
|
|
5
|
+
* Determines the key type from the API key prefix.
|
|
6
|
+
*/
|
|
7
|
+
function getKeyType(apiKey) {
|
|
8
|
+
if (apiKey.startsWith('klp_sk_'))
|
|
9
|
+
return 'secret';
|
|
10
|
+
if (apiKey.startsWith('klp_pk_'))
|
|
11
|
+
return 'public';
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Creates a status handler.
|
|
16
|
+
* This factory function allows for dependency injection in tests.
|
|
17
|
+
*/
|
|
18
|
+
export function createStatusHandler() {
|
|
19
|
+
return async () => {
|
|
20
|
+
const config = await loadConfig();
|
|
21
|
+
// If no API key, return unauthenticated state
|
|
22
|
+
if (!config.api_key) {
|
|
23
|
+
return successResponse({ authenticated: false });
|
|
24
|
+
}
|
|
25
|
+
const keyType = getKeyType(config.api_key);
|
|
26
|
+
const apiUrl = config.api_url || (await getApiUrl());
|
|
27
|
+
try {
|
|
28
|
+
const client = createApiClient({ apiKey: config.api_key, apiUrl });
|
|
29
|
+
const response = await client.get('/api/v1/auth/me');
|
|
30
|
+
return successResponse({
|
|
31
|
+
authenticated: true,
|
|
32
|
+
workspace_id: response.data.workspace.id,
|
|
33
|
+
workspace_name: response.data.workspace.name,
|
|
34
|
+
key_type: keyType,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
// If API call fails, mark as unauthenticated with error
|
|
39
|
+
return successResponse({
|
|
40
|
+
authenticated: false,
|
|
41
|
+
error: err instanceof Error ? err.message : 'Unknown error',
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Default status handler
|
|
48
|
+
*/
|
|
49
|
+
export const statusHandler = createStatusHandler();
|
|
50
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/tools/auth/status.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAY5D;;GAEG;AACH,SAAS,UAAU,CAAC,MAAc;IAChC,IAAI,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,QAAQ,CAAC;IAClD,IAAI,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,QAAQ,CAAC;IAClD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,KAAK,IAAyB,EAAE;QACrC,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;QAElC,8CAA8C;QAC9C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,eAAe,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC;QACnD,CAAC;QAED,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,SAAS,EAAE,CAAC,CAAC;QAErD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,eAAe,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YACnE,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,GAAG,CAAwB,iBAAiB,CAAC,CAAC;YAE5E,OAAO,eAAe,CAAC;gBACrB,aAAa,EAAE,IAAI;gBACnB,YAAY,EAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE;gBACxC,cAAc,EAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI;gBAC5C,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,wDAAwD;YACxD,OAAO,eAAe,CAAC;gBACrB,aAAa,EAAE,KAAK;gBACpB,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;aAC5D,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,mBAAmB,EAAE,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ToolHandler } from '../../lib/tool-registry.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a create contact handler.
|
|
4
|
+
* This factory function allows for dependency injection in tests.
|
|
5
|
+
*/
|
|
6
|
+
export declare function createCreateContactHandler(): ToolHandler;
|
|
7
|
+
/**
|
|
8
|
+
* Default create contact handler
|
|
9
|
+
*/
|
|
10
|
+
export declare const createContactHandler: ToolHandler;
|
|
11
|
+
//# sourceMappingURL=create.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/tools/contacts/create.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,4BAA4B,CAAC;AAW1E;;;GAGG;AACH,wBAAgB,0BAA0B,IAAI,WAAW,CAwCxD;AAED;;GAEG;AACH,eAAO,MAAM,oBAAoB,aAA+B,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ApiError } from '../../lib/api-client.js';
|
|
2
|
+
import { withAuth, successResponse, validationErrorResponse, errorResponse, unknownErrorResponse, } from '../../lib/tool-helpers.js';
|
|
3
|
+
import { createContactInputSchema } from './schemas.js';
|
|
4
|
+
/**
|
|
5
|
+
* Creates a create contact handler.
|
|
6
|
+
* This factory function allows for dependency injection in tests.
|
|
7
|
+
*/
|
|
8
|
+
export function createCreateContactHandler() {
|
|
9
|
+
return async (input) => {
|
|
10
|
+
// Validate input using Zod schema
|
|
11
|
+
const validationResult = createContactInputSchema.safeParse(input);
|
|
12
|
+
if (!validationResult.success) {
|
|
13
|
+
return validationErrorResponse(validationResult.error);
|
|
14
|
+
}
|
|
15
|
+
const data = validationResult.data;
|
|
16
|
+
// Custom validation: at least one identifier required
|
|
17
|
+
// (Can't use .refine() in schema as it breaks JSON Schema conversion for MCP)
|
|
18
|
+
if (!data.email && !data.external_id) {
|
|
19
|
+
return errorResponse('Validation error', 'At least one of email or external_id is required');
|
|
20
|
+
}
|
|
21
|
+
return withAuth('creating contacts', async ({ client }) => {
|
|
22
|
+
try {
|
|
23
|
+
// Send validated data directly - no need to rebuild the body
|
|
24
|
+
const response = await client.post('/api/v1/contacts', validationResult.data);
|
|
25
|
+
return successResponse(response.data);
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
if (err instanceof ApiError) {
|
|
29
|
+
// Handle duplicate contact (409 Conflict)
|
|
30
|
+
if (err.status === 409) {
|
|
31
|
+
return errorResponse('Contact already exists', err.message, { status: err.status });
|
|
32
|
+
}
|
|
33
|
+
return errorResponse('Failed to create contact', err.message, {
|
|
34
|
+
status: err.status,
|
|
35
|
+
...(err.validationErrors && { validation_errors: err.validationErrors }),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
return unknownErrorResponse(err, 'create contact');
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Default create contact handler
|
|
45
|
+
*/
|
|
46
|
+
export const createContactHandler = createCreateContactHandler();
|
|
47
|
+
//# sourceMappingURL=create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/tools/contacts/create.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EACL,QAAQ,EACR,eAAe,EACf,uBAAuB,EACvB,aAAa,EACb,oBAAoB,GACrB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,wBAAwB,EAAwB,MAAM,cAAc,CAAC;AAE9E;;;GAGG;AACH,MAAM,UAAU,0BAA0B;IACxC,OAAO,KAAK,EAAE,KAA8B,EAAuB,EAAE;QACnE,kCAAkC;QAClC,MAAM,gBAAgB,GAAG,wBAAwB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACnE,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC;YAC9B,OAAO,uBAAuB,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACzD,CAAC;QAED,MAAM,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC;QAEnC,sDAAsD;QACtD,8EAA8E;QAC9E,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACrC,OAAO,aAAa,CAClB,kBAAkB,EAClB,kDAAkD,CACnD,CAAC;QACJ,CAAC;QAED,OAAO,QAAQ,CAAC,mBAAmB,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;YACxD,IAAI,CAAC;gBACH,6DAA6D;gBAC7D,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAkB,kBAAkB,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC;gBAC/F,OAAO,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACxC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;oBAC5B,0CAA0C;oBAC1C,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;wBACvB,OAAO,aAAa,CAAC,wBAAwB,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;oBACtF,CAAC;oBAED,OAAO,aAAa,CAAC,0BAA0B,EAAE,GAAG,CAAC,OAAO,EAAE;wBAC5D,MAAM,EAAE,GAAG,CAAC,MAAM;wBAClB,GAAG,CAAC,GAAG,CAAC,gBAAgB,IAAI,EAAE,iBAAiB,EAAE,GAAG,CAAC,gBAAgB,EAAE,CAAC;qBACzE,CAAC,CAAC;gBACL,CAAC;gBACD,OAAO,oBAAoB,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;YACrD,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,0BAA0B,EAAE,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ToolWithHandler } from '../../lib/tool-registry.js';
|
|
2
|
+
/**
|
|
3
|
+
* kelpi_create_contact tool definition and handler
|
|
4
|
+
*
|
|
5
|
+
* Creates a new contact or updates an existing one.
|
|
6
|
+
*/
|
|
7
|
+
export declare const kelpiCreateContact: ToolWithHandler;
|
|
8
|
+
export * from './schemas.js';
|
|
9
|
+
export { createCreateContactHandler } from './create.js';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/contacts/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAIlE;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,eA2BhC,CAAC;AAGF,cAAc,cAAc,CAAC;AAG7B,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC"}
|