@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
@@ -1,9 +1,9 @@
1
- "use strict";
2
1
  // SPDX-License-Identifier: MIT
3
2
  /**
4
3
  * Ingest tools:
5
- * tacit_ingest_file — POST /api/v1/portfolios/:id/ingest
6
- * tacit_ingest_url — POST /api/v1/portfolios/:id/ingest-url
4
+ * tacit_ingest_file — POST /api/v1/portfolios/:id/ingest
5
+ * tacit_ingest_url — POST /api/v1/portfolios/:id/ingest-url
6
+ * tacit_ingest_url_general — POST /api/v1/portfolios/:id/ingest-url-general (FEAT-175)
7
7
  *
8
8
  * Both require portfolio_id input.
9
9
  *
@@ -16,50 +16,11 @@
16
16
  * The guard is synchronous and checks literal IPs/hostnames in the URL
17
17
  * (no DNS resolution required for the guard to function).
18
18
  */
19
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
20
- if (k2 === undefined) k2 = k;
21
- var desc = Object.getOwnPropertyDescriptor(m, k);
22
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
23
- desc = { enumerable: true, get: function() { return m[k]; } };
24
- }
25
- Object.defineProperty(o, k2, desc);
26
- }) : (function(o, m, k, k2) {
27
- if (k2 === undefined) k2 = k;
28
- o[k2] = m[k];
29
- }));
30
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
31
- Object.defineProperty(o, "default", { enumerable: true, value: v });
32
- }) : function(o, v) {
33
- o["default"] = v;
34
- });
35
- var __importStar = (this && this.__importStar) || (function () {
36
- var ownKeys = function(o) {
37
- ownKeys = Object.getOwnPropertyNames || function (o) {
38
- var ar = [];
39
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
40
- return ar;
41
- };
42
- return ownKeys(o);
43
- };
44
- return function (mod) {
45
- if (mod && mod.__esModule) return mod;
46
- var result = {};
47
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
48
- __setModuleDefault(result, mod);
49
- return result;
50
- };
51
- })();
52
- Object.defineProperty(exports, "__esModule", { value: true });
53
- exports.INGEST_URL_TOOL_DEF = exports.ingestUrlInputSchema = exports.INGEST_FILE_TOOL_DEF = exports.ingestFileInputSchema = void 0;
54
- exports.validateIngestUrl = validateIngestUrl;
55
- exports.buildIngestFileRequest = buildIngestFileRequest;
56
- exports.handleIngestFile = handleIngestFile;
57
- exports.buildIngestUrlRequest = buildIngestUrlRequest;
58
- exports.handleIngestUrl = handleIngestUrl;
59
- const zod_1 = require("zod");
60
- const fs = __importStar(require("fs"));
61
- const path = __importStar(require("path"));
62
- const client_js_1 = require("../client.js");
19
+ import { z } from 'zod';
20
+ import * as fs from 'fs';
21
+ import * as path from 'path';
22
+ import { getClient } from '../client.js';
23
+ import { apiErrorResult } from './errors.js';
63
24
  // ─── SSRF guard — synchronous IP/hostname check ───────────────────────────────
64
25
  /**
65
26
  * Parse an IPv4 string into octets, returning null if invalid.
@@ -121,7 +82,7 @@ function isPrivateHost(host) {
121
82
  * destination-IP filtering at request time, after resolution. Do not rely on
122
83
  * this function alone for SSRF protection.
123
84
  */
