@astramindapp/mcp-server 0.20.1 → 0.22.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/README.md +35 -6
- package/dist/mind-client.d.ts +6 -0
- package/dist/mind-client.d.ts.map +1 -1
- package/dist/mind-client.js +4 -0
- package/dist/mind-client.js.map +1 -1
- package/dist/oauth-connect.d.ts +36 -0
- package/dist/oauth-connect.d.ts.map +1 -0
- package/dist/oauth-connect.js +291 -0
- package/dist/oauth-connect.js.map +1 -0
- package/dist/server.d.ts +1 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +24 -4
- package/dist/server.js.map +1 -1
- package/dist/setup.d.ts +5 -2
- package/dist/setup.d.ts.map +1 -1
- package/dist/setup.js +54 -15
- package/dist/setup.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* MIND MCP Setup — browser OAuth connect.
|
|
4
|
+
*
|
|
5
|
+
* Implements the loopback OAuth 2.1 Authorization Code + PKCE flow against
|
|
6
|
+
* the MIND backend (backend/routes/mcp_oauth_routes.py):
|
|
7
|
+
*
|
|
8
|
+
* 1. Start a local HTTP server on 127.0.0.1 (OS-assigned port), path /callback.
|
|
9
|
+
* 2. Dynamically register a public client (RFC 7591) at {base}/oauth/mcp/register.
|
|
10
|
+
* 3. Open {base}/oauth/mcp/authorize in the default browser — the user clicks
|
|
11
|
+
* "Connect" on the m-i-n-d.ai consent page.
|
|
12
|
+
* 4. The browser is redirected back to the loopback server with ?code=...&state=...
|
|
13
|
+
* 5. Exchange the code at {base}/oauth/mcp/token (PKCE verified) and receive a
|
|
14
|
+
* standard `mind_` API key as the access token.
|
|
15
|
+
*
|
|
16
|
+
* No dependencies beyond Node built-ins (http, crypto, child_process) and the
|
|
17
|
+
* global fetch available in Node 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.connectViaBrowser = connectViaBrowser;
|
|
54
|
+
const http = __importStar(require("http"));
|
|
55
|
+
const crypto = __importStar(require("crypto"));
|
|
56
|
+
const child_process_1 = require("child_process");
|
|
57
|
+
const DEFAULT_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
|
|
58
|
+
const CALLBACK_PATH = "/callback";
|
|
59
|
+
const DEFAULT_CLIENT_NAME = "MIND Setup CLI";
|
|
60
|
+
function base64url(buf) {
|
|
61
|
+
return buf.toString("base64url");
|
|
62
|
+
}
|
|
63
|
+
/** RFC 7636 §4.1 — 43–128 char base64url verifier. 64 random bytes → 86 chars. */
|
|
64
|
+
function generatePkcePair() {
|
|
65
|
+
const verifier = base64url(crypto.randomBytes(64));
|
|
66
|
+
const challenge = base64url(crypto.createHash("sha256").update(verifier, "ascii").digest());
|
|
67
|
+
return { verifier, challenge };
|
|
68
|
+
}
|
|
69
|
+
function openInBrowser(url) {
|
|
70
|
+
try {
|
|
71
|
+
let child;
|
|
72
|
+
if (process.platform === "darwin") {
|
|
73
|
+
child = (0, child_process_1.spawn)("open", [url], { detached: true, stdio: "ignore" });
|
|
74
|
+
}
|
|
75
|
+
else if (process.platform === "win32") {
|
|
76
|
+
// `start` is a cmd built-in; empty "" is the window title slot.
|
|
77
|
+
child = (0, child_process_1.spawn)("cmd", ["/c", "start", "", url.replace(/&/g, "^&")], {
|
|
78
|
+
detached: true,
|
|
79
|
+
stdio: "ignore",
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
child = (0, child_process_1.spawn)("xdg-open", [url], { detached: true, stdio: "ignore" });
|
|
84
|
+
}
|
|
85
|
+
child.on("error", () => {
|
|
86
|
+
/* swallow — the URL is printed as a fallback either way */
|
|
87
|
+
});
|
|
88
|
+
child.unref();
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function htmlPage(title, heading, body, ok) {
|
|
96
|
+
const accent = ok ? "#10b981" : "#ef4444";
|
|
97
|
+
return `<!DOCTYPE html>
|
|
98
|
+
<html lang="en">
|
|
99
|
+
<head>
|
|
100
|
+
<meta charset="utf-8">
|
|
101
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
102
|
+
<title>${title}</title>
|
|
103
|
+
<style>
|
|
104
|
+
body { margin: 0; min-height: 100vh; display: flex; align-items: center; justify-content: center;
|
|
105
|
+
background: #0b0f19; color: #e5e7eb; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
|
|
106
|
+
.card { text-align: center; padding: 48px 56px; border-radius: 16px; background: #111827;
|
|
107
|
+
border: 1px solid #1f2937; box-shadow: 0 20px 60px rgba(0,0,0,.5); max-width: 440px; }
|
|
108
|
+
.badge { font-size: 44px; line-height: 1; margin-bottom: 18px; color: ${accent}; }
|
|
109
|
+
h1 { font-size: 20px; margin: 0 0 10px; font-weight: 600; }
|
|
110
|
+
p { margin: 0; color: #9ca3af; font-size: 14px; line-height: 1.6; }
|
|
111
|
+
</style>
|
|
112
|
+
</head>
|
|
113
|
+
<body>
|
|
114
|
+
<div class="card">
|
|
115
|
+
<div class="badge">${ok ? "✓" : "✕"}</div>
|
|
116
|
+
<h1>${heading}</h1>
|
|
117
|
+
<p>${body}</p>
|
|
118
|
+
</div>
|
|
119
|
+
</body>
|
|
120
|
+
</html>`;
|
|
121
|
+
}
|
|
122
|
+
const SUCCESS_PAGE = htmlPage("Connected to MIND", "✓ Connected to MIND", "You can close this tab and return to your terminal.", true);
|
|
123
|
+
function errorPage(detail) {
|
|
124
|
+
return htmlPage("MIND connection failed", "Connection failed", `${detail} — close this tab and retry from your terminal.`, false);
|
|
125
|
+
}
|
|
126
|
+
async function registerClient(base, redirectUri, clientName) {
|
|
127
|
+
const res = await fetch(`${base}/oauth/mcp/register`, {
|
|
128
|
+
method: "POST",
|
|
129
|
+
headers: { "Content-Type": "application/json" },
|
|
130
|
+
body: JSON.stringify({
|
|
131
|
+
redirect_uris: [redirectUri],
|
|
132
|
+
client_name: clientName,
|
|
133
|
+
}),
|
|
134
|
+
});
|
|
135
|
+
if (!res.ok) {
|
|
136
|
+
const text = await res.text().catch(() => "");
|
|
137
|
+
throw new Error(`Client registration failed (${res.status}): ${text.slice(0, 300)}`);
|
|
138
|
+
}
|
|
139
|
+
const data = (await res.json());
|
|
140
|
+
if (!data.client_id) {
|
|
141
|
+
throw new Error("Client registration response did not include a client_id.");
|
|
142
|
+
}
|
|
143
|
+
return data.client_id;
|
|
144
|
+
}
|
|
145
|
+
async function exchangeCode(base, code, redirectUri, clientId, verifier) {
|
|
146
|
+
const res = await fetch(`${base}/oauth/mcp/token`, {
|
|
147
|
+
method: "POST",
|
|
148
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
149
|
+
body: new URLSearchParams({
|
|
150
|
+
grant_type: "authorization_code",
|
|
151
|
+
code,
|
|
152
|
+
redirect_uri: redirectUri,
|
|
153
|
+
client_id: clientId,
|
|
154
|
+
code_verifier: verifier,
|
|
155
|
+
}).toString(),
|
|
156
|
+
});
|
|
157
|
+
const data = (await res.json().catch(() => ({})));
|
|
158
|
+
if (!res.ok || !data.access_token) {
|
|
159
|
+
const detail = data.error_description || data.error || `HTTP ${res.status}`;
|
|
160
|
+
throw new Error(`Token exchange failed: ${detail}`);
|
|
161
|
+
}
|
|
162
|
+
return data.access_token;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Run the full browser OAuth flow against a MIND backend and return the
|
|
166
|
+
* minted `mind_` API key.
|
|
167
|
+
*/
|
|
168
|
+
async function connectViaBrowser(baseUrl, options = {}) {
|
|
169
|
+
const base = baseUrl.replace(/\/+$/, "");
|
|
170
|
+
const clientName = options.clientName ?? DEFAULT_CLIENT_NAME;
|
|
171
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
172
|
+
const shouldOpenBrowser = options.openBrowser ?? process.env.MIND_CONNECT_NO_BROWSER !== "1";
|
|
173
|
+
const { verifier, challenge } = generatePkcePair();
|
|
174
|
+
const state = base64url(crypto.randomBytes(24));
|
|
175
|
+
return new Promise((resolve, reject) => {
|
|
176
|
+
let settled = false;
|
|
177
|
+
let timer;
|
|
178
|
+
const server = http.createServer();
|
|
179
|
+
const finish = (err, key) => {
|
|
180
|
+
if (settled)
|
|
181
|
+
return;
|
|
182
|
+
settled = true;
|
|
183
|
+
if (timer)
|
|
184
|
+
clearTimeout(timer);
|
|
185
|
+
// Stop accepting connections; in-flight responses use "Connection: close"
|
|
186
|
+
// so they flush fully and the server drains on its own.
|
|
187
|
+
server.close();
|
|
188
|
+
// Drop any lingering idle keep-alive sockets so the CLI exits promptly
|
|
189
|
+
// (Node 18.2+). Responses are flushed before this runs because every
|
|
190
|
+
// handler ends the response before calling finish().
|
|
191
|
+
setImmediate(() => {
|
|
192
|
+
server.closeIdleConnections?.();
|
|
193
|
+
});
|
|
194
|
+
if (err)
|
|
195
|
+
reject(err);
|
|
196
|
+
else
|
|
197
|
+
resolve(key);
|
|
198
|
+
};
|
|
199
|
+
server.on("error", (err) => finish(new Error(`Local callback server error: ${err.message}`)));
|
|
200
|
+
server.on("request", (req, res) => {
|
|
201
|
+
void (async () => {
|
|
202
|
+
const url = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
203
|
+
if (url.pathname !== CALLBACK_PATH) {
|
|
204
|
+
res.writeHead(404, { "Content-Type": "text/plain", Connection: "close" });
|
|
205
|
+
res.end("Not found");
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
const respond = (status, html) => {
|
|
209
|
+
res.writeHead(status, {
|
|
210
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
211
|
+
"Cache-Control": "no-store",
|
|
212
|
+
Connection: "close",
|
|
213
|
+
});
|
|
214
|
+
res.end(html);
|
|
215
|
+
};
|
|
216
|
+
const errParam = url.searchParams.get("error");
|
|
217
|
+
if (errParam) {
|
|
218
|
+
const desc = url.searchParams.get("error_description") || errParam;
|
|
219
|
+
respond(400, errorPage(desc));
|
|
220
|
+
finish(new Error(`Authorization failed: ${desc}`));
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
const code = url.searchParams.get("code");
|
|
224
|
+
const returnedState = url.searchParams.get("state");
|
|
225
|
+
if (!code) {
|
|
226
|
+
respond(400, errorPage("No authorization code was returned"));
|
|
227
|
+
finish(new Error("Callback did not include an authorization code."));
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (returnedState !== state) {
|
|
231
|
+
respond(400, errorPage("State mismatch — possible cross-site request forgery"));
|
|
232
|
+
finish(new Error("State mismatch on OAuth callback — aborting (possible CSRF). Retry the connection."));
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
try {
|
|
236
|
+
const accessToken = await exchangeCode(base, code, redirectUri, clientId, verifier);
|
|
237
|
+
respond(200, SUCCESS_PAGE);
|
|
238
|
+
finish(null, accessToken);
|
|
239
|
+
}
|
|
240
|
+
catch (err) {
|
|
241
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
242
|
+
respond(502, errorPage(message));
|
|
243
|
+
finish(new Error(message));
|
|
244
|
+
}
|
|
245
|
+
})();
|
|
246
|
+
});
|
|
247
|
+
let redirectUri = "";
|
|
248
|
+
let clientId = "";
|
|
249
|
+
server.listen(0, "127.0.0.1", () => {
|
|
250
|
+
void (async () => {
|
|
251
|
+
try {
|
|
252
|
+
const { port } = server.address();
|
|
253
|
+
redirectUri = `http://127.0.0.1:${port}${CALLBACK_PATH}`;
|
|
254
|
+
clientId = await registerClient(base, redirectUri, clientName);
|
|
255
|
+
const authorizeUrl = `${base}/oauth/mcp/authorize?` +
|
|
256
|
+
new URLSearchParams({
|
|
257
|
+
response_type: "code",
|
|
258
|
+
client_id: clientId,
|
|
259
|
+
redirect_uri: redirectUri,
|
|
260
|
+
state,
|
|
261
|
+
code_challenge: challenge,
|
|
262
|
+
code_challenge_method: "S256",
|
|
263
|
+
scope: "mind:full",
|
|
264
|
+
}).toString();
|
|
265
|
+
options.onAuthorizeUrl?.(authorizeUrl);
|
|
266
|
+
if (shouldOpenBrowser) {
|
|
267
|
+
console.log("Opening your browser to connect to MIND...");
|
|
268
|
+
openInBrowser(authorizeUrl);
|
|
269
|
+
console.log("If the browser didn't open, use this link to connect:");
|
|
270
|
+
console.log(` ${authorizeUrl}`);
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
console.log("Open this link to connect:");
|
|
274
|
+
console.log(` ${authorizeUrl}`);
|
|
275
|
+
}
|
|
276
|
+
console.log("");
|
|
277
|
+
console.log("Waiting for you to click \"Connect\" in the browser...");
|
|
278
|
+
timer = setTimeout(() => {
|
|
279
|
+
finish(new Error(`Timed out after ${Math.round(timeoutMs / 60000)} minutes waiting for the browser connection. Run the setup again to retry.`));
|
|
280
|
+
}, timeoutMs);
|
|
281
|
+
// Don't let the timer keep the process alive on its own.
|
|
282
|
+
timer.unref?.();
|
|
283
|
+
}
|
|
284
|
+
catch (err) {
|
|
285
|
+
finish(err instanceof Error ? err : new Error(String(err)));
|
|
286
|
+
}
|
|
287
|
+
})();
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=oauth-connect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-connect.js","sourceRoot":"","sources":["../src/oauth-connect.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* integration path to use for its runtime, how to authenticate, and the
|
|
12
12
|
* session protocol — without having to be told.
|
|
13
13
|
*
|
|
14
|
-
* Tools (
|
|
14
|
+
* Tools (24):
|
|
15
15
|
* mind_query — Semantic search across the knowledge graph
|
|
16
16
|
* mind_remember — Store/manage content in the graph (auto-categorized)
|
|
17
17
|
* mind_folders — Organize documents into folders (list/create/rename/
|
|
@@ -26,7 +26,6 @@
|
|
|
26
26
|
* mind_research — Deep research agent jobs
|
|
27
27
|
* mind_train — Self-training and chat-to-KG sessions
|
|
28
28
|
* mind_social — Public feed posts, communities, and social feed
|
|
29
|
-
* mind_social_analytics — Read-only YT/LinkedIn/X/Twitch analytics + goals
|
|
30
29
|
* mind_profile — Profile, prompts, and model preferences
|
|
31
30
|
* mind_insights — ALE insights and analytics
|
|
32
31
|
* mind_automate — Automations and triggers
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,CA4wJjE"}
|
package/dist/server.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* integration path to use for its runtime, how to authenticate, and the
|
|
13
13
|
* session protocol — without having to be told.
|
|
14
14
|
*
|
|
15
|
-
* Tools (
|
|
15
|
+
* Tools (24):
|
|
16
16
|
* mind_query — Semantic search across the knowledge graph
|
|
17
17
|
* mind_remember — Store/manage content in the graph (auto-categorized)
|
|
18
18
|
* mind_folders — Organize documents into folders (list/create/rename/
|
|
@@ -27,7 +27,6 @@
|
|
|
27
27
|
* mind_research — Deep research agent jobs
|
|
28
28
|
* mind_train — Self-training and chat-to-KG sessions
|
|
29
29
|
* mind_social — Public feed posts, communities, and social feed
|
|
30
|
-
* mind_social_analytics — Read-only YT/LinkedIn/X/Twitch analytics + goals
|
|
31
30
|
* mind_profile — Profile, prompts, and model preferences
|
|
32
31
|
* mind_insights — ALE insights and analytics
|
|
33
32
|
* mind_automate — Automations and triggers
|
|
@@ -103,6 +102,27 @@ function createMindMcpServer(client) {
|
|
|
103
102
|
};
|
|
104
103
|
}
|
|
105
104
|
});
|
|
105
|
+
// ─── mind_osint ─────────────────────────────────────────
|
|
106
|
+
// Operate Ozzie, the Osiris OSINT analyst, from any MIND client.
|
|
107
|
+
server.tool("mind_osint", "Operate Ozzie — the autonomous OSINT analyst — through MIND. Investigate a target (domain, IP, org, person) and get a cited intelligence dossier; or set up live-feed alerts and watchlists in plain English. Ozzie's dossiers and alerts persist in its MIND knowledge graph, so use mind_query to recall past intelligence and mind_osint to run new work.", {
|
|
108
|
+
action: zod_1.z
|
|
109
|
+
.enum(["investigate", "add_monitor", "list_monitors", "remove_monitor", "add_watchlist", "list_watchlist", "remove_watchlist"])
|
|
110
|
+
.describe("investigate a target · add_monitor (NL live-feed alert) · list/remove monitors · add/list/remove watchlist"),
|
|
111
|
+
target: zod_1.z.string().optional().describe("Target for investigate / watchlist — a domain, IP, org, or person"),
|
|
112
|
+
text: zod_1.z.string().optional().describe("Natural-language monitor request, e.g. 'active fires in the USA' or 'earthquakes over magnitude 6'"),
|
|
113
|
+
id: zod_1.z.string().optional().describe("Monitor id (for remove_monitor)"),
|
|
114
|
+
}, async ({ action, target, text, id }) => {
|
|
115
|
+
try {
|
|
116
|
+
const result = (await client.osint({ action, target, text, id }));
|
|
117
|
+
const out = action === "investigate"
|
|
118
|
+
? (result.dossier || JSON.stringify(result, null, 2))
|
|
119
|
+
: JSON.stringify(result, null, 2);
|
|
120
|
+
return { content: [{ type: "text", text: out }] };
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
return { content: [{ type: "text", text: `Error operating Ozzie (OSINT): ${err}` }], isError: true };
|
|
124
|
+
}
|
|
125
|
+
});
|
|
106
126
|
// ─── mind_remember ──────────────────────────────────────
|
|
107
127
|
// Store/manage content in the knowledge graph. Auto-categorized by type.
|
|
108
128
|
// Enhanced: now supports create, delete, search, get, list actions.
|
|
@@ -3964,7 +3984,7 @@ function createMindMcpServer(client) {
|
|
|
3964
3984
|
};
|
|
3965
3985
|
}
|
|
3966
3986
|
});
|
|
3967
|
-
// ───
|
|
3987
|
+
// ─── mind_social ────────────────────────────────────────
|
|
3968
3988
|
// Read-only analytics across YouTube, LinkedIn, X, Twitch + goals progress.
|
|
3969
3989
|
server.tool("mind_social_analytics", "Read social media analytics from MIND's Social Dashboard — YouTube/LinkedIn/X/Twitch channel stats, recent videos with performance, retention curves, traffic sources, comment sentiment, and goal progress. Use this to answer questions like 'how did Tuesday's video do?' or 'am I on pace for 1k subs?'", {
|
|
3970
3990
|
action: zod_1.z
|
|
@@ -4108,7 +4128,7 @@ function createMindMcpServer(client) {
|
|
|
4108
4128
|
}
|
|
4109
4129
|
catch (err) {
|
|
4110
4130
|
return {
|
|
4111
|
-
content: [{ type: "text", text: `
|
|
4131
|
+
content: [{ type: "text", text: `mind_social error: ${err}` }],
|
|
4112
4132
|
isError: true,
|
|
4113
4133
|
};
|
|
4114
4134
|
}
|