@capitalthought/agentsfirst-mcp 0.1.1 → 0.1.2
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/probe.d.ts +1 -0
- package/dist/probe.js +16 -0
- package/dist/score.js +30 -14
- package/package.json +1 -1
package/dist/probe.d.ts
CHANGED
package/dist/probe.js
CHANGED
|
@@ -379,10 +379,26 @@ export async function probeWebsite(url) {
|
|
|
379
379
|
'cohere-ai',
|
|
380
380
|
];
|
|
381
381
|
const declared = aiAgents.filter((ua) => new RegExp(`User-agent:\\s*${ua}`, 'i').test(robotsBody));
|
|
382
|
+
// Content-Signal directive (Cloudflare's emerging AI-policy convention).
|
|
383
|
+
// Format: `Content-Signal: ai-train=yes, search=yes, ai-input=yes`
|
|
384
|
+
const contentSignalLines = robotsBody.match(/^Content-Signal:\s*(.+)$/gim) ?? [];
|
|
385
|
+
const directives = {};
|
|
386
|
+
for (const line of contentSignalLines) {
|
|
387
|
+
const m = line.match(/^Content-Signal:\s*(.+)$/i);
|
|
388
|
+
const captured = m?.[1];
|
|
389
|
+
if (!captured)
|
|
390
|
+
continue;
|
|
391
|
+
for (const pair of captured.split(',')) {
|
|
392
|
+
const [k, v] = pair.split('=').map((s) => s.trim().toLowerCase());
|
|
393
|
+
if (k && v)
|
|
394
|
+
directives[k] = v;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
382
397
|
out.signals.robots_analysis = {
|
|
383
398
|
ai_agents_addressed: declared,
|
|
384
399
|
address_count: declared.length,
|
|
385
400
|
blanket_disallow: /User-agent:\s*\*[\s\S]*?Disallow:\s*\//i.test(robotsBody),
|
|
401
|
+
...(Object.keys(directives).length > 0 && { content_signal_directives: directives }),
|
|
386
402
|
};
|
|
387
403
|
}
|
|
388
404
|
const homepageBody = out.signals.homepage?.body;
|
package/dist/score.js
CHANGED
|
@@ -488,22 +488,38 @@ function scoreBotAccessControl(signals) {
|
|
|
488
488
|
let pts = 0;
|
|
489
489
|
const notes = [];
|
|
490
490
|
const robots = signals.signals.robots_analysis;
|
|
491
|
-
if (robots) {
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
491
|
+
if (!robots) {
|
|
492
|
+
notes.push('No robots.txt analysis available');
|
|
493
|
+
return { pts: 0, max, status: statusFor(0, max), notes };
|
|
494
|
+
}
|
|
495
|
+
// 10 pts: Cloudflare Content-Signal directive OR equivalent AI-policy declaration.
|
|
496
|
+
// Content-Signal is the modern machine-readable convention; per-bot rules are the
|
|
497
|
+
// older convention and earn partial credit when Content-Signal is absent.
|
|
498
|
+
const cs = robots.content_signal_directives;
|
|
499
|
+
if (cs && Object.keys(cs).length > 0) {
|
|
500
|
+
pts += 10;
|
|
501
|
+
const fmt = Object.entries(cs)
|
|
502
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
503
|
+
.join(', ');
|
|
504
|
+
notes.push(`Content-Signal directive declared: ${fmt}`);
|
|
505
|
+
}
|
|
506
|
+
else if (robots.address_count >= 3) {
|
|
507
|
+
pts += 5;
|
|
508
|
+
notes.push(`AI policy implicit via ${robots.address_count} per-bot rules — consider adding a Content-Signal directive for machine-readable, future-proof AI policy`);
|
|
504
509
|
}
|
|
505
510
|
else {
|
|
506
|
-
notes.push('No robots.txt
|
|
511
|
+
notes.push('No Content-Signal directive and no per-bot AI policy in robots.txt');
|
|
512
|
+
}
|
|
513
|
+
// 5 pts: per-bot granular posture (names ≥3 AI bots and is not paired with a global blanket disallow).
|
|
514
|
+
if (robots.address_count >= 3 && !robots.blanket_disallow) {
|
|
515
|
+
pts += 5;
|
|
516
|
+
notes.push(`Per-bot granular posture for ${robots.address_count} named bots`);
|
|
517
|
+
}
|
|
518
|
+
else if (robots.address_count >= 3 && robots.blanket_disallow) {
|
|
519
|
+
notes.push(`Names ${robots.address_count} bots but pairs with a global blanket disallow`);
|
|
520
|
+
}
|
|
521
|
+
else if (robots.address_count > 0) {
|
|
522
|
+
notes.push(`Names ${robots.address_count} bot(s) — under threshold (need 3+) for granular-control credit`);
|
|
507
523
|
}
|
|
508
524
|
return { pts: Math.min(pts, max), max, status: statusFor(pts, max), notes };
|
|
509
525
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capitalthought/agentsfirst-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "MCP server that scores websites and codebases against the Agents First framework. Use it to check how agent-ready any product is. https://agentsfirst.dev",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Joshua Baer <josh@capitalfactory.com>",
|