@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.
- package/dist/auth.d.ts +32 -0
- package/dist/auth.js +64 -0
- package/dist/client.d.ts +60 -5
- package/dist/client.js +234 -53
- package/dist/index.js +130 -106
- package/dist/oauth.d.ts +115 -0
- package/dist/oauth.js +619 -0
- package/dist/prompts.d.ts +2 -0
- package/dist/prompts.js +12 -0
- package/dist/setup.d.ts +28 -5
- package/dist/setup.js +266 -59
- package/dist/tools/agents.d.ts +277 -0
- package/dist/tools/agents.js +335 -0
- package/dist/tools/annotations.d.ts +117 -0
- package/dist/tools/annotations.js +130 -0
- package/dist/tools/artifacts.d.ts +178 -8
- package/dist/tools/artifacts.js +372 -81
- package/dist/tools/chronicle.d.ts +3 -0
- package/dist/tools/chronicle.js +165 -0
- package/dist/tools/connector_write_back.d.ts +3 -0
- package/dist/tools/connector_write_back.js +27 -0
- package/dist/tools/converse.d.ts +10 -0
- package/dist/tools/converse.js +88 -0
- package/dist/tools/crews.d.ts +3 -0
- package/dist/tools/crews.js +115 -0
- package/dist/tools/drafts.d.ts +83 -0
- package/dist/tools/drafts.js +86 -0
- package/dist/tools/errors.d.ts +15 -0
- package/dist/tools/errors.js +21 -0
- package/dist/tools/export.d.ts +54 -0
- package/dist/tools/export.js +55 -0
- package/dist/tools/gm.d.ts +214 -0
- package/dist/tools/gm.js +198 -0
- package/dist/tools/ingest.d.ts +58 -4
- package/dist/tools/ingest.js +109 -76
- package/dist/tools/kb.d.ts +544 -0
- package/dist/tools/kb.js +687 -0
- package/dist/tools/lake-structure.d.ts +3 -0
- package/dist/tools/lake-structure.js +126 -0
- package/dist/tools/lake.d.ts +932 -0
- package/dist/tools/lake.js +1017 -0
- package/dist/tools/move.d.ts +200 -0
- package/dist/tools/move.js +96 -0
- package/dist/tools/outbox.d.ts +274 -0
- package/dist/tools/outbox.js +223 -0
- package/dist/tools/people.d.ts +3 -0
- package/dist/tools/people.js +59 -0
- package/dist/tools/pyramid.d.ts +554 -0
- package/dist/tools/pyramid.js +758 -0
- package/dist/tools/recall.d.ts +2 -0
- package/dist/tools/recall.js +28 -17
- package/dist/tools/registry.d.ts +17 -0
- package/dist/tools/registry.js +199 -0
- package/dist/tools/research.d.ts +47 -0
- package/dist/tools/research.js +575 -0
- package/dist/tools/search.d.ts +9 -0
- package/dist/tools/search.js +86 -25
- package/dist/tools/sharing.d.ts +63 -0
- package/dist/tools/sharing.js +157 -0
- package/dist/tools/skills.d.ts +9 -0
- package/dist/tools/skills.js +98 -0
- package/dist/tools/synthesize.d.ts +54 -2
- package/dist/tools/synthesize.js +80 -23
- package/dist/tools/web-url.d.ts +57 -0
- package/dist/tools/web-url.js +74 -0
- package/dist/tools/workspaces.d.ts +3 -0
- package/dist/tools/workspaces.js +47 -0
- package/dist/transport.d.ts +9 -0
- package/dist/transport.js +209 -0
- package/package.json +5 -4
package/dist/tools/ingest.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
// SPDX-License-Identifier: MIT
|
|
3
2
|
/**
|
|
4
3
|
* Ingest tools:
|
|
5
|
-
* tacit_ingest_file
|
|
6
|
-
* tacit_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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
145
|
-
portfolio_id:
|
|
146
|
-
path:
|
|
147
|
-
title:
|
|
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
|
-
|
|
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 =
|
|
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
|
|
212
|
+
return buildIngestUrlGeneralRequest(getClient(), parsed.data).execute();
|
|
196
213
|
}
|
|
197
214
|
// ─── tacit_ingest_url ─────────────────────────────────────────────────────────
|
|
198
|
-
|
|
199
|
-
portfolio_id:
|
|
200
|
-
url:
|
|
201
|
-
program_id:
|
|
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
|
-
|
|
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 =
|
|
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(
|
|
264
|
+
return buildIngestUrlRequest(getClient(), parsed.data).execute();
|
|
248
265
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
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
|
}
|