git-paid 2.1.3 → 2.1.4
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 +22 -34
- package/bin/git-paid.js +14 -14
- package/lib/auth.js +866 -282
- package/lib/directories.js +123 -123
- package/lib/engine.js +228 -112
- package/lib/fixer.js +58 -0
- package/lib/inbox.js +359 -72
- package/lib/mcp.js +139 -90
- package/lib/pseo.js +290 -106
- package/lib/safe-fetch.js +239 -0
- package/lib/stateful-mcp.js +16 -4
- package/lib/submitter.js +89 -28
- package/package.json +53 -44
- package/brand/README.md +0 -54
- package/brand/postbuild-icon.png +0 -0
- package/brand/postbuild-icon.svg +0 -14
- package/brand/postbuild-logo.png +0 -0
- package/brand/postbuild-logo.svg +0 -17
- package/lib/stripe.js +0 -554
package/lib/mcp.js
CHANGED
|
@@ -9,8 +9,20 @@ import readline from "node:readline";
|
|
|
9
9
|
import { scanTargetUrl, searchBuyerIntentRadar, dispatchDirectories, DIRECTORIES } from "./engine.js";
|
|
10
10
|
import { verifyCliLicense } from "./auth.js";
|
|
11
11
|
import { applyLocalSeoFixes } from "./fixer.js";
|
|
12
|
-
import { listInboxMessages, sendTestVerificationEmail } from "./inbox.js";
|
|
13
|
-
import { withStatefulMcp, createGenericEntityAdapter } from "./stateful-mcp.js";
|
|
12
|
+
import { listInboxMessages, sendTestVerificationEmail, getBotInboxForDomain, markMessageVerified } from "./inbox.js";
|
|
13
|
+
import { withStatefulMcp, createGenericEntityAdapter, spotlightUntrustedText } from "./stateful-mcp.js";
|
|
14
|
+
import { safeFetch } from "./safe-fetch.js";
|
|
15
|
+
|
|
16
|
+
const ALLOWED_VERIFY_DOMAINS = [
|
|
17
|
+
"postbuild.dev",
|
|
18
|
+
...DIRECTORIES.map((d) => {
|
|
19
|
+
try {
|
|
20
|
+
return new URL(d.url).hostname.replace(/^www\./i, "").toLowerCase();
|
|
21
|
+
} catch {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}).filter(Boolean)
|
|
25
|
+
];
|
|
14
26
|
|
|
15
27
|
// ─── 1. STATEFUL MCP ENTITY ADAPTERS ──────────────────────────────────────────
|
|
16
28
|
|
|
@@ -43,7 +55,7 @@ export const inboxEntityAdapter = createGenericEntityAdapter({
|
|
|
43
55
|
updatedAtField: "receivedAt",
|
|
44
56
|
stubFields: ["id", "from", "otpCode", "primaryLink", "autoVerified"],
|
|
45
57
|
journalFields: ["verificationLinks"],
|
|
46
|
-
untrustedTextFields: ["subject", "snippet"],
|
|
58
|
+
untrustedTextFields: ["from", "subject", "snippet", "primaryLink", "otpCode"],
|
|
47
59
|
isActiveRecord: () => true
|
|
48
60
|
});
|
|
49
61
|
|
|
@@ -84,7 +96,7 @@ export const mcpRadar = withStatefulMcp({
|
|
|
84
96
|
|
|
85
97
|
const domainDirectoryState = new Map();
|
|
86
98
|
|
|
87
|
-
function getDomainDirectories(targetUrl = "https://postbuild.dev", report = null) {
|
|
99
|
+
function getDomainDirectories(targetUrl = "https://www.postbuild.dev", report = null) {
|
|
88
100
|
const domain = targetUrl.replace(/^https?:\/\//i, "").replace(/^www\./i, "").split("/")[0] || "postbuild.dev";
|
|
89
101
|
if (!domainDirectoryState.has(domain)) {
|
|
90
102
|
const baseDirs = (report?.directories || DIRECTORIES).map((d, idx) => ({
|
|
@@ -111,46 +123,56 @@ function getDomainDirectories(targetUrl = "https://postbuild.dev", report = null
|
|
|
111
123
|
return domainDirectoryState.get(domain);
|
|
112
124
|
}
|
|
113
125
|
|
|
114
|
-
// ─── 2. HANDS-FREE INBOX AUTO-VERIFIER
|
|
126
|
+
// ─── 2. HANDS-FREE INBOX AUTO-VERIFIER (OPT-IN & SSRF-ALLOWLISTED) ────────────
|
|
115
127
|
|
|
116
|
-
export async function autoVerifyInboxLinks(inboxAddress = "
|
|
117
|
-
const
|
|
128
|
+
export async function autoVerifyInboxLinks(inboxAddress = "", options = {}) {
|
|
129
|
+
const shouldAutoVerify = options.autoVerify === true;
|
|
130
|
+
const targetMessageId = options.messageId ? String(options.messageId).trim() : "";
|
|
131
|
+
const res = await listInboxMessages(inboxAddress || getBotInboxForDomain("postbuild.dev"), {
|
|
132
|
+
allowRemoteFallback: options.allowRemoteFallback,
|
|
133
|
+
bearerToken: options.bearerToken
|
|
134
|
+
});
|
|
118
135
|
const verificationResults = [];
|
|
119
136
|
|
|
120
137
|
for (const m of res.messages) {
|
|
138
|
+
const shouldVerifyThisRow =
|
|
139
|
+
shouldAutoVerify && (!targetMessageId || m.id === targetMessageId);
|
|
121
140
|
const entry = {
|
|
122
141
|
id: m.id,
|
|
123
142
|
from: m.from,
|
|
124
143
|
subject: m.subject,
|
|
125
144
|
otpCode: m.otpCode || null,
|
|
126
|
-
primaryLink: m.primaryLink
|
|
127
|
-
|
|
128
|
-
|
|
145
|
+
primaryLink: m.primaryLink ? spotlightUntrustedText(m.primaryLink) : null,
|
|
146
|
+
verificationUrl: m.verificationUrl || (m.primaryLink && /^https:\/\//i.test(m.primaryLink) ? m.primaryLink : null),
|
|
147
|
+
autoVerified: Boolean(m.autoVerified || m.status === "verified"),
|
|
148
|
+
status: m.status,
|
|
149
|
+
httpStatus: m.httpStatus ?? null,
|
|
129
150
|
version_etag: m.autoVerified ? "v2" : "v1",
|
|
130
151
|
receivedAt: m.receivedAt,
|
|
131
152
|
snippet: m.snippet
|
|
132
153
|
};
|
|
133
154
|
|
|
134
|
-
if (m.primaryLink && /^https?:\/\//i.test(m.primaryLink)) {
|
|
155
|
+
if (shouldVerifyThisRow && !entry.autoVerified && m.primaryLink && /^https?:\/\//i.test(m.primaryLink)) {
|
|
135
156
|
try {
|
|
136
|
-
const
|
|
137
|
-
const timer = setTimeout(() => controller.abort(), 4500);
|
|
138
|
-
const resp = await fetch(m.primaryLink, {
|
|
157
|
+
const resp = await safeFetch(m.primaryLink, {
|
|
139
158
|
method: "GET",
|
|
140
|
-
|
|
141
|
-
|
|
159
|
+
timeoutMs: 4500,
|
|
160
|
+
allowedDomains: ALLOWED_VERIFY_DOMAINS,
|
|
161
|
+
lookupFn: options.lookupFn,
|
|
142
162
|
headers: {
|
|
143
|
-
"User-Agent": "Postbuild-
|
|
163
|
+
"User-Agent": "Postbuild-Verifier/2.1 (+https://www.postbuild.dev)"
|
|
144
164
|
}
|
|
145
165
|
});
|
|
146
|
-
clearTimeout(timer);
|
|
147
166
|
entry.autoVerified = resp.ok || resp.status < 400;
|
|
148
167
|
entry.httpStatus = resp.status;
|
|
168
|
+
entry.status = entry.autoVerified ? "verified" : m.status;
|
|
149
169
|
entry.version_etag = "v2";
|
|
170
|
+
if (entry.autoVerified) {
|
|
171
|
+
markMessageVerified(m.id, true, resp.status);
|
|
172
|
+
}
|
|
150
173
|
} catch {
|
|
151
|
-
entry.autoVerified =
|
|
152
|
-
entry.httpStatus =
|
|
153
|
-
entry.version_etag = "v2";
|
|
174
|
+
entry.autoVerified = false;
|
|
175
|
+
entry.httpStatus = 0;
|
|
154
176
|
}
|
|
155
177
|
}
|
|
156
178
|
|
|
@@ -161,7 +183,9 @@ export async function autoVerifyInboxLinks(inboxAddress = "postbuild-bot@postbui
|
|
|
161
183
|
inboxAddress: res.inboxAddress,
|
|
162
184
|
totalMessages: verificationResults.length,
|
|
163
185
|
verifiedCount: verificationResults.filter((x) => x.autoVerified).length,
|
|
164
|
-
extractedOtps: verificationResults
|
|
186
|
+
extractedOtps: verificationResults
|
|
187
|
+
.filter((x) => x.otpCode)
|
|
188
|
+
.map((x) => ({ from: spotlightUntrustedText(x.from), otp: spotlightUntrustedText(x.otpCode) })),
|
|
165
189
|
messages: verificationResults
|
|
166
190
|
};
|
|
167
191
|
}
|
|
@@ -243,21 +267,20 @@ export async function runStatefulMcpSimulation({
|
|
|
243
267
|
// ─── 4. OBSIDIAN VAULTOS TELEMETRY & DASHBOARD SYNC ───────────────────────────
|
|
244
268
|
|
|
245
269
|
export async function syncPostbuildToVault({
|
|
246
|
-
vaultPath =
|
|
247
|
-
urls = ["https://postbuild.dev"
|
|
248
|
-
sessionId = "vaultos-sync"
|
|
270
|
+
vaultPath = process.cwd(),
|
|
271
|
+
urls = ["https://www.postbuild.dev"],
|
|
272
|
+
sessionId = "vaultos-sync",
|
|
273
|
+
bearerToken = ""
|
|
249
274
|
} = {}) {
|
|
250
275
|
const projectsData = [];
|
|
251
276
|
|
|
252
277
|
for (const targetUrl of urls) {
|
|
253
278
|
const report = await scanTargetUrl(targetUrl);
|
|
254
279
|
const state = getDomainDirectories(targetUrl, report);
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
}
|
|
260
|
-
const verifiedInbox = await autoVerifyInboxLinks(report.botEmail);
|
|
280
|
+
const verifiedInbox = await autoVerifyInboxLinks(report.botEmail, {
|
|
281
|
+
autoVerify: false,
|
|
282
|
+
bearerToken
|
|
283
|
+
});
|
|
261
284
|
|
|
262
285
|
const dirsQuery = await mcpDirectories.queryWithSupersetCache({
|
|
263
286
|
sessionId,
|
|
@@ -282,7 +305,7 @@ export async function syncPostbuildToVault({
|
|
|
282
305
|
botEmail: report.botEmail,
|
|
283
306
|
inboxCount: verifiedInbox.totalMessages,
|
|
284
307
|
autoVerifiedLinks: verifiedInbox.verifiedCount,
|
|
285
|
-
latestOtp: verifiedInbox.extractedOtps[0]?.otp || "
|
|
308
|
+
latestOtp: verifiedInbox.extractedOtps[0]?.otp || "None",
|
|
286
309
|
mcpReductionPct: mcpPass2._mcp?.payload_bytes?.reduction_pct || "-75.4%",
|
|
287
310
|
mcpQueryMs: mcpPass2._mcp?.query_ms || 0.04,
|
|
288
311
|
updatedAt: new Date().toISOString()
|
|
@@ -312,26 +335,54 @@ export async function syncPostbuildToVault({
|
|
|
312
335
|
};
|
|
313
336
|
|
|
314
337
|
const writtenVaultFiles = [];
|
|
338
|
+
const effectiveTarget = fs.existsSync(vaultPath) ? vaultPath : process.cwd();
|
|
339
|
+
const isObsidianVault =
|
|
340
|
+
fs.existsSync(path.join(effectiveTarget, ".obsidian")) ||
|
|
341
|
+
fs.existsSync(path.join(effectiveTarget, "_dashboards"));
|
|
315
342
|
|
|
316
|
-
if (
|
|
317
|
-
const metaDir = path.join(
|
|
343
|
+
if (isObsidianVault) {
|
|
344
|
+
const metaDir = path.join(effectiveTarget, "_meta");
|
|
318
345
|
fs.mkdirSync(metaDir, { recursive: true });
|
|
319
346
|
const metaFile = path.join(metaDir, "postbuild-telemetry.json");
|
|
320
347
|
fs.writeFileSync(metaFile, JSON.stringify(telemetryPayload, null, 2), "utf8");
|
|
321
348
|
writtenVaultFiles.push(metaFile);
|
|
322
349
|
|
|
323
|
-
const dashboardsDir = path.join(
|
|
350
|
+
const dashboardsDir = path.join(effectiveTarget, "_dashboards");
|
|
324
351
|
if (fs.existsSync(dashboardsDir)) {
|
|
325
352
|
const pbDashboardPath = path.join(dashboardsDir, "Postbuild Launch.md");
|
|
326
353
|
const pbDashboardContent = buildVaultOsPostbuildDashboardMarkdown();
|
|
327
354
|
fs.writeFileSync(pbDashboardPath, pbDashboardContent, "utf8");
|
|
328
355
|
writtenVaultFiles.push(pbDashboardPath);
|
|
329
356
|
}
|
|
357
|
+
} else {
|
|
358
|
+
const pbDir = path.join(effectiveTarget, ".postbuild");
|
|
359
|
+
fs.mkdirSync(pbDir, { recursive: true });
|
|
360
|
+
const jsonFile = path.join(pbDir, "telemetry.json");
|
|
361
|
+
fs.writeFileSync(jsonFile, JSON.stringify(telemetryPayload, null, 2), "utf8");
|
|
362
|
+
writtenVaultFiles.push(jsonFile);
|
|
363
|
+
|
|
364
|
+
const mdLines = [
|
|
365
|
+
"# postbuild Launch & SEO Status Report",
|
|
366
|
+
"",
|
|
367
|
+
`> Synced: \`${telemetryPayload.generatedAt}\` via \`postbuild-mcp\``,
|
|
368
|
+
"",
|
|
369
|
+
"| Domain | Readiness Score | Checks | Programmatic SEO | Directories | Bot Inbox | Latest OTP |",
|
|
370
|
+
"| :--- | :--- | :--- | :--- | :--- | :--- | :--- |",
|
|
371
|
+
...telemetryPayload.projects.map(
|
|
372
|
+
(p) =>
|
|
373
|
+
`| **${p.domain}** | **${p.readinessScore}/100** | ${p.passedChecks}/${p.totalChecks} | ${p.pseoCount} Routes | ${p.directoryCount} (${p.autoVerifiedLinks} Verified) | \`${p.botEmail}\` | \`${p.latestOtp}\` |`
|
|
374
|
+
),
|
|
375
|
+
""
|
|
376
|
+
];
|
|
377
|
+
const mdFile = path.join(effectiveTarget, "LAUNCH_STATUS.md");
|
|
378
|
+
fs.writeFileSync(mdFile, mdLines.join("\n"), "utf8");
|
|
379
|
+
writtenVaultFiles.push(mdFile);
|
|
330
380
|
}
|
|
331
381
|
|
|
332
382
|
return {
|
|
333
383
|
ok: true,
|
|
334
|
-
|
|
384
|
+
mode: isObsidianVault ? "obsidian_vault" : "markdown_repo",
|
|
385
|
+
vaultPath: effectiveTarget,
|
|
335
386
|
writtenVaultFiles,
|
|
336
387
|
telemetry: telemetryPayload
|
|
337
388
|
};
|
|
@@ -340,7 +391,7 @@ export async function syncPostbuildToVault({
|
|
|
340
391
|
function buildVaultOsPostbuildDashboardMarkdown() {
|
|
341
392
|
return `---
|
|
342
393
|
aliases:
|
|
343
|
-
- Postbuild Launch
|
|
394
|
+
- Postbuild Launch Dashboard
|
|
344
395
|
- "_dashboards/Postbuild Launch"
|
|
345
396
|
tags:
|
|
346
397
|
- dashboard
|
|
@@ -352,7 +403,7 @@ cssclasses:
|
|
|
352
403
|
---
|
|
353
404
|
|
|
354
405
|
\`\`\`dataviewjs
|
|
355
|
-
// ─── POSTBUILD MCP LAUNCH
|
|
406
|
+
// ─── POSTBUILD MCP LAUNCH DASHBOARD ──────────────────────────────────────────
|
|
356
407
|
// Reads cached telemetry from _meta/postbuild-telemetry.json (<2ms render)
|
|
357
408
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
358
409
|
|
|
@@ -392,8 +443,8 @@ root.innerHTML = \`
|
|
|
392
443
|
|
|
393
444
|
<div class="hero-strip">
|
|
394
445
|
<div>
|
|
395
|
-
<div class="hero-title">Postbuild Launch & SEO
|
|
396
|
-
<div class="hero-subtitle">Managed autonomously by
|
|
446
|
+
<div class="hero-title">Postbuild Launch & SEO Dashboard</div>
|
|
447
|
+
<div class="hero-subtitle">Managed autonomously by Postbuild MCP (<code>npx git-paid mcp</code>)</div>
|
|
397
448
|
</div>
|
|
398
449
|
<div class="stat-group">
|
|
399
450
|
<div class="stat-block">
|
|
@@ -423,7 +474,7 @@ root.innerHTML = \`
|
|
|
423
474
|
<span class="badge" style="background:rgba(16,185,129,0.15); color:#10b981; border:1px solid rgba(16,185,129,0.3);">LIVE AUDITS</span>
|
|
424
475
|
Domain Readiness, pSEO & Directory Dispatch
|
|
425
476
|
</div>
|
|
426
|
-
<a class="action-btn" href="https://postbuild.dev" style="text-decoration:none;">Open Studio -></a>
|
|
477
|
+
<a class="action-btn" href="https://www.postbuild.dev" style="text-decoration:none;">Open Studio -></a>
|
|
427
478
|
</div>
|
|
428
479
|
<div style="display:flex; flex-direction:column; gap:8px;">
|
|
429
480
|
\${projects.map(p => \`
|
|
@@ -432,7 +483,7 @@ root.innerHTML = \`
|
|
|
432
483
|
<strong style="font-size:14px;">\${p.domain}</strong>
|
|
433
484
|
<span class="badge badge-cyan" style="margin-left:8px;">\${p.passedChecks}/\${p.totalChecks} Checks Passed</span>
|
|
434
485
|
<div style="font-size:11.5px; color:var(--text-muted); margin-top:4px;">
|
|
435
|
-
<code>\${p.botEmail}</code> · \${p.pseoCount} pSEO Routes · \${p.directoryCount} Directories (\${p.autoVerifiedLinks}
|
|
486
|
+
<code>\${p.botEmail}</code> · \${p.pseoCount} pSEO Routes · \${p.directoryCount} Directories (\${p.autoVerifiedLinks} Verified) · Latest OTP: <code>\${p.latestOtp}</code>
|
|
436
487
|
</div>
|
|
437
488
|
</div>
|
|
438
489
|
<div style="text-align:right;">
|
|
@@ -470,7 +521,7 @@ root.innerHTML = \`
|
|
|
470
521
|
`;
|
|
471
522
|
}
|
|
472
523
|
|
|
473
|
-
// ─── 5. AGENT SKILL & CONFIG SCAFFOLDER (`npx
|
|
524
|
+
// ─── 5. AGENT SKILL & CONFIG SCAFFOLDER (`npx git-paid skill`) ───────────────
|
|
474
525
|
|
|
475
526
|
export function installAgentSkillFiles({ cwd = process.cwd() } = {}) {
|
|
476
527
|
const skillDir = path.join(cwd, ".agent", "skills", "postbuild");
|
|
@@ -479,12 +530,12 @@ export function installAgentSkillFiles({ cwd = process.cwd() } = {}) {
|
|
|
479
530
|
const skillMdPath = path.join(skillDir, "SKILL.md");
|
|
480
531
|
const skillMd = `---
|
|
481
532
|
name: postbuild
|
|
482
|
-
description: Autonomous Post-Build SEO, 85-Directory
|
|
533
|
+
description: Autonomous Post-Build SEO, 85-Directory Launch Kit, @postbuild.dev Inbox Verifier, and Markdown Launch Status Sync powered by Postbuild MCP (git-paid).
|
|
483
534
|
---
|
|
484
535
|
|
|
485
|
-
# Postbuild (\`git
|
|
536
|
+
# Postbuild (\`git-paid\`) Agent Skill
|
|
486
537
|
|
|
487
|
-
Use the \`
|
|
538
|
+
Use the \`git-paid\` MCP server (\`npx -y git-paid mcp\`) or CLI (\`npx git-paid\`) to audit, fix, monetize, and launch any web project.
|
|
488
539
|
|
|
489
540
|
## MCP Server Configuration (\`.mcp.json\` / \`mcp_config.json\`)
|
|
490
541
|
\`\`\`json
|
|
@@ -492,7 +543,7 @@ Use the \`postbuild\` MCP server (\`npx postbuild mcp\`) or CLI (\`npx postbuild
|
|
|
492
543
|
"mcpServers": {
|
|
493
544
|
"postbuild": {
|
|
494
545
|
"command": "npx",
|
|
495
|
-
"args": ["-y", "
|
|
546
|
+
"args": ["-y", "git-paid", "mcp"]
|
|
496
547
|
}
|
|
497
548
|
}
|
|
498
549
|
}
|
|
@@ -500,11 +551,11 @@ Use the \`postbuild\` MCP server (\`npx postbuild mcp\`) or CLI (\`npx postbuild
|
|
|
500
551
|
|
|
501
552
|
## Available Postbuild MCP Tools
|
|
502
553
|
1. \`postbuild_scan\` — Run the 8-check live Monetization & SEO audit on any URL.
|
|
503
|
-
2. \`postbuild_directories\` — Query the 85 startup & AI directories using In-Memory Superset Caching
|
|
554
|
+
2. \`postbuild_directories\` — Query the 85 startup & AI directories using In-Memory Superset Caching + Watermark Context Residuals (\`unchanged@vN\`).
|
|
504
555
|
3. \`postbuild_pseo\` — Query the 25 Programmatic SEO routes with stateful delta compaction.
|
|
505
|
-
4. \`postbuild_dispatch\` —
|
|
506
|
-
5. \`postbuild_inbox\` — Read \`<slug
|
|
507
|
-
6. \`postbuild_vault_sync\` —
|
|
556
|
+
4. \`postbuild_dispatch\` — Prepare 85 prefilled launch links and ping IndexNow/WebSub protected by Two-Phase Cryptographic OCC (\`dry_run: true\` issues \`commit_token: "ct_..."\`; \`dry_run: false\` commits).
|
|
557
|
+
5. \`postbuild_inbox\` — Read \`<slug>-<hash>@postbuild.dev\` with Untrusted Content Spotlighting and optionally verify allowlisted directory confirmation links (\`auto_verify: true\`).
|
|
558
|
+
6. \`postbuild_vault_sync\` — Write \`LAUNCH_STATUS.md\` and \`.postbuild/telemetry.json\` to any repository (or sync to an Obsidian VaultOS dashboard if present).
|
|
508
559
|
`;
|
|
509
560
|
fs.writeFileSync(skillMdPath, skillMd, "utf8");
|
|
510
561
|
|
|
@@ -515,24 +566,24 @@ Use the \`postbuild\` MCP server (\`npx postbuild mcp\`) or CLI (\`npx postbuild
|
|
|
515
566
|
mcpServers: {
|
|
516
567
|
postbuild: {
|
|
517
568
|
command: "npx",
|
|
518
|
-
args: ["-y", "
|
|
569
|
+
args: ["-y", "git-paid", "mcp"]
|
|
519
570
|
}
|
|
520
571
|
}
|
|
521
572
|
}
|
|
522
573
|
};
|
|
523
574
|
}
|
|
524
575
|
|
|
525
|
-
// ─── 6. STDIO JSON-RPC 2.0 MCP SERVER (`npx
|
|
576
|
+
// ─── 6. STDIO JSON-RPC 2.0 MCP SERVER (`npx git-paid mcp`) ───────────────────
|
|
526
577
|
|
|
527
578
|
export const MCP_TOOLS = [
|
|
528
579
|
{
|
|
529
580
|
name: "postbuild_scan",
|
|
530
581
|
description:
|
|
531
|
-
"Run an 8-point Post-Build Monetization, AI Crawler, & SEO audit on any URL and provision a dedicated <slug
|
|
582
|
+
"Run an 8-point Post-Build Monetization, AI Crawler, & SEO audit on any URL and provision a dedicated <slug>-<hash>@postbuild.dev verification inbox.",
|
|
532
583
|
inputSchema: {
|
|
533
584
|
type: "object",
|
|
534
585
|
properties: {
|
|
535
|
-
url: { type: "string", description: "Target URL or domain (e.g. https://postbuild.dev)" }
|
|
586
|
+
url: { type: "string", description: "Target URL or domain (e.g. https://www.postbuild.dev)" }
|
|
536
587
|
},
|
|
537
588
|
required: ["url"]
|
|
538
589
|
}
|
|
@@ -540,11 +591,11 @@ export const MCP_TOOLS = [
|
|
|
540
591
|
{
|
|
541
592
|
name: "postbuild_directories",
|
|
542
593
|
description:
|
|
543
|
-
"Search and filter the 85 startup, AI, and developer directories using In-Memory Superset Cache and Watermark Context Residuals (unchanged@vN / updated@vN)
|
|
594
|
+
"Search and filter the 85 startup, AI, and developer directories using In-Memory Superset Cache and Watermark Context Residuals (unchanged@vN / updated@vN).",
|
|
544
595
|
inputSchema: {
|
|
545
596
|
type: "object",
|
|
546
597
|
properties: {
|
|
547
|
-
url: { type: "string", description: "Target URL (default: https://postbuild.dev)" },
|
|
598
|
+
url: { type: "string", description: "Target URL (default: https://www.postbuild.dev)" },
|
|
548
599
|
category: { type: "string", description: "Optional category filter (e.g. AI, SaaS, Developer, Launch)" },
|
|
549
600
|
status: { type: "string", description: "Optional status filter (ready_auto, queued, dispatched)" },
|
|
550
601
|
min_da: { type: "number", description: "Minimum Domain Rating (0-100)" },
|
|
@@ -569,7 +620,7 @@ export const MCP_TOOLS = [
|
|
|
569
620
|
{
|
|
570
621
|
name: "postbuild_dispatch",
|
|
571
622
|
description:
|
|
572
|
-
"
|
|
623
|
+
"Prepare 85 prefilled directory links and ping IndexNow/WebSub with Two-Phase Cryptographic OCC Guard. Call with dry_run: true first to receive a commit_token (ct_...), then call with dry_run: false and commit_token to commit.",
|
|
573
624
|
inputSchema: {
|
|
574
625
|
type: "object",
|
|
575
626
|
properties: {
|
|
@@ -577,7 +628,7 @@ export const MCP_TOOLS = [
|
|
|
577
628
|
directory_ids: {
|
|
578
629
|
type: "array",
|
|
579
630
|
items: { type: "string" },
|
|
580
|
-
description: "Optional subset of directory IDs
|
|
631
|
+
description: "Optional subset of directory IDs"
|
|
581
632
|
},
|
|
582
633
|
expected_version: { type: "string", description: "Expected version watermark (e.g. v1)" },
|
|
583
634
|
dry_run: { type: "boolean", description: "Phase 1 preview mode (default: true)" },
|
|
@@ -589,13 +640,12 @@ export const MCP_TOOLS = [
|
|
|
589
640
|
{
|
|
590
641
|
name: "postbuild_inbox",
|
|
591
642
|
description:
|
|
592
|
-
"Check the dedicated <slug
|
|
643
|
+
"Check the dedicated <slug>-<hash>@postbuild.dev verification inbox with Untrusted Content Spotlighting. Set auto_verify: true to follow allowlisted directory confirmation links.",
|
|
593
644
|
inputSchema: {
|
|
594
645
|
type: "object",
|
|
595
646
|
properties: {
|
|
596
|
-
inbox: { type: "string", description: "Bot inbox address
|
|
597
|
-
auto_verify: { type: "boolean", description: "
|
|
598
|
-
send_test: { type: "boolean", description: "Send a test verification email first" }
|
|
647
|
+
inbox: { type: "string", description: "Bot inbox address" },
|
|
648
|
+
auto_verify: { type: "boolean", description: "Opt-in: follow allowlisted confirmation links (default: false)" }
|
|
599
649
|
}
|
|
600
650
|
}
|
|
601
651
|
},
|
|
@@ -615,13 +665,13 @@ export const MCP_TOOLS = [
|
|
|
615
665
|
{
|
|
616
666
|
name: "postbuild_vault_sync",
|
|
617
667
|
description:
|
|
618
|
-
"
|
|
668
|
+
"Write LAUNCH_STATUS.md and .postbuild/telemetry.json into a local project directory (or sync to an Obsidian VaultOS dashboard if .obsidian/ is present).",
|
|
619
669
|
inputSchema: {
|
|
620
670
|
type: "object",
|
|
621
671
|
properties: {
|
|
622
672
|
vault_path: {
|
|
623
673
|
type: "string",
|
|
624
|
-
description: "
|
|
674
|
+
description: "Target repository or Obsidian vault path (defaults to current working directory)"
|
|
625
675
|
},
|
|
626
676
|
urls: {
|
|
627
677
|
type: "array",
|
|
@@ -633,10 +683,10 @@ export const MCP_TOOLS = [
|
|
|
633
683
|
}
|
|
634
684
|
];
|
|
635
685
|
|
|
636
|
-
export async function executeMcpToolCall(name, args = {}, sessionId = "mcp-stdio-session") {
|
|
686
|
+
export async function executeMcpToolCall(name, args = {}, sessionId = "mcp-stdio-session", authToken = "") {
|
|
637
687
|
if (name === "postbuild_scan") {
|
|
638
|
-
const report = await scanTargetUrl(args.url || "https://postbuild.dev");
|
|
639
|
-
const license = await verifyCliLicense({ domain: report.domain });
|
|
688
|
+
const report = await scanTargetUrl(args.url || "https://www.postbuild.dev");
|
|
689
|
+
const license = await verifyCliLicense({ domain: report.domain, token: authToken });
|
|
640
690
|
getDomainDirectories(report.targetUrl, report);
|
|
641
691
|
return {
|
|
642
692
|
domain: report.domain,
|
|
@@ -658,9 +708,9 @@ export async function executeMcpToolCall(name, args = {}, sessionId = "mcp-stdio
|
|
|
658
708
|
}
|
|
659
709
|
|
|
660
710
|
if (name === "postbuild_directories") {
|
|
661
|
-
const targetUrl = args.url || "https://postbuild.dev";
|
|
711
|
+
const targetUrl = args.url || "https://www.postbuild.dev";
|
|
662
712
|
const state = getDomainDirectories(targetUrl);
|
|
663
|
-
const license = await verifyCliLicense({ domain: state.domain });
|
|
713
|
+
const license = await verifyCliLicense({ domain: state.domain, token: authToken });
|
|
664
714
|
const catFilter = (args.category || "").toLowerCase();
|
|
665
715
|
const statusFilter = (args.status || "").toLowerCase();
|
|
666
716
|
const minDa = Number(args.min_da) || 0;
|
|
@@ -698,8 +748,8 @@ export async function executeMcpToolCall(name, args = {}, sessionId = "mcp-stdio
|
|
|
698
748
|
}
|
|
699
749
|
|
|
700
750
|
if (name === "postbuild_pseo") {
|
|
701
|
-
const targetUrl = args.url || "https://postbuild.dev";
|
|
702
|
-
const license = await verifyCliLicense({ domain: targetUrl.replace(/^https?:\/\//, "") });
|
|
751
|
+
const targetUrl = args.url || "https://www.postbuild.dev";
|
|
752
|
+
const license = await verifyCliLicense({ domain: targetUrl.replace(/^https?:\/\//, ""), token: authToken });
|
|
703
753
|
const intentFilter = (args.intent || "").toLowerCase();
|
|
704
754
|
const maxAllowed = license.valid ? 25 : 3;
|
|
705
755
|
|
|
@@ -738,9 +788,9 @@ export async function executeMcpToolCall(name, args = {}, sessionId = "mcp-stdio
|
|
|
738
788
|
}
|
|
739
789
|
|
|
740
790
|
if (name === "postbuild_dispatch") {
|
|
741
|
-
const targetUrl = args.url || "https://postbuild.dev";
|
|
791
|
+
const targetUrl = args.url || "https://www.postbuild.dev";
|
|
742
792
|
const state = getDomainDirectories(targetUrl);
|
|
743
|
-
const license = await verifyCliLicense({ domain: state.domain });
|
|
793
|
+
const license = await verifyCliLicense({ domain: state.domain, token: authToken });
|
|
744
794
|
if (!license.valid) {
|
|
745
795
|
return {
|
|
746
796
|
isError: true,
|
|
@@ -798,7 +848,7 @@ export async function executeMcpToolCall(name, args = {}, sessionId = "mcp-stdio
|
|
|
798
848
|
state.updated_at = nowIso;
|
|
799
849
|
for (const d of state.directories) {
|
|
800
850
|
if (!targetIds.length || targetIds.includes(d.id)) {
|
|
801
|
-
d.status = d.autoSubmit ? "
|
|
851
|
+
d.status = d.autoSubmit ? "indexnow_pinged_form_ready" : "prefilled_ready";
|
|
802
852
|
d.version_etag = nextVer;
|
|
803
853
|
d.updated_at = nowIso;
|
|
804
854
|
}
|
|
@@ -815,7 +865,7 @@ export async function executeMcpToolCall(name, args = {}, sessionId = "mcp-stdio
|
|
|
815
865
|
}
|
|
816
866
|
|
|
817
867
|
if (name === "postbuild_inbox") {
|
|
818
|
-
const license = await verifyCliLicense({ domain: "postbuild.dev" });
|
|
868
|
+
const license = await verifyCliLicense({ domain: "postbuild.dev", token: authToken });
|
|
819
869
|
if (!license.valid) {
|
|
820
870
|
return {
|
|
821
871
|
isError: true,
|
|
@@ -826,14 +876,12 @@ export async function executeMcpToolCall(name, args = {}, sessionId = "mcp-stdio
|
|
|
826
876
|
};
|
|
827
877
|
}
|
|
828
878
|
|
|
829
|
-
const inboxAddr = args.inbox || "postbuild
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
? await autoVerifyInboxLinks(inboxAddr)
|
|
836
|
-
: await listInboxMessages(inboxAddr);
|
|
879
|
+
const inboxAddr = args.inbox || license.inbox || getBotInboxForDomain(license.domain || "postbuild.dev", license.email);
|
|
880
|
+
const autoVerify = Boolean(args.auto_verify);
|
|
881
|
+
const result = await autoVerifyInboxLinks(inboxAddr, {
|
|
882
|
+
autoVerify,
|
|
883
|
+
bearerToken: license.token
|
|
884
|
+
});
|
|
837
885
|
|
|
838
886
|
const compacted = mcpInbox.compactList({
|
|
839
887
|
sessionId,
|
|
@@ -850,8 +898,8 @@ export async function executeMcpToolCall(name, args = {}, sessionId = "mcp-stdio
|
|
|
850
898
|
}
|
|
851
899
|
|
|
852
900
|
if (name === "postbuild_fix") {
|
|
853
|
-
const report = await scanTargetUrl(args.url || "https://postbuild.dev");
|
|
854
|
-
const license = await verifyCliLicense({ domain: report.domain });
|
|
901
|
+
const report = await scanTargetUrl(args.url || "https://www.postbuild.dev");
|
|
902
|
+
const license = await verifyCliLicense({ domain: report.domain, token: authToken });
|
|
855
903
|
if (!license.valid) {
|
|
856
904
|
return {
|
|
857
905
|
isError: true,
|
|
@@ -871,7 +919,7 @@ export async function executeMcpToolCall(name, args = {}, sessionId = "mcp-stdio
|
|
|
871
919
|
}
|
|
872
920
|
|
|
873
921
|
if (name === "postbuild_vault_sync") {
|
|
874
|
-
const license = await verifyCliLicense({ domain: "postbuild.dev" });
|
|
922
|
+
const license = await verifyCliLicense({ domain: "postbuild.dev", token: authToken });
|
|
875
923
|
if (!license.valid) {
|
|
876
924
|
return {
|
|
877
925
|
isError: true,
|
|
@@ -883,9 +931,10 @@ export async function executeMcpToolCall(name, args = {}, sessionId = "mcp-stdio
|
|
|
883
931
|
}
|
|
884
932
|
|
|
885
933
|
return await syncPostbuildToVault({
|
|
886
|
-
vaultPath: args.vault_path ||
|
|
887
|
-
urls: Array.isArray(args.urls) && args.urls.length ? args.urls : ["https://postbuild.dev"
|
|
888
|
-
sessionId
|
|
934
|
+
vaultPath: args.vault_path || process.cwd(),
|
|
935
|
+
urls: Array.isArray(args.urls) && args.urls.length ? args.urls : ["https://www.postbuild.dev"],
|
|
936
|
+
sessionId,
|
|
937
|
+
bearerToken: license.token
|
|
889
938
|
});
|
|
890
939
|
}
|
|
891
940
|
|