@tacitai/mcp-server 0.1.1 → 0.3.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 (70) hide show
  1. package/dist/auth.d.ts +32 -0
  2. package/dist/auth.js +64 -0
  3. package/dist/client.d.ts +60 -5
  4. package/dist/client.js +234 -53
  5. package/dist/index.js +130 -106
  6. package/dist/oauth.d.ts +115 -0
  7. package/dist/oauth.js +619 -0
  8. package/dist/prompts.d.ts +2 -0
  9. package/dist/prompts.js +12 -0
  10. package/dist/setup.d.ts +28 -5
  11. package/dist/setup.js +266 -59
  12. package/dist/tools/agents.d.ts +277 -0
  13. package/dist/tools/agents.js +335 -0
  14. package/dist/tools/annotations.d.ts +117 -0
  15. package/dist/tools/annotations.js +130 -0
  16. package/dist/tools/artifacts.d.ts +178 -8
  17. package/dist/tools/artifacts.js +372 -81
  18. package/dist/tools/chronicle.d.ts +3 -0
  19. package/dist/tools/chronicle.js +165 -0
  20. package/dist/tools/connector_write_back.d.ts +3 -0
  21. package/dist/tools/connector_write_back.js +27 -0
  22. package/dist/tools/converse.d.ts +10 -0
  23. package/dist/tools/converse.js +88 -0
  24. package/dist/tools/crews.d.ts +3 -0
  25. package/dist/tools/crews.js +115 -0
  26. package/dist/tools/drafts.d.ts +83 -0
  27. package/dist/tools/drafts.js +86 -0
  28. package/dist/tools/errors.d.ts +15 -0
  29. package/dist/tools/errors.js +21 -0
  30. package/dist/tools/export.d.ts +54 -0
  31. package/dist/tools/export.js +55 -0
  32. package/dist/tools/gm.d.ts +214 -0
  33. package/dist/tools/gm.js +198 -0
  34. package/dist/tools/ingest.d.ts +58 -4
  35. package/dist/tools/ingest.js +109 -76
  36. package/dist/tools/kb.d.ts +544 -0
  37. package/dist/tools/kb.js +687 -0
  38. package/dist/tools/lake-structure.d.ts +3 -0
  39. package/dist/tools/lake-structure.js +126 -0
  40. package/dist/tools/lake.d.ts +932 -0
  41. package/dist/tools/lake.js +1017 -0
  42. package/dist/tools/move.d.ts +200 -0
  43. package/dist/tools/move.js +96 -0
  44. package/dist/tools/outbox.d.ts +274 -0
  45. package/dist/tools/outbox.js +223 -0
  46. package/dist/tools/people.d.ts +3 -0
  47. package/dist/tools/people.js +59 -0
  48. package/dist/tools/pyramid.d.ts +554 -0
  49. package/dist/tools/pyramid.js +758 -0
  50. package/dist/tools/recall.d.ts +2 -0
  51. package/dist/tools/recall.js +28 -17
  52. package/dist/tools/registry.d.ts +17 -0
  53. package/dist/tools/registry.js +199 -0
  54. package/dist/tools/research.d.ts +47 -0
  55. package/dist/tools/research.js +575 -0
  56. package/dist/tools/search.d.ts +9 -0
  57. package/dist/tools/search.js +86 -25
  58. package/dist/tools/sharing.d.ts +63 -0
  59. package/dist/tools/sharing.js +157 -0
  60. package/dist/tools/skills.d.ts +9 -0
  61. package/dist/tools/skills.js +98 -0
  62. package/dist/tools/synthesize.d.ts +54 -2
  63. package/dist/tools/synthesize.js +80 -23
  64. package/dist/tools/web-url.d.ts +57 -0
  65. package/dist/tools/web-url.js +74 -0
  66. package/dist/tools/workspaces.d.ts +3 -0
  67. package/dist/tools/workspaces.js +47 -0
  68. package/dist/transport.d.ts +9 -0
  69. package/dist/transport.js +209 -0
  70. package/package.json +5 -4
