@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/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
2
|
// SPDX-License-Identifier: MIT
|
|
4
3
|
/**
|
|
5
4
|
* @tacit/mcp-server — stdio MCP server
|
|
@@ -22,54 +21,49 @@
|
|
|
22
21
|
* `tacit-mcp-server setup` is reserved for MV-1057h setup wizard.
|
|
23
22
|
* Currently prints a placeholder message and exits 0.
|
|
24
23
|
*/
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
//
|
|
66
|
-
const
|
|
67
|
-
const
|
|
68
|
-
const recall_js_1 = require("./tools/recall.js");
|
|
69
|
-
const artifacts_js_1 = require("./tools/artifacts.js");
|
|
70
|
-
const ingest_js_1 = require("./tools/ingest.js");
|
|
71
|
-
// Setup wizard (MV-1057h)
|
|
72
|
-
const setup_js_1 = require("./setup.js");
|
|
24
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
25
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
26
|
+
import * as semver from 'semver';
|
|
27
|
+
import * as path from 'path';
|
|
28
|
+
import * as fs from 'fs';
|
|
29
|
+
import * as os from 'os';
|
|
30
|
+
import { fileURLToPath } from 'url';
|
|
31
|
+
import { TacitClient, getClient as getModuleClient } from './client.js';
|
|
32
|
+
import { startHttpTransport } from './transport.js';
|
|
33
|
+
// Tool registration modules
|
|
34
|
+
import { registerSearchTools } from './tools/search.js';
|
|
35
|
+
import { registerSynthesizeTools } from './tools/synthesize.js';
|
|
36
|
+
import { registerConverseTools } from './tools/converse.js';
|
|
37
|
+
import { registerConnectorWriteBackTools } from './tools/connector_write_back.js';
|
|
38
|
+
import { registerRecallTools } from './tools/recall.js';
|
|
39
|
+
import { registerArtifactTools } from './tools/artifacts.js';
|
|
40
|
+
import { registerDraftTools } from './tools/drafts.js';
|
|
41
|
+
import { registerIngestTools } from './tools/ingest.js';
|
|
42
|
+
import { registerOutboxTools } from './tools/outbox.js';
|
|
43
|
+
import { registerAnnotationTools } from './tools/annotations.js';
|
|
44
|
+
import { registerExportTools } from './tools/export.js';
|
|
45
|
+
import { registerMoveTools } from './tools/move.js';
|
|
46
|
+
import { registerAgentTools } from './tools/agents.js';
|
|
47
|
+
import { registerPyramidTools } from './tools/pyramid.js';
|
|
48
|
+
import { registerSharingTools } from './tools/sharing.js';
|
|
49
|
+
import { registerKbTools } from './tools/kb.js';
|
|
50
|
+
import { registerLakeTools } from './tools/lake.js';
|
|
51
|
+
import { registerWebUrlTools } from './tools/web-url.js';
|
|
52
|
+
import { registerWorkspaceTools } from './tools/workspaces.js';
|
|
53
|
+
import { registerChronicleTools } from './tools/chronicle.js';
|
|
54
|
+
import { registerCrewTools } from './tools/crews.js';
|
|
55
|
+
import { registerPeopleTools } from './tools/people.js';
|
|
56
|
+
import { registerLakeStructureTools } from './tools/lake-structure.js';
|
|
57
|
+
import { registerResearchTools } from './tools/research.js';
|
|
58
|
+
import { registerGmTools } from './tools/gm.js';
|
|
59
|
+
import { registerSkillTools } from './tools/skills.js';
|
|
60
|
+
import { registerPrompts } from './prompts.js';
|
|
61
|
+
import { getRequestPrincipal } from './client.js';
|
|
62
|
+
// Setup wizard (MV-1057h / W5)
|
|
63
|
+
import { setup, profileToEnvVar } from './setup.js';
|
|
64
|
+
// ─── ESM __dirname replacement ───────────────────────────────────────────────
|
|
65
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
66
|
+
const __dirname = path.dirname(__filename);
|
|
73
67
|
// ─── Compatibility guard ──────────────────────────────────────────────────────
|
|
74
68
|
function checkCompatibility() {
|
|
75
69
|
const pkgPath = path.join(__dirname, '..', 'package.json');
|
|
@@ -78,13 +72,11 @@ function checkCompatibility() {
|
|
|
78
72
|
pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
79
73
|
}
|
|
80
74
|
catch {
|
|
81
|
-
// Non-fatal if package.json cannot be read at runtime.
|
|
82
75
|
return;
|
|
83
76
|
}
|
|
84
77
|
const compat = pkg['compatibility'];
|
|
85
78
|
const coreArtifactRange = compat?.['coreArtifact'];
|
|
86
79
|
if (typeof coreArtifactRange === 'string') {
|
|
87
|
-
// Print range for oracle D4 grep.
|
|
88
80
|
process.stderr.write(`COMPAT_RANGE: ${coreArtifactRange}\n`);
|
|
89
81
|
const coreVersion = process.env['TACIT_CORE_VERSION'];
|
|
90
82
|
if (coreVersion) {
|
|
@@ -97,69 +89,101 @@ function checkCompatibility() {
|
|
|
97
89
|
}
|
|
98
90
|
}
|
|
99
91
|
}
|
|
100
|
-
// ───
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
return (0, ingest_js_1.handleIngestUrl)(args);
|
|
134
|
-
default:
|
|
135
|
-
return {
|
|
136
|
-
content: [{ type: 'text', text: `Unknown tool: ${name}` }],
|
|
137
|
-
isError: true,
|
|
138
|
-
};
|
|
92
|
+
// ─── Profile helpers ──────────────────────────────────────────────────────────
|
|
93
|
+
function parseProfile(argv) {
|
|
94
|
+
for (let i = 0; i < argv.length; i++) {
|
|
95
|
+
if (argv[i] === '--profile' && argv[i + 1] && !argv[i + 1].startsWith('--')) {
|
|
96
|
+
return argv[i + 1];
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return 'tacit';
|
|
100
|
+
}
|
|
101
|
+
function checkProfileExpiry(profile) {
|
|
102
|
+
const metaPath = path.join(os.homedir(), '.tacit', 'profiles', `${profile}.json`);
|
|
103
|
+
if (!fs.existsSync(metaPath)) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
let meta;
|
|
107
|
+
try {
|
|
108
|
+
meta = JSON.parse(fs.readFileSync(metaPath, 'utf-8'));
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const expiresAt = typeof meta['expires_at'] === 'string' ? meta['expires_at'] : null;
|
|
114
|
+
if (!expiresAt)
|
|
115
|
+
return;
|
|
116
|
+
const expiresMs = Date.parse(expiresAt);
|
|
117
|
+
if (Number.isNaN(expiresMs))
|
|
118
|
+
return;
|
|
119
|
+
const nowMs = Date.now();
|
|
120
|
+
const diffDays = Math.floor((expiresMs - nowMs) / (1000 * 60 * 60 * 24));
|
|
121
|
+
if (diffDays < 14) {
|
|
122
|
+
const apiUrl = typeof meta['api_url'] === 'string' ? meta['api_url'] : 'https://beta.tacitai.app';
|
|
123
|
+
process.stderr.write(`[TACIT] Developer token expires in ${diffDays} day${diffDays === 1 ? '' : 's'}. ` +
|
|
124
|
+
`Run: npx @tacitai/mcp-server setup --api-url ${apiUrl}\n`);
|
|
139
125
|
}
|
|
140
126
|
}
|
|
141
127
|
// ─── Main ─────────────────────────────────────────────────────────────────────
|
|
142
128
|
async function run() {
|
|
143
|
-
// Handle setup subcommand before starting stdio transport (MV-1057h).
|
|
144
129
|
if (process.argv[2] === 'setup') {
|
|
145
|
-
await
|
|
130
|
+
await setup(process.argv.slice(3));
|
|
146
131
|
return;
|
|
147
132
|
}
|
|
148
|
-
|
|
133
|
+
const profile = parseProfile(process.argv.slice(2));
|
|
134
|
+
const envVarName = profileToEnvVar(profile);
|
|
135
|
+
if (envVarName !== 'TACIT_TOKEN' && process.env[envVarName] && !process.env['TACIT_TOKEN']) {
|
|
136
|
+
process.env['TACIT_TOKEN'] = process.env[envVarName];
|
|
137
|
+
}
|
|
138
|
+
checkProfileExpiry(profile);
|
|
149
139
|
checkCompatibility();
|
|
150
|
-
const server = new
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
140
|
+
const server = new McpServer({ name: '@tacitai/mcp-server', version: '0.3.0' }, { capabilities: { tools: {}, prompts: {} } });
|
|
141
|
+
const isHttpMode = process.env['MCP_TRANSPORT'] === 'http';
|
|
142
|
+
let clientInstance = null;
|
|
143
|
+
const getClient = async () => {
|
|
144
|
+
if (isHttpMode) {
|
|
145
|
+
// Per-request client via AsyncLocalStorage (caller's token)
|
|
146
|
+
return getModuleClient();
|
|
147
|
+
}
|
|
148
|
+
if (!clientInstance) {
|
|
149
|
+
clientInstance = new TacitClient();
|
|
150
|
+
await clientInstance.initialize();
|
|
151
|
+
}
|
|
152
|
+
return clientInstance;
|
|
153
|
+
};
|
|
154
|
+
// Register all tool modules
|
|
155
|
+
registerSearchTools(server, getClient);
|
|
156
|
+
registerSynthesizeTools(server, getClient);
|
|
157
|
+
registerConverseTools(server, getClient);
|
|
158
|
+
registerConnectorWriteBackTools(server, getClient);
|
|
159
|
+
registerRecallTools(server, getClient);
|
|
160
|
+
registerArtifactTools(server, getClient);
|
|
161
|
+
registerDraftTools(server, getClient);
|
|
162
|
+
registerIngestTools(server, getClient);
|
|
163
|
+
registerOutboxTools(server);
|
|
164
|
+
registerAnnotationTools(server, getClient);
|
|
165
|
+
registerExportTools(server, getClient);
|
|
166
|
+
registerMoveTools(server, getClient);
|
|
167
|
+
registerAgentTools(server, getClient);
|
|
168
|
+
registerPyramidTools(server, getClient);
|
|
169
|
+
registerSharingTools(server, getClient);
|
|
170
|
+
registerKbTools(server, getClient);
|
|
171
|
+
registerLakeTools(server, getClient);
|
|
172
|
+
registerWebUrlTools(server);
|
|
173
|
+
registerWorkspaceTools(server, getClient);
|
|
174
|
+
registerChronicleTools(server, getClient);
|
|
175
|
+
registerCrewTools(server, getClient);
|
|
176
|
+
registerPeopleTools(server, getClient);
|
|
177
|
+
registerLakeStructureTools(server, getClient);
|
|
178
|
+
registerGmTools(server, getClient);
|
|
179
|
+
registerResearchTools(server, getClient, getRequestPrincipal);
|
|
180
|
+
registerSkillTools(server, getClient);
|
|
181
|
+
registerPrompts(server);
|
|
182
|
+
if (process.env['MCP_TRANSPORT'] === 'http') {
|
|
183
|
+
await startHttpTransport(server);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
const transport = new StdioServerTransport();
|
|
163
187
|
await server.connect(transport);
|
|
164
188
|
}
|
|
165
189
|
run().catch((err) => {
|
package/dist/oauth.d.ts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth 2.0 Authorization Server for MCP (FEAT-176).
|
|
3
|
+
*
|
|
4
|
+
* Authorization code flow with PKCE S256. In-memory stores for auth codes
|
|
5
|
+
* and access tokens — process restart voids all grants.
|
|
6
|
+
*
|
|
7
|
+
* Security invariants:
|
|
8
|
+
* - PINs, auth codes, and token values are NEVER logged.
|
|
9
|
+
* - OAuth path NEVER falls back to process.env.TACIT_TOKEN.
|
|
10
|
+
* - Unknown client_id → 400 (never redirect to unregistered URI).
|
|
11
|
+
* - code_challenge_method must be S256 (plain rejected).
|
|
12
|
+
*/
|
|
13
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
14
|
+
export interface OAuthClient {
|
|
15
|
+
client_id: string;
|
|
16
|
+
client_secret?: string;
|
|
17
|
+
redirect_uris: string[];
|
|
18
|
+
client_name: string;
|
|
19
|
+
}
|
|
20
|
+
export interface OAuthTokenInfo {
|
|
21
|
+
user_email: string;
|
|
22
|
+
workspace_id: string;
|
|
23
|
+
tacit_token: string;
|
|
24
|
+
client_id: string;
|
|
25
|
+
}
|
|
26
|
+
interface AuthCodeEntry {
|
|
27
|
+
client_id: string;
|
|
28
|
+
redirect_uri: string;
|
|
29
|
+
code_challenge: string;
|
|
30
|
+
user_email: string;
|
|
31
|
+
workspace_id: string;
|
|
32
|
+
tacit_token: string;
|
|
33
|
+
state: string;
|
|
34
|
+
created_at: number;
|
|
35
|
+
}
|
|
36
|
+
interface CsrfEntry {
|
|
37
|
+
created_at: number;
|
|
38
|
+
client_id: string;
|
|
39
|
+
redirect_uri: string;
|
|
40
|
+
code_challenge: string;
|
|
41
|
+
code_challenge_method: string;
|
|
42
|
+
state: string;
|
|
43
|
+
scope: string;
|
|
44
|
+
}
|
|
45
|
+
export declare function getTokenTtlSeconds(): number;
|
|
46
|
+
export declare function isOAuthEnabled(): boolean;
|
|
47
|
+
export declare function getRegisteredClients(): OAuthClient[];
|
|
48
|
+
export declare function resetClientRegistry(): void;
|
|
49
|
+
export declare function findClient(client_id: string): OAuthClient | undefined;
|
|
50
|
+
export declare function validateRedirectUri(client: OAuthClient, redirect_uri: string): boolean;
|
|
51
|
+
export declare function registerDynamicClient(params: {
|
|
52
|
+
redirect_uris: string[];
|
|
53
|
+
client_name?: string;
|
|
54
|
+
token_endpoint_auth_method?: string;
|
|
55
|
+
}): {
|
|
56
|
+
client_id: string;
|
|
57
|
+
client_secret: string;
|
|
58
|
+
client_id_issued_at: number;
|
|
59
|
+
redirect_uris: string[];
|
|
60
|
+
client_name: string;
|
|
61
|
+
token_endpoint_auth_method: string;
|
|
62
|
+
};
|
|
63
|
+
export declare function issueAuthCode(params: {
|
|
64
|
+
client_id: string;
|
|
65
|
+
redirect_uri: string;
|
|
66
|
+
code_challenge: string;
|
|
67
|
+
user_email: string;
|
|
68
|
+
workspace_id: string;
|
|
69
|
+
tacit_token: string;
|
|
70
|
+
state: string;
|
|
71
|
+
}): string;
|
|
72
|
+
export declare function consumeAuthCode(code: string): AuthCodeEntry | null;
|
|
73
|
+
export declare function issueAccessToken(params: {
|
|
74
|
+
client_id: string;
|
|
75
|
+
user_email: string;
|
|
76
|
+
workspace_id: string;
|
|
77
|
+
tacit_token: string;
|
|
78
|
+
}): {
|
|
79
|
+
access_token: string;
|
|
80
|
+
expires_in: number;
|
|
81
|
+
};
|
|
82
|
+
export declare function validateOAuthToken(token: string): OAuthTokenInfo | null;
|
|
83
|
+
export declare function verifyPkce(code_verifier: string, code_challenge: string): boolean;
|
|
84
|
+
export declare function generateCsrfToken(params: {
|
|
85
|
+
client_id: string;
|
|
86
|
+
redirect_uri: string;
|
|
87
|
+
code_challenge: string;
|
|
88
|
+
code_challenge_method: string;
|
|
89
|
+
state: string;
|
|
90
|
+
scope: string;
|
|
91
|
+
}): string;
|
|
92
|
+
export declare function consumeCsrfToken(token: string): CsrfEntry | null;
|
|
93
|
+
export declare function checkLoginRateLimit(email: string): boolean;
|
|
94
|
+
export declare function getAuthorizationServerMetadata(issuer: string): Record<string, unknown>;
|
|
95
|
+
export declare function getProtectedResourceMetadata(resource: string, issuer: string): Record<string, unknown>;
|
|
96
|
+
export declare function renderLoginPage(params: {
|
|
97
|
+
client_name: string;
|
|
98
|
+
csrf_token: string;
|
|
99
|
+
error?: string;
|
|
100
|
+
}): string;
|
|
101
|
+
export declare function handleAuthorizeGet(req: IncomingMessage, res: ServerResponse): Promise<void>;
|
|
102
|
+
export declare function handleAuthorizePost(req: IncomingMessage, res: ServerResponse, apiUrl: string): Promise<void>;
|
|
103
|
+
export declare function handleTokenExchange(req: IncomingMessage, res: ServerResponse): Promise<void>;
|
|
104
|
+
export declare function handleClientRegistration(req: IncomingMessage, res: ServerResponse): Promise<void>;
|
|
105
|
+
export declare function handleDiscovery(res: ServerResponse, issuer: string): void;
|
|
106
|
+
export declare function handleProtectedResource(res: ServerResponse, resource: string, issuer: string): void;
|
|
107
|
+
export declare function startCleanupInterval(): void;
|
|
108
|
+
export declare function stopCleanupInterval(): void;
|
|
109
|
+
export declare function _testClearStores(): void;
|
|
110
|
+
export declare function _testGetStoreSize(): {
|
|
111
|
+
codes: number;
|
|
112
|
+
tokens: number;
|
|
113
|
+
csrf: number;
|
|
114
|
+
};
|
|
115
|
+
export {};
|