124
- function validateIngestUrl(rawUrl) {
85
+ export function validateIngestUrl(rawUrl) {
125
86
  let parsed;
126
87
  try {
127
88
  parsed = new URL(rawUrl);
@@ -141,12 +102,12 @@ function validateIngestUrl(rawUrl) {
141
102
  return { ok: true };
142
103
  }
143
104
  // ─── tacit_ingest_file ────────────────────────────────────────────────────────
144
- exports.ingestFileInputSchema = zod_1.z.object({
145
- portfolio_id: zod_1.z.string().min(1).describe('Portfolio UUID to ingest into'),
146
- path: zod_1.z.string().min(1).describe('Local file path to ingest'),
147
- title: zod_1.z.string().optional().describe('Optional title override'),
105
+ export const ingestFileInputSchema = z.object({
106
+ portfolio_id: z.string().min(1).describe('Portfolio UUID to ingest into'),
107
+ path: z.string().min(1).describe('Local file path to ingest'),
108
+ title: z.string().optional().describe('Optional title override'),
148
109
  });
149
- exports.INGEST_FILE_TOOL_DEF = {
110
+ export const INGEST_FILE_TOOL_DEF = {
150
111
  name: 'tacit_ingest_file',
151
112
  description: 'Ingest a local file into a Tacit portfolio. Route: POST /api/v1/portfolios/:id/ingest.',
152
113
  inputSchema: {
@@ -159,7 +120,7 @@ exports.INGEST_FILE_TOOL_DEF = {
159
120
  required: ['portfolio_id', 'path'],
160
121
  },
161
122
  };
162
- function buildIngestFileRequest(client, input) {
123
+ export function buildIngestFileRequest(client, input) {
163
124
  return {
164
125
  async execute() {
165
126
  const { portfolio_id, path: filePath, title } = input;
@@ -187,20 +148,76 @@ function buildIngestFileRequest(client, input) {
187
148
  },
188
149
  };
189
150
  }
190
- async function handleIngestFile(args) {
191
- const parsed = exports.ingestFileInputSchema.safeParse(args);
151
+ export async function handleIngestFile(args) {
152
+ const parsed = ingestFileInputSchema.safeParse(args);
153
+ if (!parsed.success) {
154
+ return { content: [{ type: 'text', text: `Invalid input: ${parsed.error.message}` }], isError: true };
155
+ }
156
+ return buildIngestFileRequest(getClient(), parsed.data).execute();
157
+ }
158
+ // ─── tacit_ingest_url_general ────────────────────────────────────────────────
159
+ export const ingestUrlGeneralInputSchema = z.object({
160
+ portfolio_id: z.string().min(1).describe('Portfolio UUID to ingest into'),
161
+ url: z.string().min(1).describe('Public HTTPS URL to ingest (PDF, HTML, text — any content type)'),
162
+ program_id: z.string().optional().describe('Optional program UUID within the portfolio'),
163
+ title: z.string().optional().describe('Optional title override'),
164
+ });
165
+ export const INGEST_URL_GENERAL_TOOL_DEF = {
166
+ name: 'tacit_ingest_url_general',
167
+ description: 'Ingest any public URL (PDF, HTML, text) into a Tacit portfolio. Not domain-restricted. ' +
168
+ 'Route: POST /api/v1/portfolios/:id/ingest-url-general. ' +
169
+ 'URL must use https:// scheme and must not resolve to private/loopback addresses (SSRF protection).',
170
+ inputSchema: {
171
+ type: 'object',
172
+ properties: {
173
+ portfolio_id: { type: 'string', description: 'Portfolio UUID' },
174
+ url: { type: 'string', description: 'Public HTTPS URL to ingest (PDF, HTML, text)' },
175
+ program_id: { type: 'string', description: 'Optional program UUID within the portfolio' },
176
+ title: { type: 'string', description: 'Optional title override' },
177
+ },
178
+ required: ['portfolio_id', 'url'],
179
+ },
180
+ };
181
+ export function buildIngestUrlGeneralRequest(client, input) {
182
+ return {
183
+ async execute() {
184
+ const { portfolio_id, url, program_id, title } = input;
185
+ const guard = validateIngestUrl(url);
186
+ if (!guard.ok) {
187
+ return {
188
+ content: [{ type: 'text', text: `SSRF guard rejected URL: ${guard.reason}` }],
189
+ isError: true,
190
+ };
191
+ }
192
+ try {
193
+ const body = { source_url: url };
194
+ if (program_id)
195
+ body['program_id'] = program_id;
196
+ if (title)
197
+ body['title'] = title;
198
+ const result = await client.post(`/api/v1/portfolios/${portfolio_id}/ingest-url-general`, body);
199
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
200
+ }
201
+ catch (err) {
202
+ return apiErrorResult(err, `/api/v1/portfolios/:id/ingest-url-general`);
203
+ }
204
+ },
205
+ };
206
+ }
207
+ export async function handleIngestUrlGeneral(args) {
208
+ const parsed = ingestUrlGeneralInputSchema.safeParse(args);
192
209
  if (!parsed.success) {
193
210
  return { content: [{ type: 'text', text: `Invalid input: ${parsed.error.message}` }], isError: true };
194
211
  }
195
- return buildIngestFileRequest((0, client_js_1.getClient)(), parsed.data).execute();
212
+ return buildIngestUrlGeneralRequest(getClient(), parsed.data).execute();
196
213
  }
197
214
  // ─── tacit_ingest_url ─────────────────────────────────────────────────────────
198
- exports.ingestUrlInputSchema = zod_1.z.object({
199
- portfolio_id: zod_1.z.string().min(1).describe('Portfolio UUID to ingest into'),
200
- url: zod_1.z.string().min(1).describe('Public HTTPS URL to ingest (must be https://, no private/loopback hosts)'),
201
- program_id: zod_1.z.string().min(1).describe('Program UUID within the portfolio'),
215
+ export const ingestUrlInputSchema = z.object({
216
+ portfolio_id: z.string().min(1).describe('Portfolio UUID to ingest into'),
217
+ url: z.string().min(1).describe('Public HTTPS URL to ingest (must be https://, no private/loopback hosts)'),
218
+ program_id: z.string().min(1).describe('Program UUID within the portfolio'),
202
219
  });
203
- exports.INGEST_URL_TOOL_DEF = {
220
+ export const INGEST_URL_TOOL_DEF = {
204
221
  name: 'tacit_ingest_url',
205
222
  description: 'Ingest a public URL into a Tacit portfolio. Route: POST /api/v1/portfolios/:id/ingest-url. ' +
206
223
  'URL must use https:// scheme and must not resolve to private/loopback addresses (SSRF protection).',
@@ -214,7 +231,7 @@ exports.INGEST_URL_TOOL_DEF = {
214
231
  required: ['portfolio_id', 'url', 'program_id'],
215
232
  },
216
233
  };
217
- function buildIngestUrlRequest(client, input) {
234
+ export function buildIngestUrlRequest(client, input) {
218
235
  return {
219
236
  async execute() {
220
237
  const { portfolio_id, url, program_id } = input;
@@ -239,21 +256,37 @@ function buildIngestUrlRequest(client, input) {
239
256
  },
240
257
  };
241
258
  }
242
- async function handleIngestUrl(args) {
243
- const parsed = exports.ingestUrlInputSchema.safeParse(args);
259
+ export async function handleIngestUrl(args) {
260
+ const parsed = ingestUrlInputSchema.safeParse(args);
244
261
  if (!parsed.success) {
245
262
  return { content: [{ type: 'text', text: `Invalid input: ${parsed.error.message}` }], isError: true };
246
263
  }
247
- return buildIngestUrlRequest((0, client_js_1.getClient)(), parsed.data).execute();
264
+ return buildIngestUrlRequest(getClient(), parsed.data).execute();
248
265
  }
249
- // ─── Shared error helper ──────────────────────────────────────────────────────
250
- function apiErrorResult(err, endpoint) {
251
- if (err instanceof client_js_1.TacitApiError) {
252
- return {
253
- content: [{ type: 'text', text: `API error ${err.statusCode} on ${endpoint}: ${err.body}` }],
254
- isError: true,
255
- };
256
- }
257
- const msg = err instanceof Error ? err.message : String(err);
258
- return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
266
+ export function registerIngestTools(server, getClientFn) {
267
+ server.tool('tacit_ingest_file', 'Ingest a local file into a Tacit portfolio. Route: POST /api/v1/portfolios/:id/ingest.', {
268
+ portfolio_id: z.string().min(1).describe('Portfolio UUID to ingest into'),
269
+ path: z.string().min(1).describe('Local file path to ingest'),
270
+ title: z.string().optional().describe('Optional title override'),
271
+ }, async (args) => {
272
+ const client = await getClientFn();
273
+ return buildIngestFileRequest(client, args).execute();
274
+ });
275
+ server.tool('tacit_ingest_url', 'Ingest a public URL into a Tacit portfolio (SSRF-guarded). Route: POST /api/v1/portfolios/:id/ingest-url.', {
276
+ portfolio_id: z.string().min(1).describe('Portfolio UUID to ingest into'),
277
+ url: z.string().min(1).describe('Public HTTPS URL to ingest'),
278
+ program_id: z.string().min(1).describe('Program UUID within the portfolio'),
279
+ }, async (args) => {
280
+ const client = await getClientFn();
281
+ return buildIngestUrlRequest(client, args).execute();
282
+ });
283
+ server.tool('tacit_ingest_url_general', 'Ingest any public URL (PDF, HTML, text) into a Tacit portfolio — not domain-restricted. Route: POST /api/v1/portfolios/:id/ingest-url-general.', {
284
+ portfolio_id: z.string().min(1).describe('Portfolio UUID to ingest into'),
285
+ url: z.string().min(1).describe('Public HTTPS URL to ingest (PDF, HTML, text)'),
286
+ program_id: z.string().optional().describe('Optional program UUID within the portfolio'),
287
+ title: z.string().optional().describe('Optional title override'),
288
+ }, async (args) => {
289
+ const client = await getClientFn();
290
+ return buildIngestUrlGeneralRequest(client, args).execute();
291
+ });
259
292
  }