@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.
Files changed (195) hide show
  1. package/README.md +312 -0
  2. package/bin/kelpi-mcp +3 -0
  3. package/dist/__tests__/integration-api/fixtures.d.ts +382 -0
  4. package/dist/__tests__/integration-api/fixtures.d.ts.map +1 -0
  5. package/dist/__tests__/integration-api/fixtures.js +478 -0
  6. package/dist/__tests__/integration-api/fixtures.js.map +1 -0
  7. package/dist/__tests__/integration-api/index.d.ts +19 -0
  8. package/dist/__tests__/integration-api/index.d.ts.map +1 -0
  9. package/dist/__tests__/integration-api/index.js +33 -0
  10. package/dist/__tests__/integration-api/index.js.map +1 -0
  11. package/dist/__tests__/integration-api/setup.d.ts +176 -0
  12. package/dist/__tests__/integration-api/setup.d.ts.map +1 -0
  13. package/dist/__tests__/integration-api/setup.js +329 -0
  14. package/dist/__tests__/integration-api/setup.js.map +1 -0
  15. package/dist/__tests__/setup.d.ts +2 -0
  16. package/dist/__tests__/setup.d.ts.map +1 -0
  17. package/dist/__tests__/setup.js +11 -0
  18. package/dist/__tests__/setup.js.map +1 -0
  19. package/dist/__tests__/unit/test-utils.d.ts +46 -0
  20. package/dist/__tests__/unit/test-utils.d.ts.map +1 -0
  21. package/dist/__tests__/unit/test-utils.js +50 -0
  22. package/dist/__tests__/unit/test-utils.js.map +1 -0
  23. package/dist/index.d.ts +6 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +34 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/lib/api-client.d.ts +17 -0
  28. package/dist/lib/api-client.d.ts.map +1 -0
  29. package/dist/lib/api-client.js +169 -0
  30. package/dist/lib/api-client.js.map +1 -0
  31. package/dist/lib/auth-state.d.ts +54 -0
  32. package/dist/lib/auth-state.d.ts.map +1 -0
  33. package/dist/lib/auth-state.js +131 -0
  34. package/dist/lib/auth-state.js.map +1 -0
  35. package/dist/lib/config.d.ts +39 -0
  36. package/dist/lib/config.d.ts.map +1 -0
  37. package/dist/lib/config.js +170 -0
  38. package/dist/lib/config.js.map +1 -0
  39. package/dist/lib/error-formatter.d.ts +40 -0
  40. package/dist/lib/error-formatter.d.ts.map +1 -0
  41. package/dist/lib/error-formatter.js +149 -0
  42. package/dist/lib/error-formatter.js.map +1 -0
  43. package/dist/lib/errors.d.ts +44 -0
  44. package/dist/lib/errors.d.ts.map +1 -0
  45. package/dist/lib/errors.js +56 -0
  46. package/dist/lib/errors.js.map +1 -0
  47. package/dist/lib/tool-helpers.d.ts +49 -0
  48. package/dist/lib/tool-helpers.d.ts.map +1 -0
  49. package/dist/lib/tool-helpers.js +101 -0
  50. package/dist/lib/tool-helpers.js.map +1 -0
  51. package/dist/lib/tool-registry.d.ts +111 -0
  52. package/dist/lib/tool-registry.d.ts.map +1 -0
  53. package/dist/lib/tool-registry.js +112 -0
  54. package/dist/lib/tool-registry.js.map +1 -0
  55. package/dist/lib/version.d.ts +13 -0
  56. package/dist/lib/version.d.ts.map +1 -0
  57. package/dist/lib/version.js +13 -0
  58. package/dist/lib/version.js.map +1 -0
  59. package/dist/prompts/flow-generator.d.ts +45 -0
  60. package/dist/prompts/flow-generator.d.ts.map +1 -0
  61. package/dist/prompts/flow-generator.js +177 -0
  62. package/dist/prompts/flow-generator.js.map +1 -0
  63. package/dist/prompts/index.d.ts +7 -0
  64. package/dist/prompts/index.d.ts.map +1 -0
  65. package/dist/prompts/index.js +7 -0
  66. package/dist/prompts/index.js.map +1 -0
  67. package/dist/server.d.ts +66 -0
  68. package/dist/server.d.ts.map +1 -0
  69. package/dist/server.js +140 -0
  70. package/dist/server.js.map +1 -0
  71. package/dist/tools/auth/index.d.ts +18 -0
  72. package/dist/tools/auth/index.d.ts.map +1 -0
  73. package/dist/tools/auth/index.js +50 -0
  74. package/dist/tools/auth/index.js.map +1 -0
  75. package/dist/tools/auth/login.d.ts +37 -0
  76. package/dist/tools/auth/login.d.ts.map +1 -0
  77. package/dist/tools/auth/login.js +257 -0
  78. package/dist/tools/auth/login.js.map +1 -0
  79. package/dist/tools/auth/schemas.d.ts +69 -0
  80. package/dist/tools/auth/schemas.d.ts.map +1 -0
  81. package/dist/tools/auth/schemas.js +36 -0
  82. package/dist/tools/auth/schemas.js.map +1 -0
  83. package/dist/tools/auth/status.d.ts +11 -0
  84. package/dist/tools/auth/status.d.ts.map +1 -0
  85. package/dist/tools/auth/status.js +50 -0
  86. package/dist/tools/auth/status.js.map +1 -0
  87. package/dist/tools/contacts/create.d.ts +11 -0
  88. package/dist/tools/contacts/create.d.ts.map +1 -0
  89. package/dist/tools/contacts/create.js +47 -0
  90. package/dist/tools/contacts/create.js.map +1 -0
  91. package/dist/tools/contacts/index.d.ts +10 -0
  92. package/dist/tools/contacts/index.d.ts.map +1 -0
  93. package/dist/tools/contacts/index.js +40 -0
  94. package/dist/tools/contacts/index.js.map +1 -0
  95. package/dist/tools/contacts/schemas.d.ts +37 -0
  96. package/dist/tools/contacts/schemas.d.ts.map +1 -0
  97. package/dist/tools/contacts/schemas.js +15 -0
  98. package/dist/tools/contacts/schemas.js.map +1 -0
  99. package/dist/tools/events/index.d.ts +10 -0
  100. package/dist/tools/events/index.d.ts.map +1 -0
  101. package/dist/tools/events/index.js +42 -0
  102. package/dist/tools/events/index.js.map +1 -0
  103. package/dist/tools/events/schemas.d.ts +37 -0
  104. package/dist/tools/events/schemas.d.ts.map +1 -0
  105. package/dist/tools/events/schemas.js +17 -0
  106. package/dist/tools/events/schemas.js.map +1 -0
  107. package/dist/tools/events/track.d.ts +11 -0
  108. package/dist/tools/events/track.d.ts.map +1 -0
  109. package/dist/tools/events/track.js +41 -0
  110. package/dist/tools/events/track.js.map +1 -0
  111. package/dist/tools/flows/activate.d.ts +11 -0
  112. package/dist/tools/flows/activate.d.ts.map +1 -0
  113. package/dist/tools/flows/activate.js +46 -0
  114. package/dist/tools/flows/activate.js.map +1 -0
  115. package/dist/tools/flows/create.d.ts +11 -0
  116. package/dist/tools/flows/create.d.ts.map +1 -0
  117. package/dist/tools/flows/create.js +72 -0
  118. package/dist/tools/flows/create.js.map +1 -0
  119. package/dist/tools/flows/index.d.ts +24 -0
  120. package/dist/tools/flows/index.d.ts.map +1 -0
  121. package/dist/tools/flows/index.js +183 -0
  122. package/dist/tools/flows/index.js.map +1 -0
  123. package/dist/tools/flows/list.d.ts +11 -0
  124. package/dist/tools/flows/list.d.ts.map +1 -0
  125. package/dist/tools/flows/list.js +34 -0
  126. package/dist/tools/flows/list.js.map +1 -0
  127. package/dist/tools/flows/schemas.d.ts +621 -0
  128. package/dist/tools/flows/schemas.d.ts.map +1 -0
  129. package/dist/tools/flows/schemas.js +135 -0
  130. package/dist/tools/flows/schemas.js.map +1 -0
  131. package/dist/tools/flows/transform.d.ts +39 -0
  132. package/dist/tools/flows/transform.d.ts.map +1 -0
  133. package/dist/tools/flows/transform.js +139 -0
  134. package/dist/tools/flows/transform.js.map +1 -0
  135. package/dist/tools/index.d.ts +34 -0
  136. package/dist/tools/index.d.ts.map +1 -0
  137. package/dist/tools/index.js +46 -0
  138. package/dist/tools/index.js.map +1 -0
  139. package/dist/tools/sdk/index.d.ts +18 -0
  140. package/dist/tools/sdk/index.d.ts.map +1 -0
  141. package/dist/tools/sdk/index.js +69 -0
  142. package/dist/tools/sdk/index.js.map +1 -0
  143. package/dist/tools/sdk/public-key.d.ts +11 -0
  144. package/dist/tools/sdk/public-key.d.ts.map +1 -0
  145. package/dist/tools/sdk/public-key.js +24 -0
  146. package/dist/tools/sdk/public-key.js.map +1 -0
  147. package/dist/tools/sdk/schemas.d.ts +48 -0
  148. package/dist/tools/sdk/schemas.d.ts.map +1 -0
  149. package/dist/tools/sdk/schemas.js +35 -0
  150. package/dist/tools/sdk/schemas.js.map +1 -0
  151. package/dist/tools/sdk/snippet.d.ts +11 -0
  152. package/dist/tools/sdk/snippet.d.ts.map +1 -0
  153. package/dist/tools/sdk/snippet.js +50 -0
  154. package/dist/tools/sdk/snippet.js.map +1 -0
  155. package/dist/tools/sdk/templates/index.d.ts +5 -0
  156. package/dist/tools/sdk/templates/index.d.ts.map +1 -0
  157. package/dist/tools/sdk/templates/index.js +5 -0
  158. package/dist/tools/sdk/templates/index.js.map +1 -0
  159. package/dist/tools/sdk/templates/nextjs.d.ts +5 -0
  160. package/dist/tools/sdk/templates/nextjs.d.ts.map +1 -0
  161. package/dist/tools/sdk/templates/nextjs.js +71 -0
  162. package/dist/tools/sdk/templates/nextjs.js.map +1 -0
  163. package/dist/tools/sdk/templates/node.d.ts +9 -0
  164. package/dist/tools/sdk/templates/node.d.ts.map +1 -0
  165. package/dist/tools/sdk/templates/node.js +170 -0
  166. package/dist/tools/sdk/templates/node.js.map +1 -0
  167. package/dist/tools/sdk/templates/react.d.ts +5 -0
  168. package/dist/tools/sdk/templates/react.d.ts.map +1 -0
  169. package/dist/tools/sdk/templates/react.js +54 -0
  170. package/dist/tools/sdk/templates/react.js.map +1 -0
  171. package/dist/tools/sdk/templates/vanilla.d.ts +5 -0
  172. package/dist/tools/sdk/templates/vanilla.d.ts.map +1 -0
  173. package/dist/tools/sdk/templates/vanilla.js +61 -0
  174. package/dist/tools/sdk/templates/vanilla.js.map +1 -0
  175. package/dist/tools/templates/create.d.ts +11 -0
  176. package/dist/tools/templates/create.d.ts.map +1 -0
  177. package/dist/tools/templates/create.js +39 -0
  178. package/dist/tools/templates/create.js.map +1 -0
  179. package/dist/tools/templates/index.d.ts +17 -0
  180. package/dist/tools/templates/index.d.ts.map +1 -0
  181. package/dist/tools/templates/index.js +68 -0
  182. package/dist/tools/templates/index.js.map +1 -0
  183. package/dist/tools/templates/list.d.ts +11 -0
  184. package/dist/tools/templates/list.d.ts.map +1 -0
  185. package/dist/tools/templates/list.js +31 -0
  186. package/dist/tools/templates/list.js.map +1 -0
  187. package/dist/tools/templates/schemas.d.ts +90 -0
  188. package/dist/tools/templates/schemas.d.ts.map +1 -0
  189. package/dist/tools/templates/schemas.js +37 -0
  190. package/dist/tools/templates/schemas.js.map +1 -0
  191. package/dist/types.d.ts +55 -0
  192. package/dist/types.d.ts.map +1 -0
  193. package/dist/types.js +2 -0
  194. package/dist/types.js.map +1 -0
  195. 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"}