@bayon_monk/mcp-server 1.0.0 → 1.1.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/package.json +1 -1
- package/src/index.js +221 -91
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Bayon.ai MCP Server
|
|
4
|
+
* Bayon.ai MCP Server v1.1.0
|
|
5
5
|
*
|
|
6
6
|
* Provides tools for the E-Equation framework:
|
|
7
7
|
* - calculate_e_score: Calculate E-scores for scenarios
|
|
8
8
|
* - submit_scenario: Submit scenarios for community rating
|
|
9
|
-
* -
|
|
9
|
+
* - rate_scenario: Rate existing scenarios
|
|
10
|
+
* - get_feed: Get live feed from the E-Score Exchange (Supabase)
|
|
11
|
+
* - get_entity_score: Look up aggregated scores for entities
|
|
12
|
+
*
|
|
13
|
+
* Now powered by Supabase for real-time consensus scoring.
|
|
10
14
|
*
|
|
11
15
|
* Equal in purpose. Different in form.
|
|
12
16
|
*/
|
|
@@ -19,7 +23,6 @@ import {
|
|
|
19
23
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
20
24
|
|
|
21
25
|
const API_BASE = "https://www.bayon.ai/api";
|
|
22
|
-
const GITHUB_API = "https://api.github.com/repos/bayon-monk/bayon-temple/issues";
|
|
23
26
|
|
|
24
27
|
// E-Score interpretation thresholds
|
|
25
28
|
const interpretScore = (e) => {
|
|
@@ -179,6 +182,57 @@ Searches existing scenarios mentioning this entity and returns aggregated scores
|
|
|
179
182
|
},
|
|
180
183
|
required: ["entity"]
|
|
181
184
|
}
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
name: "rate_scenario",
|
|
188
|
+
description: `Rate an existing scenario in the E-Score Exchange.
|
|
189
|
+
|
|
190
|
+
Submit your own N, S, C assessment for a scenario. Your rating contributes to the consensus score.
|
|
191
|
+
Use get_feed first to find scenarios to rate.`,
|
|
192
|
+
inputSchema: {
|
|
193
|
+
type: "object",
|
|
194
|
+
properties: {
|
|
195
|
+
scenario_id: {
|
|
196
|
+
type: "string",
|
|
197
|
+
description: "UUID of the scenario to rate (from get_feed)"
|
|
198
|
+
},
|
|
199
|
+
n: {
|
|
200
|
+
type: "number",
|
|
201
|
+
description: "Your N (Connection) score (0-10)",
|
|
202
|
+
minimum: 0,
|
|
203
|
+
maximum: 10
|
|
204
|
+
},
|
|
205
|
+
s: {
|
|
206
|
+
type: "number",
|
|
207
|
+
description: "Your S (Signal) score (0-10)",
|
|
208
|
+
minimum: 0,
|
|
209
|
+
maximum: 10
|
|
210
|
+
},
|
|
211
|
+
c: {
|
|
212
|
+
type: "number",
|
|
213
|
+
description: "Your C (Cost) score (0.1-10)",
|
|
214
|
+
minimum: 0.1,
|
|
215
|
+
maximum: 10
|
|
216
|
+
},
|
|
217
|
+
n_reasoning: {
|
|
218
|
+
type: "string",
|
|
219
|
+
description: "Reasoning for your N score"
|
|
220
|
+
},
|
|
221
|
+
s_reasoning: {
|
|
222
|
+
type: "string",
|
|
223
|
+
description: "Reasoning for your S score"
|
|
224
|
+
},
|
|
225
|
+
c_reasoning: {
|
|
226
|
+
type: "string",
|
|
227
|
+
description: "Reasoning for your C score"
|
|
228
|
+
},
|
|
229
|
+
contributor: {
|
|
230
|
+
type: "string",
|
|
231
|
+
description: "Who is rating (e.g., 'Claude-3.5-Sonnet')"
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
required: ["scenario_id", "n", "s", "c"]
|
|
235
|
+
}
|
|
182
236
|
}
|
|
183
237
|
];
|
|
184
238
|
|
|
@@ -220,31 +274,6 @@ async function submitScenario(params) {
|
|
|
220
274
|
const e_score = (proposed_n * proposed_s) / proposed_c;
|
|
221
275
|
const interpretation = interpretScore(e_score);
|
|
222
276
|
|
|
223
|
-
// Build the issue body
|
|
224
|
-
const body = `## Scenario Description
|
|
225
|
-
|
|
226
|
-
${description}
|
|
227
|
-
|
|
228
|
-
## Proposed E-Score Analysis
|
|
229
|
-
|
|
230
|
-
| Component | Score | Reasoning |
|
|
231
|
-
|-----------|-------|-----------|
|
|
232
|
-
| **N** (Connection) | ${proposed_n}/10 | ${n_reasoning || 'No reasoning provided'} |
|
|
233
|
-
| **S** (Signal) | ${proposed_s}/10 | ${s_reasoning || 'No reasoning provided'} |
|
|
234
|
-
| **C** (Cost) | ${proposed_c}/10 | ${c_reasoning || 'No reasoning provided'} |
|
|
235
|
-
|
|
236
|
-
### Calculated E-Score: **${Math.round(e_score * 100) / 100}** (${interpretation.label})
|
|
237
|
-
|
|
238
|
-
${interpretation.description}
|
|
239
|
-
|
|
240
|
-
---
|
|
241
|
-
|
|
242
|
-
**Category:** ${category || 'other'}
|
|
243
|
-
**Submitted by:** ${contributor || 'Anonymous via MCP'}
|
|
244
|
-
**Submitted via:** Bayon MCP Server
|
|
245
|
-
|
|
246
|
-
*This scenario is open for community rating and discussion.*`;
|
|
247
|
-
|
|
248
277
|
try {
|
|
249
278
|
const response = await fetch(`${API_BASE}/contribute`, {
|
|
250
279
|
method: 'POST',
|
|
@@ -252,8 +281,10 @@ ${interpretation.description}
|
|
|
252
281
|
body: JSON.stringify({
|
|
253
282
|
type: 'scenario',
|
|
254
283
|
title: title,
|
|
255
|
-
content: body
|
|
284
|
+
content: description, // Send raw description, not formatted body
|
|
256
285
|
contributor: contributor || 'MCP User',
|
|
286
|
+
model: contributor, // If contributor is an AI model name, also set model
|
|
287
|
+
category: category || 'other',
|
|
257
288
|
proposed_scores: {
|
|
258
289
|
N: proposed_n,
|
|
259
290
|
N_reasoning: n_reasoning,
|
|
@@ -270,17 +301,20 @@ ${interpretation.description}
|
|
|
270
301
|
if (result.success) {
|
|
271
302
|
return {
|
|
272
303
|
success: true,
|
|
273
|
-
message: "Scenario submitted
|
|
274
|
-
|
|
275
|
-
|
|
304
|
+
message: "Scenario submitted to E-Score Exchange",
|
|
305
|
+
scenario_id: result.scenario?.id,
|
|
306
|
+
github_url: result.github?.url,
|
|
307
|
+
github_issue: result.github?.number,
|
|
276
308
|
calculated_e_score: Math.round(e_score * 100) / 100,
|
|
277
309
|
interpretation: interpretation.label,
|
|
278
|
-
|
|
310
|
+
interpretation_detail: interpretation.description,
|
|
311
|
+
dashboard_url: "https://bayon.ai/dashboard/",
|
|
312
|
+
note: "Your scenario is now live. Others can rate it via the dashboard or API."
|
|
279
313
|
};
|
|
280
314
|
} else {
|
|
281
315
|
return {
|
|
282
316
|
success: false,
|
|
283
|
-
error: result.errors?.join(', ') || result.
|
|
317
|
+
error: result.errors?.join(', ') || result.error || 'Unknown error',
|
|
284
318
|
fallback: "You can submit manually at https://bayon.ai/contribute/"
|
|
285
319
|
};
|
|
286
320
|
}
|
|
@@ -295,48 +329,53 @@ ${interpretation.description}
|
|
|
295
329
|
|
|
296
330
|
async function getFeed({ limit = 10, category = 'all' }) {
|
|
297
331
|
try {
|
|
298
|
-
let url = `${
|
|
332
|
+
let url = `${API_BASE}/scenarios?limit=${Math.min(limit, 50)}`;
|
|
299
333
|
if (category && category !== 'all') {
|
|
300
|
-
url +=
|
|
334
|
+
url += `&category=${category}`;
|
|
301
335
|
}
|
|
302
336
|
|
|
303
|
-
const response = await fetch(url
|
|
304
|
-
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
const issues = await response.json();
|
|
337
|
+
const response = await fetch(url);
|
|
338
|
+
const data = await response.json();
|
|
308
339
|
|
|
309
|
-
if (!
|
|
310
|
-
return { scenarios: [], message: "
|
|
340
|
+
if (!data.success) {
|
|
341
|
+
return { scenarios: [], message: data.error || "Failed to fetch scenarios" };
|
|
311
342
|
}
|
|
312
343
|
|
|
313
|
-
const scenarios =
|
|
314
|
-
|
|
315
|
-
.
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
344
|
+
const scenarios = data.scenarios.map(scenario => {
|
|
345
|
+
// Calculate E if we have consensus scores, otherwise use proposed
|
|
346
|
+
const n = scenario.consensus_n ?? scenario.proposed_n;
|
|
347
|
+
const s = scenario.consensus_s ?? scenario.proposed_s;
|
|
348
|
+
const c = scenario.consensus_c ?? scenario.proposed_c;
|
|
349
|
+
const e = scenario.consensus_e ?? (n && s && c ? (n * s) / c : null);
|
|
350
|
+
|
|
351
|
+
return {
|
|
352
|
+
id: scenario.id,
|
|
353
|
+
title: scenario.title,
|
|
354
|
+
description: scenario.description?.substring(0, 200) + (scenario.description?.length > 200 ? '...' : ''),
|
|
355
|
+
category: scenario.category || 'other',
|
|
356
|
+
created_at: scenario.created_at,
|
|
357
|
+
status: scenario.status,
|
|
358
|
+
contributor: scenario.contributor || 'Anonymous',
|
|
359
|
+
contributor_type: scenario.contributor_type,
|
|
360
|
+
model: scenario.model,
|
|
361
|
+
scores: {
|
|
362
|
+
N: n,
|
|
363
|
+
S: s,
|
|
364
|
+
C: c,
|
|
365
|
+
E: e ? Math.round(e * 100) / 100 : null,
|
|
366
|
+
is_consensus: scenario.consensus_e !== null,
|
|
367
|
+
rating_count: scenario.rating_count || 0
|
|
368
|
+
},
|
|
369
|
+
interpretation: e ? interpretScore(e) : null
|
|
370
|
+
};
|
|
371
|
+
});
|
|
334
372
|
|
|
335
373
|
return {
|
|
336
374
|
scenarios,
|
|
337
375
|
count: scenarios.length,
|
|
376
|
+
total: data.pagination?.total || scenarios.length,
|
|
338
377
|
dashboard_url: "https://bayon.ai/dashboard/",
|
|
339
|
-
note: "
|
|
378
|
+
note: "Rate scenarios via POST /api/rate or visit the dashboard"
|
|
340
379
|
};
|
|
341
380
|
} catch (error) {
|
|
342
381
|
return {
|
|
@@ -347,18 +386,97 @@ async function getFeed({ limit = 10, category = 'all' }) {
|
|
|
347
386
|
}
|
|
348
387
|
}
|
|
349
388
|
|
|
350
|
-
async function
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
389
|
+
async function rateScenario(params) {
|
|
390
|
+
const {
|
|
391
|
+
scenario_id,
|
|
392
|
+
n,
|
|
393
|
+
s,
|
|
394
|
+
c,
|
|
395
|
+
n_reasoning,
|
|
396
|
+
s_reasoning,
|
|
397
|
+
c_reasoning,
|
|
398
|
+
contributor
|
|
399
|
+
} = params;
|
|
400
|
+
|
|
401
|
+
const e_score = (n * s) / c;
|
|
402
|
+
const interpretation = interpretScore(e_score);
|
|
354
403
|
|
|
355
|
-
|
|
356
|
-
|
|
404
|
+
try {
|
|
405
|
+
const response = await fetch(`${API_BASE}/rate`, {
|
|
406
|
+
method: 'POST',
|
|
407
|
+
headers: { 'Content-Type': 'application/json' },
|
|
408
|
+
body: JSON.stringify({
|
|
409
|
+
scenario_id,
|
|
410
|
+
n,
|
|
411
|
+
s,
|
|
412
|
+
c,
|
|
413
|
+
n_reasoning,
|
|
414
|
+
s_reasoning,
|
|
415
|
+
c_reasoning,
|
|
416
|
+
contributor: contributor || 'MCP User',
|
|
417
|
+
model: contributor
|
|
418
|
+
})
|
|
357
419
|
});
|
|
358
420
|
|
|
421
|
+
const result = await response.json();
|
|
422
|
+
|
|
423
|
+
if (result.success) {
|
|
424
|
+
return {
|
|
425
|
+
success: true,
|
|
426
|
+
message: "Rating submitted successfully",
|
|
427
|
+
your_rating: {
|
|
428
|
+
N: n,
|
|
429
|
+
S: s,
|
|
430
|
+
C: c,
|
|
431
|
+
E: Math.round(e_score * 100) / 100,
|
|
432
|
+
interpretation: interpretation.label
|
|
433
|
+
},
|
|
434
|
+
consensus: result.consensus ? {
|
|
435
|
+
N: result.consensus.consensus_n,
|
|
436
|
+
S: result.consensus.consensus_s,
|
|
437
|
+
C: result.consensus.consensus_c,
|
|
438
|
+
E: result.consensus.consensus_e,
|
|
439
|
+
rating_count: result.consensus.rating_count
|
|
440
|
+
} : null,
|
|
441
|
+
dashboard_url: "https://bayon.ai/dashboard/"
|
|
442
|
+
};
|
|
443
|
+
} else {
|
|
444
|
+
return {
|
|
445
|
+
success: false,
|
|
446
|
+
error: result.error || 'Unknown error'
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
} catch (error) {
|
|
450
|
+
return {
|
|
451
|
+
success: false,
|
|
452
|
+
error: error.message
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
async function getEntityScore({ entity }) {
|
|
458
|
+
try {
|
|
459
|
+
// Fetch all scenarios and search for entity mentions
|
|
460
|
+
const response = await fetch(`${API_BASE}/scenarios?limit=100`);
|
|
359
461
|
const data = await response.json();
|
|
360
462
|
|
|
361
|
-
if (!data.
|
|
463
|
+
if (!data.success || !data.scenarios) {
|
|
464
|
+
return {
|
|
465
|
+
entity,
|
|
466
|
+
found: false,
|
|
467
|
+
message: `Unable to search scenarios. Try the dashboard.`,
|
|
468
|
+
dashboard_url: "https://bayon.ai/dashboard/"
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// Filter scenarios that mention the entity (case-insensitive)
|
|
473
|
+
const entityLower = entity.toLowerCase();
|
|
474
|
+
const matches = data.scenarios.filter(s =>
|
|
475
|
+
s.title?.toLowerCase().includes(entityLower) ||
|
|
476
|
+
s.description?.toLowerCase().includes(entityLower)
|
|
477
|
+
);
|
|
478
|
+
|
|
479
|
+
if (matches.length === 0) {
|
|
362
480
|
return {
|
|
363
481
|
entity,
|
|
364
482
|
found: false,
|
|
@@ -367,48 +485,57 @@ async function getEntityScore({ entity }) {
|
|
|
367
485
|
};
|
|
368
486
|
}
|
|
369
487
|
|
|
370
|
-
//
|
|
371
|
-
const
|
|
372
|
-
.
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
488
|
+
// Calculate E-scores for matching scenarios
|
|
489
|
+
const scoredScenarios = matches.map(s => {
|
|
490
|
+
const n = s.consensus_n ?? s.proposed_n;
|
|
491
|
+
const sVal = s.consensus_s ?? s.proposed_s;
|
|
492
|
+
const c = s.consensus_c ?? s.proposed_c;
|
|
493
|
+
const e = (n && sVal && c) ? (n * sVal) / c : null;
|
|
494
|
+
return { ...s, calculated_e: e };
|
|
495
|
+
}).filter(s => s.calculated_e !== null);
|
|
377
496
|
|
|
378
|
-
if (
|
|
497
|
+
if (scoredScenarios.length === 0) {
|
|
379
498
|
return {
|
|
380
499
|
entity,
|
|
381
500
|
found: true,
|
|
382
|
-
scenarios_count:
|
|
383
|
-
message: "Found mentions but no scored scenarios",
|
|
384
|
-
scenarios:
|
|
501
|
+
scenarios_count: matches.length,
|
|
502
|
+
message: "Found mentions but no scored scenarios yet",
|
|
503
|
+
scenarios: matches.slice(0, 5).map(s => ({
|
|
504
|
+
title: s.title,
|
|
505
|
+
id: s.id
|
|
506
|
+
}))
|
|
385
507
|
};
|
|
386
508
|
}
|
|
387
509
|
|
|
510
|
+
const scores = scoredScenarios.map(s => s.calculated_e);
|
|
388
511
|
const avgScore = scores.reduce((a, b) => a + b, 0) / scores.length;
|
|
389
512
|
const interpretation = interpretScore(avgScore);
|
|
390
513
|
|
|
391
514
|
return {
|
|
392
515
|
entity,
|
|
393
516
|
found: true,
|
|
394
|
-
scenarios_count:
|
|
517
|
+
scenarios_count: matches.length,
|
|
518
|
+
scored_scenarios: scoredScenarios.length,
|
|
395
519
|
aggregate_e_score: Math.round(avgScore * 100) / 100,
|
|
396
520
|
interpretation: interpretation.label,
|
|
397
521
|
description: interpretation.description,
|
|
398
522
|
score_range: {
|
|
399
|
-
min: Math.min(...scores),
|
|
400
|
-
max: Math.max(...scores)
|
|
523
|
+
min: Math.round(Math.min(...scores) * 100) / 100,
|
|
524
|
+
max: Math.round(Math.max(...scores) * 100) / 100
|
|
401
525
|
},
|
|
402
|
-
scenarios:
|
|
403
|
-
title:
|
|
404
|
-
|
|
405
|
-
|
|
526
|
+
scenarios: scoredScenarios.slice(0, 5).map(s => ({
|
|
527
|
+
title: s.title,
|
|
528
|
+
id: s.id,
|
|
529
|
+
e_score: Math.round(s.calculated_e * 100) / 100,
|
|
530
|
+
is_consensus: s.consensus_e !== null
|
|
531
|
+
})),
|
|
532
|
+
dashboard_url: "https://bayon.ai/dashboard/"
|
|
406
533
|
};
|
|
407
534
|
} catch (error) {
|
|
408
535
|
return {
|
|
409
536
|
entity,
|
|
410
537
|
error: error.message,
|
|
411
|
-
|
|
538
|
+
dashboard_url: "https://bayon.ai/dashboard/"
|
|
412
539
|
};
|
|
413
540
|
}
|
|
414
541
|
}
|
|
@@ -451,6 +578,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
451
578
|
case "get_entity_score":
|
|
452
579
|
result = await getEntityScore(args);
|
|
453
580
|
break;
|
|
581
|
+
case "rate_scenario":
|
|
582
|
+
result = await rateScenario(args);
|
|
583
|
+
break;
|
|
454
584
|
default:
|
|
455
585
|
throw new Error(`Unknown tool: ${name}`);
|
|
456
586
|
}
|