@@ -0,0 +1,1017 @@
1
+ // SPDX-License-Identifier: MIT
2
+ /**
3
+ * Lake tools — CLI wrappers for data lake source, sync, proposal,
4
+ * classification, catalog, taxonomy, and subject-classification operations
5
+ * on the Axum REST API.
6
+ *
7
+ * Routes (Axum, all under /api/v1/org/lake):
8
+ * POST /onboard
9
+ * GET /sources
10
+ * DELETE /sources/:id
11
+ * GET /status
12
+ * POST /sync
13
+ * GET /proposals
14
+ * POST /proposals/confirm
15
+ * POST /classify
16
+ * POST /catalog/:id/reclassify
17
+ * POST /writeback
18
+ * GET /catalog
19
+ * GET /catalog/:id
20
+ * DELETE /catalog/:id
21
+ * POST /ingest
22
+ * GET /taxonomy
23
+ * POST /taxonomy/seed
24
+ * POST /taxonomy/nodes
25
+ * POST /catalog/:id/subject
26
+ * POST /catalog/subject/bulk
27
+ */
28
+ import { z } from 'zod';
29
+ import { getClient, TacitApiError, TokenExpiredError } from '../client.js';
30
+ function apiErrorResult(err, toolName) {
31
+ if (err instanceof TokenExpiredError) {
32
+ return {
33
+ content: [{ type: 'text', text: err.message }],
34
+ isError: true,
35
+ };
36
+ }
37
+ if (err instanceof TacitApiError) {
38
+ return { content: [{ type: 'text', text: `API error ${err.statusCode} on ${toolName}: ${err.body}` }], isError: true };
39
+ }
40
+ const msg = err instanceof Error ? err.message : String(err);
41
+ return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
42
+ }
43
+ // ─── tacit_lake_register_source ─────────────────────────────────────────────
44
+ export const registerSourceInputSchema = z.object({
45
+ source: z.string().min(1).describe('Source path / s3:// URI / git remote'),
46
+ kind: z.string().optional().describe('Source kind: localfs|s3|git; inferred from source if omitted'),
47
+ sync_mode: z.string().optional().describe('Sync mode: manual|scheduled|event; defaults to MANUAL'),
48
+ interval: z.number().optional().describe('Scheduled-only interval in seconds'),
49
+ write_back: z.boolean().optional().describe('Enable Mode B write-back'),
50
+ write_back_path: z.string().optional().describe('Repo-relative partition for write-back'),
51
+ default_kb_collection: z.string().optional().describe('Per-source default KB collection name'),
52
+ webhook_secret: z.string().optional().describe('HMAC-SHA256 secret for event-driven webhook sync (LAKE-18)'),
53
+ });
54
+ export const REGISTER_SOURCE_TOOL_DEF = {
55
+ name: 'tacit_lake_register_source',
56
+ description: 'Register a new data lake source (onboard). Route: POST /api/v1/org/lake/onboard.',
57
+ inputSchema: {
58
+ type: 'object',
59
+ properties: {
60
+ source: { type: 'string', description: 'Source path / s3:// URI / git remote' },
61
+ kind: { type: 'string', description: 'Source kind: localfs|s3|git; inferred from source if omitted' },
62
+ sync_mode: { type: 'string', description: 'Sync mode: manual|scheduled|event; defaults to MANUAL' },
63
+ interval: { type: 'number', description: 'Scheduled-only interval in seconds' },
64
+ write_back: { type: 'boolean', description: 'Enable Mode B write-back' },
65
+ write_back_path: { type: 'string', description: 'Repo-relative partition for write-back' },
66
+ default_kb_collection: { type: 'string', description: 'Per-source default KB collection name' },
67
+ webhook_secret: { type: 'string', description: 'HMAC-SHA256 secret for event-driven webhook sync (LAKE-18)' },
68
+ },
69
+ required: ['source'],
70
+ },
71
+ };
72
+ export function buildRegisterSourceRequest(client, input) {
73
+ return {
74
+ async execute() {
75
+ try {
76
+ const body = { source: input.source };
77
+ if (input.kind !== undefined)
78
+ body['kind'] = input.kind;
79
+ if (input.sync_mode !== undefined)
80
+ body['sync_mode'] = input.sync_mode;
81
+ if (input.interval !== undefined)
82
+ body['interval'] = input.interval;
83
+ if (input.write_back !== undefined)
84
+ body['write_back'] = input.write_back;
85
+ if (input.write_back_path !== undefined)
86
+ body['write_back_path'] = input.write_back_path;
87
+ if (input.default_kb_collection !== undefined)
88
+ body['default_kb_collection'] = input.default_kb_collection;
89
+ if (input.webhook_secret !== undefined)
90
+ body['webhook_secret'] = input.webhook_secret;
91
+ const result = await client.post('/api/v1/org/lake/onboard', body);
92
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
93
+ }
94
+ catch (err) {
95
+ return apiErrorResult(err, 'tacit_lake_register_source');
96
+ }
97
+ },
98
+ };
99
+ }
100
+ export async function handleRegisterSource(args) {
101
+ const parsed = registerSourceInputSchema.safeParse(args);
102
+ if (!parsed.success) {
103
+ return { content: [{ type: 'text', text: `Invalid input: ${parsed.error.message}` }], isError: true };
104
+ }
105
+ return buildRegisterSourceRequest(getClient(), parsed.data).execute();
106
+ }
107
+ // ─── tacit_lake_list_sources ─────────────────────────────────────────────────
108
+ export const listSourcesInputSchema = z.object({});
109
+ export const LIST_SOURCES_TOOL_DEF = {
110
+ name: 'tacit_lake_list_sources',
111
+ description: 'List registered data lake sources for the current workspace. Route: GET /api/v1/org/lake/sources.',
112
+ inputSchema: {
113
+ type: 'object',
114
+ properties: {},
115
+ required: [],
116
+ },
117
+ };
118
+ export function buildListSourcesRequest(client, _input) {
119
+ return {
120
+ async execute() {
121
+ try {
122
+ const result = await client.get('/api/v1/org/lake/sources');
123
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
124
+ }
125
+ catch (err) {
126
+ return apiErrorResult(err, 'tacit_lake_list_sources');
127
+ }
128
+ },
129
+ };
130
+ }
131
+ export async function handleListSources(args) {
132
+ const parsed = listSourcesInputSchema.safeParse(args);
133
+ if (!parsed.success) {
134
+ return { content: [{ type: 'text', text: `Invalid input: ${parsed.error.message}` }], isError: true };
135
+ }
136
+ return buildListSourcesRequest(getClient(), parsed.data).execute();
137
+ }
138
+ // ─── tacit_lake_deregister_source ───────────────────────────────────────────
139
+ export const deregisterSourceInputSchema = z.object({
140
+ source_id: z.string().uuid().describe('Source to deregister'),
141
+ });
142
+ export const DEREGISTER_SOURCE_TOOL_DEF = {
143
+ name: 'tacit_lake_deregister_source',
144
+ description: 'Deregister a data lake source (soft-delete). Archives catalog entries and clears sync queue. Destructive — T3 approval required. Route: DELETE /api/v1/org/lake/sources/{source_id}.',
145
+ inputSchema: {
146
+ type: 'object',
147
+ properties: {
148
+ source_id: { type: 'string', description: 'Source to deregister' },
149
+ },
150
+ required: ['source_id'],
151
+ },
152
+ };
153
+ export function buildDeregisterSourceRequest(client, input) {
154
+ return {
155
+ async execute() {
156
+ try {
157
+ const result = await client.delete(`/api/v1/org/lake/sources/${input.source_id}`);
158
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
159
+ }
160
+ catch (err) {
161
+ return apiErrorResult(err, 'tacit_lake_deregister_source');
162
+ }
163
+ },
164
+ };
165
+ }
166
+ export async function handleDeregisterSource(args) {
167
+ const parsed = deregisterSourceInputSchema.safeParse(args);
168
+ if (!parsed.success) {
169
+ return { content: [{ type: 'text', text: `Invalid input: ${parsed.error.message}` }], isError: true };
170
+ }
171
+ return buildDeregisterSourceRequest(getClient(), parsed.data).execute();
172
+ }
173
+ // ─── tacit_lake_sync_status ──────────────────────────────────────────────────
174
+ export const syncStatusInputSchema = z.object({
175
+ source_id: z.string().uuid().optional().describe('Filter by source ID'),
176
+ });
177
+ export const SYNC_STATUS_TOOL_DEF = {
178
+ name: 'tacit_lake_sync_status',
179
+ description: 'Check data lake sync status — running runs, active catalog rows, latest run status. Route: GET /api/v1/org/lake/status.',
180
+ inputSchema: {
181
+ type: 'object',
182
+ properties: {
183
+ source_id: { type: 'string', description: 'Filter by source ID' },
184
+ },
185
+ required: [],
186
+ },
187
+ };
188
+ export function buildSyncStatusRequest(client, input) {
189
+ return {
190
+ async execute() {
191
+ try {
192
+ const params = {};
193
+ if (input.source_id !== undefined)
194
+ params['source_id'] = input.source_id;
195
+ const result = await client.get('/api/v1/org/lake/status', params);
196
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
197
+ }
198
+ catch (err) {
199
+ return apiErrorResult(err, 'tacit_lake_sync_status');
200
+ }
201
+ },
202
+ };
203
+ }
204
+ export async function handleSyncStatus(args) {
205
+ const parsed = syncStatusInputSchema.safeParse(args);
206
+ if (!parsed.success) {
207
+ return { content: [{ type: 'text', text: `Invalid input: ${parsed.error.message}` }], isError: true };
208
+ }
209
+ return buildSyncStatusRequest(getClient(), parsed.data).execute();
210
+ }
211
+ // ─── tacit_lake_trigger_sync ─────────────────────────────────────────────────
212
+ export const triggerSyncInputSchema = z.object({
213
+ source_id: z.string().uuid().describe('Source to sync'),
214
+ confirm_deletions: z.boolean().optional().describe('Confirm deletion of removed source files'),
215
+ });
216
+ export const TRIGGER_SYNC_TOOL_DEF = {
217
+ name: 'tacit_lake_trigger_sync',
218
+ description: 'Trigger an incremental sync from a registered data lake source. Route: POST /api/v1/org/lake/sync.',
219
+ inputSchema: {
220
+ type: 'object',
221
+ properties: {
222
+ source_id: { type: 'string', description: 'Source to sync' },
223
+ confirm_deletions: { type: 'boolean', description: 'Confirm deletion of removed source files' },
224
+ },
225
+ required: ['source_id'],
226
+ },
227
+ };
228
+ export function buildTriggerSyncRequest(client, input) {
229
+ return {
230
+ async execute() {
231
+ try {
232
+ const body = { source_id: input.source_id };
233
+ if (input.confirm_deletions !== undefined)
234
+ body['confirm_deletions'] = input.confirm_deletions;
235
+ const result = await client.post('/api/v1/org/lake/sync', body);
236
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
237
+ }
238
+ catch (err) {
239
+ return apiErrorResult(err, 'tacit_lake_trigger_sync');
240
+ }
241
+ },
242
+ };
243
+ }
244
+ export async function handleTriggerSync(args) {
245
+ const parsed = triggerSyncInputSchema.safeParse(args);
246
+ if (!parsed.success) {
247
+ return { content: [{ type: 'text', text: `Invalid input: ${parsed.error.message}` }], isError: true };
248
+ }
249
+ return buildTriggerSyncRequest(getClient(), parsed.data).execute();
250
+ }
251
+ // ─── tacit_lake_list_proposals ───────────────────────────────────────────────
252
+ export const listProposalsInputSchema = z.object({});
253
+ export const LIST_PROPOSALS_TOOL_DEF = {
254
+ name: 'tacit_lake_list_proposals',
255
+ description: 'List pending org-structure placement proposals from the data lake bridge. Route: GET /api/v1/org/lake/proposals.',
256
+ inputSchema: {
257
+ type: 'object',
258
+ properties: {},
259
+ required: [],
260
+ },
261
+ };
262
+ export function buildListProposalsRequest(client, _input) {
263
+ return {
264
+ async execute() {
265
+ try {
266
+ const result = await client.get('/api/v1/org/lake/proposals');
267
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
268
+ }
269
+ catch (err) {
270
+ return apiErrorResult(err, 'tacit_lake_list_proposals');
271
+ }
272
+ },
273
+ };
274
+ }
275
+ export async function handleListProposals(args) {
276
+ const parsed = listProposalsInputSchema.safeParse(args);
277
+ if (!parsed.success) {
278
+ return { content: [{ type: 'text', text: `Invalid input: ${parsed.error.message}` }], isError: true };
279
+ }
280
+ return buildListProposalsRequest(getClient(), parsed.data).execute();
281
+ }
282
+ // ─── tacit_lake_confirm_proposal ─────────────────────────────────────────────
283
+ export const confirmProposalInputSchema = z.object({
284
+ proposal_id: z.string().uuid().describe('Proposal to confirm'),
285
+ });
286
+ export const CONFIRM_PROPOSAL_TOOL_DEF = {
287
+ name: 'tacit_lake_confirm_proposal',
288
+ description: 'Confirm a placement proposal, applying the org-structure link. Route: POST /api/v1/org/lake/proposals/confirm.',
289
+ inputSchema: {
290
+ type: 'object',
291
+ properties: {
292
+ proposal_id: { type: 'string', description: 'Proposal to confirm' },
293
+ },
294
+ required: ['proposal_id'],
295
+ },
296
+ };
297
+ export function buildConfirmProposalRequest(client, input) {
298
+ return {
299
+ async execute() {
300
+ try {
301
+ const result = await client.post('/api/v1/org/lake/proposals/confirm', { proposal_id: input.proposal_id });
302
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
303
+ }
304
+ catch (err) {
305
+ return apiErrorResult(err, 'tacit_lake_confirm_proposal');
306
+ }
307
+ },
308
+ };
309
+ }
310
+ export async function handleConfirmProposal(args) {
311
+ const parsed = confirmProposalInputSchema.safeParse(args);
312
+ if (!parsed.success) {
313
+ return { content: [{ type: 'text', text: `Invalid input: ${parsed.error.message}` }], isError: true };
314
+ }
315
+ return buildConfirmProposalRequest(getClient(), parsed.data).execute();
316
+ }
317
+ // ─── tacit_lake_classify ─────────────────────────────────────────────────────
318
+ export const classifyInputSchema = z.object({
319
+ source_uri: z.string().min(1).describe('URI of the document to classify'),
320
+ content: z.string().optional().describe('Document content for classification'),
321
+ });
322
+ export const CLASSIFY_TOOL_DEF = {
323
+ name: 'tacit_lake_classify',
324
+ description: 'Run ad-hoc classification on a document URI and optional content to get a placement proposal. Route: POST /api/v1/org/lake/classify.',
325
+ inputSchema: {
326
+ type: 'object',
327
+ properties: {
328
+ source_uri: { type: 'string', description: 'URI of the document to classify' },
329
+ content: { type: 'string', description: 'Document content for classification' },
330
+ },
331
+ required: ['source_uri'],
332
+ },
333
+ };
334
+ export function buildClassifyRequest(client, input) {
335
+ return {
336
+ async execute() {
337
+ try {
338
+ const body = { source_uri: input.source_uri };
339
+ if (input.content !== undefined)
340
+ body['content'] = input.content;
341
+ const result = await client.post('/api/v1/org/lake/classify', body);
342
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
343
+ }
344
+ catch (err) {
345
+ return apiErrorResult(err, 'tacit_lake_classify');
346
+ }
347
+ },
348
+ };
349
+ }
350
+ export async function handleClassify(args) {
351
+ const parsed = classifyInputSchema.safeParse(args);
352
+ if (!parsed.success) {
353
+ return { content: [{ type: 'text', text: `Invalid input: ${parsed.error.message}` }], isError: true };
354
+ }
355
+ return buildClassifyRequest(getClient(), parsed.data).execute();
356
+ }
357
+ // ─── tacit_lake_reclassify ───────────────────────────────────────────────────
358
+ export const reclassifyInputSchema = z.object({
359
+ catalog_id: z.string().uuid().describe('Catalog item to reclassify'),
360
+ proposed_portfolio: z.string().optional().describe('New portfolio placement'),
361
+ proposed_program: z.string().optional().describe('New program placement'),
362
+ proposed_domain_id: z.string().optional().describe('New domain ID placement'),
363
+ });
364
+ export const RECLASSIFY_TOOL_DEF = {
365
+ name: 'tacit_lake_reclassify',
366
+ description: 'Create a reclassification proposal to move a catalog item to a different placement. Route: POST /api/v1/org/lake/catalog/{catalog_id}/reclassify.',
367
+ inputSchema: {
368
+ type: 'object',
369
+ properties: {
370
+ catalog_id: { type: 'string', description: 'Catalog item to reclassify' },
371
+ proposed_portfolio: { type: 'string', description: 'New portfolio placement' },
372
+ proposed_program: { type: 'string', description: 'New program placement' },
373
+ proposed_domain_id: { type: 'string', description: 'New domain ID placement' },
374
+ },
375
+ required: ['catalog_id'],
376
+ },
377
+ };
378
+ export function buildReclassifyRequest(client, input) {
379
+ return {
380
+ async execute() {
381
+ try {
382
+ const body = {};
383
+ if (input.proposed_portfolio !== undefined)
384
+ body['proposed_portfolio'] = input.proposed_portfolio;
385
+ if (input.proposed_program !== undefined)
386
+ body['proposed_program'] = input.proposed_program;
387
+ if (input.proposed_domain_id !== undefined)
388
+ body['proposed_domain_id'] = input.proposed_domain_id;
389
+ const result = await client.post(`/api/v1/org/lake/catalog/${input.catalog_id}/reclassify`, body);
390
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
391
+ }
392
+ catch (err) {
393
+ return apiErrorResult(err, 'tacit_lake_reclassify');
394
+ }
395
+ },
396
+ };
397
+ }
398
+ export async function handleReclassify(args) {
399
+ const parsed = reclassifyInputSchema.safeParse(args);
400
+ if (!parsed.success) {
401
+ return { content: [{ type: 'text', text: `Invalid input: ${parsed.error.message}` }], isError: true };
402
+ }
403
+ return buildReclassifyRequest(getClient(), parsed.data).execute();
404
+ }
405
+ // ─── tacit_lake_writeback ────────────────────────────────────────────────────
406
+ export const writebackInputSchema = z.object({
407
+ source_id: z.string().uuid().describe('Source to write back to'),
408
+ artifact_id: z.string().uuid().describe('Artifact to write back'),
409
+ target_folder: z.string().optional().describe('Repo-relative folder to write into (overrides write_back_path)'),
410
+ slug: z.string().optional().describe('Filename slug (without extension); defaults to artifact_id'),
411
+ frontmatter: z.object({
412
+ subject: z.string().optional(),
413
+ title: z.string().optional(),
414
+ supersedes: z.string().uuid().optional(),
415
+ sensitivity: z.string().optional(),
416
+ status: z.string().optional(),
417
+ }).optional().describe('YAML frontmatter overrides for the written file (LAKE-18)'),
418
+ });
419
+ export const WRITEBACK_TOOL_DEF = {
420
+ name: 'tacit_lake_writeback',
421
+ description: 'Write back an artifact to its source Git repository via the LakeWriter. Route: POST /api/v1/org/lake/writeback.',
422
+ inputSchema: {
423
+ type: 'object',
424
+ properties: {
425
+ source_id: { type: 'string', description: 'Source to write back to' },
426
+ artifact_id: { type: 'string', description: 'Artifact to write back' },
427
+ target_folder: { type: 'string', description: 'Repo-relative folder to write into (overrides write_back_path)' },
428
+ slug: { type: 'string', description: 'Filename slug (without extension); defaults to artifact_id' },
429
+ frontmatter: { type: 'object', description: 'YAML frontmatter overrides: subject, title, supersedes, sensitivity, status' },
430
+ },
431
+ required: ['source_id', 'artifact_id'],
432
+ },
433
+ };
434
+ export function buildWritebackRequest(client, input) {
435
+ return {
436
+ async execute() {
437
+ try {
438
+ const body = {
439
+ source_id: input.source_id,
440
+ artifact_id: input.artifact_id,
441
+ };
442
+ if (input.target_folder !== undefined)
443
+ body['target_folder'] = input.target_folder;
444
+ if (input.slug !== undefined)
445
+ body['slug'] = input.slug;
446
+ if (input.frontmatter !== undefined)
447
+ body['frontmatter'] = input.frontmatter;
448
+ const result = await client.post('/api/v1/org/lake/writeback', body);
449
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
450
+ }
451
+ catch (err) {
452
+ return apiErrorResult(err, 'tacit_lake_writeback');
453
+ }
454
+ },
455
+ };
456
+ }
457
+ export async function handleWriteback(args) {
458
+ const parsed = writebackInputSchema.safeParse(args);
459
+ if (!parsed.success) {
460
+ return { content: [{ type: 'text', text: `Invalid input: ${parsed.error.message}` }], isError: true };
461
+ }
462
+ return buildWritebackRequest(getClient(), parsed.data).execute();
463
+ }
464
+ // ─── tacit_lake_browse_catalog ───────────────────────────────────────────────
465
+ export const browseCatalogInputSchema = z.object({
466
+ limit: z.number().optional().describe('Max items to return'),
467
+ offset: z.number().optional().describe('Pagination offset'),
468
+ origin: z.string().optional().describe('Filter by origin'),
469
+ catalog_status: z.string().optional().describe('Filter by catalog status'),
470
+ content_type: z.string().optional().describe('Filter by content type'),
471
+ source_id: z.string().uuid().optional().describe('Filter by source ID'),
472
+ q: z.string().optional().describe('Search query'),
473
+ subject_id: z.string().uuid().optional().describe('Filter by subject node ID'),
474
+ subject_needs_review: z.boolean().optional().describe('Filter by review status'),
475
+ subject_layer: z.string().optional().describe('Filter by subject layer'),
476
+ });
477
+ export const BROWSE_CATALOG_TOOL_DEF = {
478
+ name: 'tacit_lake_browse_catalog',
479
+ description: 'Browse the data lake catalog with filtering and pagination. Route: GET /api/v1/org/lake/catalog.',
480
+ inputSchema: {
481
+ type: 'object',
482
+ properties: {
483
+ limit: { type: 'number', description: 'Max items to return' },
484
+ offset: { type: 'number', description: 'Pagination offset' },
485
+ origin: { type: 'string', description: 'Filter by origin' },
486
+ catalog_status: { type: 'string', description: 'Filter by catalog status' },
487
+ content_type: { type: 'string', description: 'Filter by content type' },
488
+ source_id: { type: 'string', description: 'Filter by source ID' },
489
+ q: { type: 'string', description: 'Search query' },
490
+ subject_id: { type: 'string', description: 'Filter by subject node ID' },
491
+ subject_needs_review: { type: 'boolean', description: 'Filter by review status' },
492
+ subject_layer: { type: 'string', description: 'Filter by subject layer' },
493
+ },
494
+ required: [],
495
+ },
496
+ };
497
+ export function buildBrowseCatalogRequest(client, input) {
498
+ return {
499
+ async execute() {
500
+ try {
501
+ const params = {};
502
+ if (input.limit !== undefined)
503
+ params['limit'] = input.limit;
504
+ if (input.offset !== undefined)
505
+ params['offset'] = input.offset;
506
+ if (input.origin !== undefined)
507
+ params['origin'] = input.origin;
508
+ if (input.catalog_status !== undefined)
509
+ params['catalog_status'] = input.catalog_status;
510
+ if (input.content_type !== undefined)
511
+ params['content_type'] = input.content_type;
512
+ if (input.source_id !== undefined)
513
+ params['source_id'] = input.source_id;
514
+ if (input.q !== undefined)
515
+ params['q'] = input.q;
516
+ if (input.subject_id !== undefined)
517
+ params['subject_id'] = input.subject_id;
518
+ if (input.subject_needs_review !== undefined)
519
+ params['subject_needs_review'] = input.subject_needs_review;
520
+ if (input.subject_layer !== undefined)
521
+ params['subject_layer'] = input.subject_layer;
522
+ const result = await client.get('/api/v1/org/lake/catalog', params);
523
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
524
+ }
525
+ catch (err) {
526
+ return apiErrorResult(err, 'tacit_lake_browse_catalog');
527
+ }
528
+ },
529
+ };
530
+ }
531
+ export async function handleBrowseCatalog(args) {
532
+ const parsed = browseCatalogInputSchema.safeParse(args);
533
+ if (!parsed.success) {
534
+ return { content: [{ type: 'text', text: `Invalid input: ${parsed.error.message}` }], isError: true };
535
+ }
536
+ return buildBrowseCatalogRequest(getClient(), parsed.data).execute();
537
+ }
538
+ // ─── tacit_lake_catalog_detail ───────────────────────────────────────────────
539
+ export const catalogDetailInputSchema = z.object({
540
+ catalog_id: z.string().uuid().describe('Catalog item UUID'),
541
+ });
542
+ export const CATALOG_DETAIL_TOOL_DEF = {
543
+ name: 'tacit_lake_catalog_detail',
544
+ description: 'Get full detail for a catalog item, including source name and linked proposals. Route: GET /api/v1/org/lake/catalog/{catalog_id}.',
545
+ inputSchema: {
546
+ type: 'object',
547
+ properties: {
548
+ catalog_id: { type: 'string', description: 'Catalog item UUID' },
549
+ },
550
+ required: ['catalog_id'],
551
+ },
552
+ };
553
+ export function buildCatalogDetailRequest(client, input) {
554
+ return {
555
+ async execute() {
556
+ try {
557
+ const result = await client.get(`/api/v1/org/lake/catalog/${input.catalog_id}`);
558
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
559
+ }
560
+ catch (err) {
561
+ return apiErrorResult(err, 'tacit_lake_catalog_detail');
562
+ }
563
+ },
564
+ };
565
+ }
566
+ export async function handleCatalogDetail(args) {
567
+ const parsed = catalogDetailInputSchema.safeParse(args);
568
+ if (!parsed.success) {
569
+ return { content: [{ type: 'text', text: `Invalid input: ${parsed.error.message}` }], isError: true };
570
+ }
571
+ return buildCatalogDetailRequest(getClient(), parsed.data).execute();
572
+ }
573
+ // ─── tacit_lake_delete_catalog_item ──────────────────────────────────────────
574
+ export const deleteCatalogItemInputSchema = z.object({
575
+ catalog_id: z.string().uuid().describe('Catalog item to delete'),
576
+ });
577
+ export const DELETE_CATALOG_ITEM_TOOL_DEF = {
578
+ name: 'tacit_lake_delete_catalog_item',
579
+ description: 'Soft-delete a catalog item (sets status to OPERATOR_DELETED). Reversible. Route: DELETE /api/v1/org/lake/catalog/{catalog_id}.',
580
+ inputSchema: {
581
+ type: 'object',
582
+ properties: {
583
+ catalog_id: { type: 'string', description: 'Catalog item to delete' },
584
+ },
585
+ required: ['catalog_id'],
586
+ },
587
+ };
588
+ export function buildDeleteCatalogItemRequest(client, input) {
589
+ return {
590
+ async execute() {
591
+ try {
592
+ const result = await client.delete(`/api/v1/org/lake/catalog/${input.catalog_id}`);
593
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
594
+ }
595
+ catch (err) {
596
+ return apiErrorResult(err, 'tacit_lake_delete_catalog_item');
597
+ }
598
+ },
599
+ };
600
+ }
601
+ export async function handleDeleteCatalogItem(args) {
602
+ const parsed = deleteCatalogItemInputSchema.safeParse(args);
603
+ if (!parsed.success) {
604
+ return { content: [{ type: 'text', text: `Invalid input: ${parsed.error.message}` }], isError: true };
605
+ }
606
+ return buildDeleteCatalogItemRequest(getClient(), parsed.data).execute();
607
+ }
608
+ // ─── tacit_lake_ingest ───────────────────────────────────────────────────────
609
+ export const ingestInputSchema = z.object({
610
+ source_uri: z.string().min(1).describe('URI identifying the document'),
611
+ content: z.string().min(1).describe('Document content'),
612
+ content_type: z.string().optional().describe('MIME type of the content'),
613
+ });
614
+ export const INGEST_TOOL_DEF = {
615
+ name: 'tacit_lake_ingest',
616
+ description: 'Ingest a single document into the data lake without a registered source. Creates a TACIT-origin catalog entry. Route: POST /api/v1/org/lake/ingest.',
617
+ inputSchema: {
618
+ type: 'object',
619
+ properties: {
620
+ source_uri: { type: 'string', description: 'URI identifying the document' },
621
+ content: { type: 'string', description: 'Document content' },
622
+ content_type: { type: 'string', description: 'MIME type of the content' },
623
+ },
624
+ required: ['source_uri', 'content'],
625
+ },
626
+ };
627
+ export function buildIngestRequest(client, input) {
628
+ return {
629
+ async execute() {
630
+ try {
631
+ const body = { source_uri: input.source_uri, content: input.content };
632
+ if (input.content_type !== undefined)
633
+ body['content_type'] = input.content_type;
634
+ const result = await client.post('/api/v1/org/lake/ingest', body);
635
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
636
+ }
637
+ catch (err) {
638
+ return apiErrorResult(err, 'tacit_lake_ingest');
639
+ }
640
+ },
641
+ };
642
+ }
643
+ export async function handleIngest(args) {
644
+ const parsed = ingestInputSchema.safeParse(args);
645
+ if (!parsed.success) {
646
+ return { content: [{ type: 'text', text: `Invalid input: ${parsed.error.message}` }], isError: true };
647
+ }
648
+ return buildIngestRequest(getClient(), parsed.data).execute();
649
+ }
650
+ // ─── tacit_lake_taxonomy_browse ──────────────────────────────────────────────
651
+ export const taxonomyBrowseInputSchema = z.object({
652
+ layer: z.string().optional().describe('Filter by layer: COMPANY, DOMAIN, DIMENSION'),
653
+ parent_id: z.string().uuid().optional().describe('Filter by parent node ID'),
654
+ });
655
+ export const TAXONOMY_BROWSE_TOOL_DEF = {
656
+ name: 'tacit_lake_taxonomy_browse',
657
+ description: 'Browse the lake classification taxonomy tree for the current workspace. Route: GET /api/v1/org/lake/taxonomy.',
658
+ inputSchema: {
659
+ type: 'object',
660
+ properties: {
661
+ layer: { type: 'string', description: 'Filter by layer: COMPANY, DOMAIN, DIMENSION' },
662
+ parent_id: { type: 'string', description: 'Filter by parent node ID' },
663
+ },
664
+ required: [],
665
+ },
666
+ };
667
+ export function buildTaxonomyBrowseRequest(client, input) {
668
+ return {
669
+ async execute() {
670
+ try {
671
+ const params = {};
672
+ if (input.layer !== undefined)
673
+ params['layer'] = input.layer;
674
+ if (input.parent_id !== undefined)
675
+ params['parent_id'] = input.parent_id;
676
+ const result = await client.get('/api/v1/org/lake/taxonomy', params);
677
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
678
+ }
679
+ catch (err) {
680
+ return apiErrorResult(err, 'tacit_lake_taxonomy_browse');
681
+ }
682
+ },
683
+ };
684
+ }
685
+ export async function handleTaxonomyBrowse(args) {
686
+ const parsed = taxonomyBrowseInputSchema.safeParse(args);
687
+ if (!parsed.success) {
688
+ return { content: [{ type: 'text', text: `Invalid input: ${parsed.error.message}` }], isError: true };
689
+ }
690
+ return buildTaxonomyBrowseRequest(getClient(), parsed.data).execute();
691
+ }
692
+ // ─── tacit_lake_taxonomy_seed ────────────────────────────────────────────────
693
+ export const taxonomySeedInputSchema = z.object({});
694
+ export const TAXONOMY_SEED_TOOL_DEF = {
695
+ name: 'tacit_lake_taxonomy_seed',
696
+ description: 'Seed the DOMAIN layer of the taxonomy from built-in domain schema definitions. Idempotent — safe to call multiple times. Route: POST /api/v1/org/lake/taxonomy/seed.',
697
+ inputSchema: {
698
+ type: 'object',
699
+ properties: {},
700
+ required: [],
701
+ },
702
+ };
703
+ export function buildTaxonomySeedRequest(client, _input) {
704
+ return {
705
+ async execute() {
706
+ try {
707
+ const result = await client.post('/api/v1/org/lake/taxonomy/seed', {});
708
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
709
+ }
710
+ catch (err) {
711
+ return apiErrorResult(err, 'tacit_lake_taxonomy_seed');
712
+ }
713
+ },
714
+ };
715
+ }
716
+ export async function handleTaxonomySeed(args) {
717
+ const parsed = taxonomySeedInputSchema.safeParse(args);
718
+ if (!parsed.success) {
719
+ return { content: [{ type: 'text', text: `Invalid input: ${parsed.error.message}` }], isError: true };
720
+ }
721
+ return buildTaxonomySeedRequest(getClient(), parsed.data).execute();
722
+ }
723
+ // ─── tacit_lake_taxonomy_upsert_node ─────────────────────────────────────────
724
+ export const taxonomyUpsertNodeInputSchema = z.object({
725
+ slug: z.string().min(1).describe('Unique slug for the node within its layer'),
726
+ name: z.string().min(1).describe('Display name'),
727
+ layer: z.enum(['COMPANY', 'DOMAIN', 'DIMENSION']).describe('Taxonomy layer'),
728
+ parent_id: z.string().uuid().optional().describe('Parent node ID'),
729
+ description: z.string().optional().describe('Node description'),
730
+ aliases: z.array(z.string()).optional().describe('Alternative names for matching'),
731
+ });
732
+ export const TAXONOMY_UPSERT_NODE_TOOL_DEF = {
733
+ name: 'tacit_lake_taxonomy_upsert_node',
734
+ description: 'Create or update a taxonomy classification node. Route: POST /api/v1/org/lake/taxonomy/nodes.',
735
+ inputSchema: {
736
+ type: 'object',
737
+ properties: {
738
+ slug: { type: 'string', description: 'Unique slug for the node within its layer' },
739
+ name: { type: 'string', description: 'Display name' },
740
+ layer: { type: 'string', enum: ['COMPANY', 'DOMAIN', 'DIMENSION'], description: 'Taxonomy layer' },
741
+ parent_id: { type: 'string', description: 'Parent node ID' },
742
+ description: { type: 'string', description: 'Node description' },
743
+ aliases: { type: 'array', items: { type: 'string' }, description: 'Alternative names for matching' },
744
+ },
745
+ required: ['slug', 'name', 'layer'],
746
+ },
747
+ };
748
+ export function buildTaxonomyUpsertNodeRequest(client, input) {
749
+ return {
750
+ async execute() {
751
+ try {
752
+ const body = { slug: input.slug, name: input.name, layer: input.layer };
753
+ if (input.parent_id !== undefined)
754
+ body['parent_id'] = input.parent_id;
755
+ if (input.description !== undefined)
756
+ body['description'] = input.description;
757
+ if (input.aliases !== undefined)
758
+ body['aliases'] = input.aliases;
759
+ const result = await client.post('/api/v1/org/lake/taxonomy/nodes', body);
760
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
761
+ }
762
+ catch (err) {
763
+ return apiErrorResult(err, 'tacit_lake_taxonomy_upsert_node');
764
+ }
765
+ },
766
+ };
767
+ }
768
+ export async function handleTaxonomyUpsertNode(args) {
769
+ const parsed = taxonomyUpsertNodeInputSchema.safeParse(args);
770
+ if (!parsed.success) {
771
+ return { content: [{ type: 'text', text: `Invalid input: ${parsed.error.message}` }], isError: true };
772
+ }
773
+ return buildTaxonomyUpsertNodeRequest(getClient(), parsed.data).execute();
774
+ }
775
+ // ─── tacit_lake_classify_subject ─────────────────────────────────────────────
776
+ export const classifySubjectInputSchema = z.object({
777
+ catalog_id: z.string().uuid().describe('Catalog item to classify'),
778
+ subject_id: z.string().uuid().describe('Target taxonomy node ID'),
779
+ });
780
+ export const CLASSIFY_SUBJECT_TOOL_DEF = {
781
+ name: 'tacit_lake_classify_subject',
782
+ description: 'Set the subject classification of a specific catalog item (operator OVERRIDE). Route: POST /api/v1/org/lake/catalog/{catalog_id}/subject.',
783
+ inputSchema: {
784
+ type: 'object',
785
+ properties: {
786
+ catalog_id: { type: 'string', description: 'Catalog item to classify' },
787
+ subject_id: { type: 'string', description: 'Target taxonomy node ID' },
788
+ },
789
+ required: ['catalog_id', 'subject_id'],
790
+ },
791
+ };
792
+ export function buildClassifySubjectRequest(client, input) {
793
+ return {
794
+ async execute() {
795
+ try {
796
+ const result = await client.post(`/api/v1/org/lake/catalog/${input.catalog_id}/subject`, {
797
+ subject_id: input.subject_id,
798
+ });
799
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
800
+ }
801
+ catch (err) {
802
+ return apiErrorResult(err, 'tacit_lake_classify_subject');
803
+ }
804
+ },
805
+ };
806
+ }
807
+ export async function handleClassifySubject(args) {
808
+ const parsed = classifySubjectInputSchema.safeParse(args);
809
+ if (!parsed.success) {
810
+ return { content: [{ type: 'text', text: `Invalid input: ${parsed.error.message}` }], isError: true };
811
+ }
812
+ return buildClassifySubjectRequest(getClient(), parsed.data).execute();
813
+ }
814
+ // ─── tacit_lake_reclassify_subjects ──────────────────────────────────────────
815
+ export const reclassifySubjectsInputSchema = z.object({
816
+ subject_id: z.string().uuid().describe('Target taxonomy node ID'),
817
+ catalog_ids: z.array(z.string().uuid()).min(1).describe('Catalog item IDs to reclassify'),
818
+ });
819
+ export const RECLASSIFY_SUBJECTS_TOOL_DEF = {
820
+ name: 'tacit_lake_reclassify_subjects',
821
+ description: 'Propose bulk reclassification of catalog items to a new subject. Creates a workspace proposal requiring human approval (T3). Route: POST /api/v1/org/lake/catalog/subject/bulk.',
822
+ inputSchema: {
823
+ type: 'object',
824
+ properties: {
825
+ subject_id: { type: 'string', description: 'Target taxonomy node ID' },
826
+ catalog_ids: { type: 'array', items: { type: 'string' }, description: 'Catalog item IDs to reclassify' },
827
+ },
828
+ required: ['subject_id', 'catalog_ids'],
829
+ },
830
+ };
831
+ export function buildReclassifySubjectsRequest(client, input) {
832
+ return {
833
+ async execute() {
834
+ try {
835
+ const result = await client.post('/api/v1/org/lake/catalog/subject/bulk', {
836
+ subject_id: input.subject_id,
837
+ catalog_ids: input.catalog_ids,
838
+ });
839
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
840
+ }
841
+ catch (err) {
842
+ return apiErrorResult(err, 'tacit_lake_reclassify_subjects');
843
+ }
844
+ },
845
+ };
846
+ }
847
+ export async function handleReclassifySubjects(args) {
848
+ const parsed = reclassifySubjectsInputSchema.safeParse(args);
849
+ if (!parsed.success) {
850
+ return { content: [{ type: 'text', text: `Invalid input: ${parsed.error.message}` }], isError: true };
851
+ }
852
+ return buildReclassifySubjectsRequest(getClient(), parsed.data).execute();
853
+ }
854
+ // ─── tacit_lake_resolve ───────────────────────────────────────────────────────
855
+ export const resolveInputSchema = z.object({
856
+ doc_id: z.string().optional().describe('Document identity UUID (highest priority)'),
857
+ sha256: z.string().optional().describe('Content SHA-256 hash'),
858
+ path: z.string().optional().describe('Source URI path (lowest priority)'),
859
+ });
860
+ export const RESOLVE_TOOL_DEF = {
861
+ name: 'tacit_lake_resolve',
862
+ description: 'Resolve a lake document by doc_id, sha256, or path (priority: doc_id > sha256 > path). Route: POST /api/v1/org/lake/resolve.',
863
+ inputSchema: {
864
+ type: 'object',
865
+ properties: {
866
+ doc_id: { type: 'string', description: 'Document identity UUID (highest priority)' },
867
+ sha256: { type: 'string', description: 'Content SHA-256 hash' },
868
+ path: { type: 'string', description: 'Source URI path (lowest priority)' },
869
+ },
870
+ required: [],
871
+ },
872
+ };
873
+ export function buildResolveRequest(client, input) {
874
+ return {
875
+ async execute() {
876
+ try {
877
+ const result = await client.post('/api/v1/org/lake/resolve', {
878
+ doc_id: input.doc_id,
879
+ sha256: input.sha256,
880
+ path: input.path,
881
+ });
882
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
883
+ }
884
+ catch (err) {
885
+ return apiErrorResult(err, 'tacit_lake_resolve');
886
+ }
887
+ },
888
+ };
889
+ }
890
+ export async function handleResolve(args) {
891
+ const parsed = resolveInputSchema.safeParse(args);
892
+ if (!parsed.success) {
893
+ return { content: [{ type: 'text', text: `Invalid input: ${parsed.error.message}` }], isError: true };
894
+ }
895
+ return buildResolveRequest(getClient(), parsed.data).execute();
896
+ }
897
+ // ─── tacit_lake_manifest ──────────────────────────────────────────────────────
898
+ export const manifestInputSchema = z.object({
899
+ source_id: z.string().min(1).describe('Source UUID to read manifest from'),
900
+ });
901
+ export const MANIFEST_TOOL_DEF = {
902
+ name: 'tacit_lake_manifest',
903
+ description: 'Read the parsed .tacit-lake.yaml manifest for a source. Route: GET /api/v1/org/lake/sources/:source_id/manifest.',
904
+ inputSchema: {
905
+ type: 'object',
906
+ properties: {
907
+ source_id: { type: 'string', description: 'Source UUID to read manifest from' },
908
+ },
909
+ required: ['source_id'],
910
+ },
911
+ };
912
+ export function buildManifestRequest(client, input) {
913
+ return {
914
+ async execute() {
915
+ try {
916
+ const result = await client.get(`/api/v1/org/lake/sources/${encodeURIComponent(input.source_id)}/manifest`);
917
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
918
+ }
919
+ catch (err) {
920
+ return apiErrorResult(err, 'tacit_lake_manifest');
921
+ }
922
+ },
923
+ };
924
+ }
925
+ export async function handleManifest(args) {
926
+ const parsed = manifestInputSchema.safeParse(args);
927
+ if (!parsed.success) {
928
+ return { content: [{ type: 'text', text: `Invalid input: ${parsed.error.message}` }], isError: true };
929
+ }
930
+ return buildManifestRequest(getClient(), parsed.data).execute();
931
+ }
932
+ export function registerLakeTools(server, getClientFn) {
933
+ server.tool('tacit_lake_register_source', REGISTER_SOURCE_TOOL_DEF.description, registerSourceInputSchema.shape, async (args) => {
934
+ const client = await getClientFn();
935
+ return buildRegisterSourceRequest(client, args).execute();
936
+ });
937
+ server.tool('tacit_lake_list_sources', LIST_SOURCES_TOOL_DEF.description, {}, async () => {
938
+ const client = await getClientFn();
939
+ return buildListSourcesRequest(client, {}).execute();
940
+ });
941
+ server.tool('tacit_lake_deregister_source', DEREGISTER_SOURCE_TOOL_DEF.description, deregisterSourceInputSchema.shape, async (args) => {
942
+ const client = await getClientFn();
943
+ return buildDeregisterSourceRequest(client, args).execute();
944
+ });
945
+ server.tool('tacit_lake_sync_status', SYNC_STATUS_TOOL_DEF.description, syncStatusInputSchema.shape, async (args) => {
946
+ const client = await getClientFn();
947
+ return buildSyncStatusRequest(client, args).execute();
948
+ });
949
+ server.tool('tacit_lake_trigger_sync', TRIGGER_SYNC_TOOL_DEF.description, triggerSyncInputSchema.shape, async (args) => {
950
+ const client = await getClientFn();
951
+ return buildTriggerSyncRequest(client, args).execute();
952
+ });
953
+ server.tool('tacit_lake_list_proposals', LIST_PROPOSALS_TOOL_DEF.description, {}, async () => {
954
+ const client = await getClientFn();
955
+ return buildListProposalsRequest(client, {}).execute();
956
+ });
957
+ server.tool('tacit_lake_confirm_proposal', CONFIRM_PROPOSAL_TOOL_DEF.description, confirmProposalInputSchema.shape, async (args) => {
958
+ const client = await getClientFn();
959
+ return buildConfirmProposalRequest(client, args).execute();
960
+ });
961
+ server.tool('tacit_lake_classify', CLASSIFY_TOOL_DEF.description, classifyInputSchema.shape, async (args) => {
962
+ const client = await getClientFn();
963
+ return buildClassifyRequest(client, args).execute();
964
+ });
965
+ server.tool('tacit_lake_reclassify', RECLASSIFY_TOOL_DEF.description, reclassifyInputSchema.shape, async (args) => {
966
+ const client = await getClientFn();
967
+ return buildReclassifyRequest(client, args).execute();
968
+ });
969
+ server.tool('tacit_lake_writeback', WRITEBACK_TOOL_DEF.description, writebackInputSchema.shape, async (args) => {
970
+ const client = await getClientFn();
971
+ return buildWritebackRequest(client, args).execute();
972
+ });
973
+ server.tool('tacit_lake_browse_catalog', BROWSE_CATALOG_TOOL_DEF.description, browseCatalogInputSchema.shape, async (args) => {
974
+ const client = await getClientFn();
975
+ return buildBrowseCatalogRequest(client, args).execute();
976
+ });
977
+ server.tool('tacit_lake_catalog_detail', CATALOG_DETAIL_TOOL_DEF.description, catalogDetailInputSchema.shape, async (args) => {
978
+ const client = await getClientFn();
979
+ return buildCatalogDetailRequest(client, args).execute();
980
+ });
981
+ server.tool('tacit_lake_delete_catalog_item', DELETE_CATALOG_ITEM_TOOL_DEF.description, deleteCatalogItemInputSchema.shape, async (args) => {
982
+ const client = await getClientFn();
983
+ return buildDeleteCatalogItemRequest(client, args).execute();
984
+ });
985
+ server.tool('tacit_lake_ingest', INGEST_TOOL_DEF.description, ingestInputSchema.shape, async (args) => {
986
+ const client = await getClientFn();
987
+ return buildIngestRequest(client, args).execute();
988
+ });
989
+ server.tool('tacit_lake_taxonomy_browse', TAXONOMY_BROWSE_TOOL_DEF.description, taxonomyBrowseInputSchema.shape, async (args) => {
990
+ const client = await getClientFn();
991
+ return buildTaxonomyBrowseRequest(client, args).execute();
992
+ });
993
+ server.tool('tacit_lake_taxonomy_seed', TAXONOMY_SEED_TOOL_DEF.description, {}, async () => {
994
+ const client = await getClientFn();
995
+ return buildTaxonomySeedRequest(client, {}).execute();
996
+ });
997
+ server.tool('tacit_lake_taxonomy_upsert_node', TAXONOMY_UPSERT_NODE_TOOL_DEF.description, taxonomyUpsertNodeInputSchema.shape, async (args) => {
998
+ const client = await getClientFn();
999
+ return buildTaxonomyUpsertNodeRequest(client, args).execute();
1000
+ });
1001
+ server.tool('tacit_lake_classify_subject', CLASSIFY_SUBJECT_TOOL_DEF.description, classifySubjectInputSchema.shape, async (args) => {
1002
+ const client = await getClientFn();
1003
+ return buildClassifySubjectRequest(client, args).execute();
1004
+ });
1005
+ server.tool('tacit_lake_reclassify_subjects', RECLASSIFY_SUBJECTS_TOOL_DEF.description, reclassifySubjectsInputSchema.shape, async (args) => {
1006
+ const client = await getClientFn();
1007
+ return buildReclassifySubjectsRequest(client, args).execute();
1008
+ });
1009
+ server.tool('tacit_lake_resolve', RESOLVE_TOOL_DEF.description, resolveInputSchema.shape, async (args) => {
1010
+ const client = await getClientFn();
1011
+ return buildResolveRequest(client, args).execute();
1012
+ });
1013
+ server.tool('tacit_lake_manifest', MANIFEST_TOOL_DEF.description, manifestInputSchema.shape, async (args) => {
1014
+ const client = await getClientFn();
1015
+ return buildManifestRequest(client, args).execute();
1016
+ });
1017
+ }