legends-mcp 1.2.0 → 1.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/index.js CHANGED
@@ -7,7 +7,7 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
7
7
  import { ListToolsRequestSchema, CallToolRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
8
8
  import { loadLegends, getAllLegends, getLegendById, getLegendCount } from './legends/loader.js';
9
9
  import { formatLegendMarkdown } from './legends/prompt-builder.js';
10
- import { allTools, listLegends, formatLegendsMarkdown, summonLegend, formatSummonedLegend, getLegendContext, getLegendInsight, searchLegends, formatSearchResults, } from './tools/index.js';
10
+ import { allTools, listLegends, formatLegendsMarkdown, summonLegend, formatSummonedLegend, getLegendContext, getLegendInsight, searchLegends, formatSearchResults, partyMode, formatPartyMode, autoMatch, formatAutoMatch, } from './tools/index.js';
11
11
  // Load legends at startup
12
12
  const legends = loadLegends();
13
13
  console.error(`[legends-mcp] Loaded ${getLegendCount()} legends`);
@@ -15,7 +15,7 @@ console.error(`[legends-mcp] No API key required - Claude does the roleplay!`);
15
15
  // Create MCP server
16
16
  const server = new Server({
17
17
  name: 'legends-mcp',
18
- version: '1.1.3',
18
+ version: '1.3.0', // Security release - sync with package.json
19
19
  }, {
20
20
  capabilities: {
21
21
  tools: {},
@@ -130,6 +130,60 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
130
130
  content: [{ type: 'text', text: formatted }],
131
131
  };
132
132
  }
133
+ case 'party_mode': {
134
+ const input = args;
135
+ if (!input.question) {
136
+ return {
137
+ content: [{ type: 'text', text: 'Error: question parameter is required' }],
138
+ isError: true,
139
+ };
140
+ }
141
+ try {
142
+ const result = partyMode(input);
143
+ const formatted = formatPartyMode(result);
144
+ return {
145
+ content: [{ type: 'text', text: formatted }],
146
+ };
147
+ }
148
+ catch (error) {
149
+ return {
150
+ content: [
151
+ {
152
+ type: 'text',
153
+ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,
154
+ },
155
+ ],
156
+ isError: true,
157
+ };
158
+ }
159
+ }
160
+ case 'auto_match': {
161
+ const input = args;
162
+ if (!input.question) {
163
+ return {
164
+ content: [{ type: 'text', text: 'Error: question parameter is required' }],
165
+ isError: true,
166
+ };
167
+ }
168
+ try {
169
+ const result = autoMatch(input);
170
+ const formatted = formatAutoMatch(result);
171
+ return {
172
+ content: [{ type: 'text', text: formatted }],
173
+ };
174
+ }
175
+ catch (error) {
176
+ return {
177
+ content: [
178
+ {
179
+ type: 'text',
180
+ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,
181
+ },
182
+ ],
183
+ isError: true,
184
+ };
185
+ }
186
+ }
133
187
  default:
134
188
  return {
135
189
  content: [{ type: 'text', text: `Unknown tool: ${name}` }],
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -17,10 +17,15 @@ export declare function getLegendById(id: string): LegendSkill | undefined;
17
17
  export declare function getLegendSummaries(): LegendSummary[];
18
18
  /**
19
19
  * Search legends by query
20
+ * SECURITY: Uses safe string handling to prevent crashes from malformed data
20
21
  */
21
22
  export declare function searchLegends(query: string): LegendSkill[];
22
23
  /**
23
24
  * Get legend count
24
25
  */
25
26
  export declare function getLegendCount(): number;
27
+ /**
28
+ * Clear the legends cache (for testing)
29
+ */
30
+ export declare function clearLegendsCache(): void;
26
31
  //# sourceMappingURL=loader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/legends/loader.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA4B9D;;GAEG;AACH,wBAAgB,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAgCtD;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,WAAW,EAAE,CAG7C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAGjE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,aAAa,EAAE,CASpD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE,CAU1D;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/legends/loader.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAyF9D;;GAEG;AACH,wBAAgB,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CA8CtD;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,WAAW,EAAE,CAG7C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAGjE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,aAAa,EAAE,CASpD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE,CAoB1D;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAExC"}
@@ -3,26 +3,78 @@ import fs from 'fs';
3
3
  import path from 'path';
4
4
  import { fileURLToPath } from 'url';
5
5
  import yaml from 'yaml';
6
+ import { safeString } from '../utils/sanitize.js';
6
7
  const __filename = fileURLToPath(import.meta.url);
7
8
  const __dirname = path.dirname(__filename);
8
9
  // Cache for loaded legends
9
10
  let legendsCache = null;
11
+ // Maximum file size to prevent DoS (10MB)
12
+ const MAX_FILE_SIZE = 10 * 1024 * 1024;
13
+ // Maximum number of legends to load
14
+ const MAX_LEGENDS = 500;
10
15
  /**
11
16
  * Get the path to the bundled legends directory
17
+ * SECURITY: Only load from package directory unless explicitly allowed
12
18
  */
13
19
  function getLegendsDir() {
14
- // In dist/legends/ or ../legends/ relative to the compiled file
20
+ // Check for explicit custom directory (opt-in only)
21
+ const customDir = process.env.LEGENDS_MCP_LEGENDS_DIR;
22
+ if (customDir) {
23
+ if (fs.existsSync(customDir)) {
24
+ console.error(`[legends-mcp] Using custom legends directory: ${customDir}`);
25
+ return customDir;
26
+ }
27
+ throw new Error(`Custom legends directory not found: ${customDir}`);
28
+ }
29
+ // SECURITY: Only load from package directory (relative to compiled file)
30
+ // Do NOT fall back to process.cwd() to prevent loading untrusted legends
15
31
  const possiblePaths = [
16
32
  path.join(__dirname, '..', '..', 'legends'),
17
33
  path.join(__dirname, '..', 'legends'),
18
- path.join(process.cwd(), 'legends'),
19
34
  ];
35
+ // Only allow CWD if explicitly opted in (for development)
36
+ if (process.env.LEGENDS_MCP_ALLOW_CWD === '1') {
37
+ possiblePaths.push(path.join(process.cwd(), 'legends'));
38
+ console.error('[legends-mcp] WARNING: CWD loading enabled - only use in trusted environments');
39
+ }
20
40
  for (const p of possiblePaths) {
21
41
  if (fs.existsSync(p)) {
22
42
  return p;
23
43
  }
24
44
  }
25
- throw new Error('Could not find legends directory. Ensure the package is properly installed.');
45
+ throw new Error('Could not find legends directory. Ensure the package is properly installed. ' +
46
+ 'For custom directories, set LEGENDS_MCP_LEGENDS_DIR environment variable.');
47
+ }
48
+ /**
49
+ * Validate a legend file before loading
50
+ */
51
+ function validateLegendFile(filePath) {
52
+ try {
53
+ const stats = fs.statSync(filePath);
54
+ if (stats.size > MAX_FILE_SIZE) {
55
+ console.error(`[legends-mcp] Skipping oversized file: ${filePath} (${stats.size} bytes)`);
56
+ return false;
57
+ }
58
+ return true;
59
+ }
60
+ catch {
61
+ return false;
62
+ }
63
+ }
64
+ /**
65
+ * Validate required fields in a legend
66
+ */
67
+ function validateLegend(data, filePath) {
68
+ if (!data || typeof data !== 'object') {
69
+ console.error(`[legends-mcp] Invalid legend data in ${filePath}`);
70
+ return false;
71
+ }
72
+ // Must have at least a name or id
73
+ if (!data.name && !data.id) {
74
+ console.error(`[legends-mcp] Legend missing name/id in ${filePath}`);
75
+ return false;
76
+ }
77
+ return true;
26
78
  }
27
79
  /**
28
80
  * Load all legends from YAML files
@@ -34,24 +86,40 @@ export function loadLegends() {
34
86
  const legendsDir = getLegendsDir();
35
87
  const legends = new Map();
36
88
  const entries = fs.readdirSync(legendsDir, { withFileTypes: true });
89
+ let loadedCount = 0;
37
90
  for (const entry of entries) {
38
91
  if (!entry.isDirectory())
39
92
  continue;
93
+ if (loadedCount >= MAX_LEGENDS) {
94
+ console.error(`[legends-mcp] Maximum legends limit reached (${MAX_LEGENDS})`);
95
+ break;
96
+ }
40
97
  const skillPath = path.join(legendsDir, entry.name, 'skill.yaml');
41
98
  if (!fs.existsSync(skillPath))
42
99
  continue;
100
+ // Validate file before loading
101
+ if (!validateLegendFile(skillPath))
102
+ continue;
43
103
  try {
44
104
  const content = fs.readFileSync(skillPath, 'utf-8');
45
105
  const data = yaml.parse(content);
46
- // Ensure required fields
106
+ // Validate legend data
107
+ if (!validateLegend(data, skillPath))
108
+ continue;
109
+ // Ensure required fields with safe defaults
47
110
  if (!data.id)
48
111
  data.id = entry.name;
49
112
  if (!data.category)
50
113
  data.category = 'legends';
114
+ if (!data.name)
115
+ data.name = entry.name;
116
+ if (!data.description)
117
+ data.description = '';
51
118
  legends.set(data.id, data);
119
+ loadedCount++;
52
120
  }
53
121
  catch (error) {
54
- console.error(`[vibey-legends] Error loading ${skillPath}:`, error);
122
+ console.error(`[legends-mcp] Error loading ${skillPath}:`, error);
55
123
  }
56
124
  }
57
125
  legendsCache = legends;
@@ -78,22 +146,32 @@ export function getLegendSummaries() {
78
146
  const legends = getAllLegends();
79
147
  return legends.map(l => ({
80
148
  id: l.id,
81
- name: l.name,
82
- description: l.description,
149
+ name: safeString(l.name, l.id),
150
+ description: safeString(l.description, ''),
83
151
  expertise: l.owns || [],
84
152
  tags: l.tags || [],
85
153
  }));
86
154
  }
87
155
  /**
88
156
  * Search legends by query
157
+ * SECURITY: Uses safe string handling to prevent crashes from malformed data
89
158
  */
90
159
  export function searchLegends(query) {
91
160
  const legends = getAllLegends();
92
- const q = query.toLowerCase();
93
- return legends.filter(l => l.name.toLowerCase().includes(q) ||
94
- l.description.toLowerCase().includes(q) ||
95
- l.tags?.some(t => t.toLowerCase().includes(q)) ||
96
- l.owns?.some(o => o.toLowerCase().includes(q)));
161
+ const q = safeString(query, '').toLowerCase();
162
+ if (!q)
163
+ return [];
164
+ return legends.filter(l => {
165
+ // Safe string comparisons with fallbacks
166
+ const name = safeString(l.name, '').toLowerCase();
167
+ const description = safeString(l.description, '').toLowerCase();
168
+ const tags = (l.tags || []).map(t => safeString(t, '').toLowerCase());
169
+ const owns = (l.owns || []).map(o => safeString(o, '').toLowerCase());
170
+ return (name.includes(q) ||
171
+ description.includes(q) ||
172
+ tags.some(t => t.includes(q)) ||
173
+ owns.some(o => o.includes(q)));
174
+ });
97
175
  }
98
176
  /**
99
177
  * Get legend count
@@ -101,4 +179,10 @@ export function searchLegends(query) {
101
179
  export function getLegendCount() {
102
180
  return loadLegends().size;
103
181
  }
182
+ /**
183
+ * Clear the legends cache (for testing)
184
+ */
185
+ export function clearLegendsCache() {
186
+ legendsCache = null;
187
+ }
104
188
  //# sourceMappingURL=loader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/legends/loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/legends/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ export interface AutoMatchInput {
2
+ question: string;
3
+ max_matches?: number;
4
+ include_prompts?: boolean;
5
+ }
6
+ export interface MatchedLegend {
7
+ legend_id: string;
8
+ name: string;
9
+ relevance_reason: string;
10
+ expertise_match: string[];
11
+ key_insight: string;
12
+ system_prompt?: string;
13
+ }
14
+ export interface AutoMatchResponse {
15
+ question: string;
16
+ matches: MatchedLegend[];
17
+ suggested_approach: string;
18
+ }
19
+ /**
20
+ * Auto-match legends to a question
21
+ */
22
+ export declare function autoMatch(input: AutoMatchInput): AutoMatchResponse;
23
+ /**
24
+ * Format auto-match response for display
25
+ */
26
+ export declare function formatAutoMatch(response: AutoMatchResponse): string;
27
+ export declare const autoMatchTool: {
28
+ name: string;
29
+ description: string;
30
+ inputSchema: {
31
+ type: "object";
32
+ properties: {
33
+ question: {
34
+ type: string;
35
+ description: string;
36
+ };
37
+ max_matches: {
38
+ type: string;
39
+ description: string;
40
+ };
41
+ include_prompts: {
42
+ type: string;
43
+ description: string;
44
+ };
45
+ };
46
+ required: string[];
47
+ };
48
+ };
49
+ //# sourceMappingURL=auto-match.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-match.d.ts","sourceRoot":"","sources":["../../src/tools/auto-match.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAmID;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,iBAAiB,CAyClE;AAgBD;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,CA8CnE;AAGD,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;CA4CzB,CAAC"}
@@ -0,0 +1,264 @@
1
+ // MCP Tool: auto_match
2
+ // Automatically matches and provides context from relevant legends based on user's question
3
+ // This is the "auto proc" feature - proactively giving relevant legend perspectives
4
+ import { getLegendById } from '../legends/loader.js';
5
+ import { buildLegendSystemPrompt } from '../legends/prompt-builder.js';
6
+ import { sanitizeContext, escapeBackticks, safeString } from '../utils/sanitize.js';
7
+ // Keywords to legend expertise mapping
8
+ const EXPERTISE_KEYWORDS = {
9
+ // Crypto & Web3
10
+ crypto: { legends: ['cz-binance', 'vitalik-buterin', 'balaji-srinivasan'], expertise: 'cryptocurrency' },
11
+ bitcoin: { legends: ['michael-saylor', 'jack-dorsey', 'balaji-srinivasan'], expertise: 'Bitcoin' },
12
+ ethereum: { legends: ['vitalik-buterin'], expertise: 'Ethereum' },
13
+ solana: { legends: ['anatoly-yakovenko', 'mert-mumtaz'], expertise: 'Solana' },
14
+ defi: { legends: ['hayden-adams', 'andre-cronje', 'vitalik-buterin'], expertise: 'DeFi' },
15
+ nft: { legends: ['gary-vaynerchuk', 'cz-binance'], expertise: 'NFTs' },
16
+ blockchain: { legends: ['vitalik-buterin', 'balaji-srinivasan', 'cz-binance'], expertise: 'blockchain' },
17
+ web3: { legends: ['balaji-srinivasan', 'chris-dixon'], expertise: 'Web3' },
18
+ exchange: { legends: ['cz-binance', 'brian-armstrong'], expertise: 'crypto exchanges' },
19
+ // Investing
20
+ invest: { legends: ['warren-buffett', 'charlie-munger', 'ray-dalio'], expertise: 'investing' },
21
+ stock: { legends: ['warren-buffett', 'peter-lynch', 'cathie-wood'], expertise: 'stock investing' },
22
+ value: { legends: ['warren-buffett', 'charlie-munger', 'benjamin-graham'], expertise: 'value investing' },
23
+ growth: { legends: ['cathie-wood', 'bill-gurley'], expertise: 'growth investing' },
24
+ portfolio: { legends: ['ray-dalio', 'howard-marks'], expertise: 'portfolio management' },
25
+ risk: { legends: ['ray-dalio', 'howard-marks', 'nassim-taleb'], expertise: 'risk management' },
26
+ venture: { legends: ['marc-andreessen', 'peter-thiel', 'bill-gurley'], expertise: 'venture capital' },
27
+ // Startups
28
+ startup: { legends: ['paul-graham', 'sam-altman', 'peter-thiel'], expertise: 'startups' },
29
+ founder: { legends: ['elon-musk', 'jeff-bezos', 'brian-chesky'], expertise: 'founding companies' },
30
+ fundrais: { legends: ['paul-graham', 'marc-andreessen', 'peter-thiel'], expertise: 'fundraising' },
31
+ pitch: { legends: ['paul-graham', 'guy-kawasaki'], expertise: 'pitching' },
32
+ scale: { legends: ['reid-hoffman', 'patrick-collison', 'tobi-lutke'], expertise: 'scaling' },
33
+ yc: { legends: ['paul-graham', 'sam-altman'], expertise: 'Y Combinator' },
34
+ accelerat: { legends: ['paul-graham', 'sam-altman'], expertise: 'accelerators' },
35
+ // Tech & Product
36
+ product: { legends: ['steve-jobs', 'brian-chesky', 'tobi-lutke'], expertise: 'product development' },
37
+ design: { legends: ['steve-jobs', 'jony-ive', 'brian-chesky'], expertise: 'design' },
38
+ engineer: { legends: ['elon-musk', 'jensen-huang', 'patrick-collison'], expertise: 'engineering' },
39
+ ai: { legends: ['sam-altman', 'demis-hassabis', 'jensen-huang'], expertise: 'artificial intelligence' },
40
+ machine: { legends: ['demis-hassabis', 'andrej-karpathy'], expertise: 'machine learning' },
41
+ gpu: { legends: ['jensen-huang'], expertise: 'GPUs' },
42
+ software: { legends: ['bill-gates', 'satya-nadella', 'marc-andreessen'], expertise: 'software' },
43
+ hardware: { legends: ['steve-jobs', 'jensen-huang', 'elon-musk'], expertise: 'hardware' },
44
+ // Leadership & Management
45
+ lead: { legends: ['satya-nadella', 'jeff-bezos', 'reed-hastings'], expertise: 'leadership' },
46
+ manage: { legends: ['andy-grove', 'ben-horowitz', 'reed-hastings'], expertise: 'management' },
47
+ culture: { legends: ['reed-hastings', 'brian-chesky', 'tobi-lutke'], expertise: 'company culture' },
48
+ team: { legends: ['ben-horowitz', 'patrick-lencioni', 'reed-hastings'], expertise: 'team building' },
49
+ hire: { legends: ['paul-graham', 'ben-horowitz', 'reid-hoffman'], expertise: 'hiring' },
50
+ // Marketing & Growth
51
+ market: { legends: ['seth-godin', 'gary-vaynerchuk'], expertise: 'marketing' },
52
+ brand: { legends: ['gary-vaynerchuk', 'seth-godin', 'steve-jobs'], expertise: 'branding' },
53
+ social: { legends: ['gary-vaynerchuk', 'jack-dorsey'], expertise: 'social media' },
54
+ content: { legends: ['gary-vaynerchuk', 'seth-godin'], expertise: 'content marketing' },
55
+ // Personal Development
56
+ productiv: { legends: ['tim-ferriss', 'naval-ravikant'], expertise: 'productivity' },
57
+ wealth: { legends: ['naval-ravikant', 'warren-buffett', 'charlie-munger'], expertise: 'wealth building' },
58
+ success: { legends: ['naval-ravikant', 'tim-ferriss'], expertise: 'success principles' },
59
+ happiness: { legends: ['naval-ravikant', 'tim-ferriss'], expertise: 'happiness' },
60
+ philosophy: { legends: ['naval-ravikant', 'charlie-munger', 'ray-dalio'], expertise: 'philosophy' },
61
+ decision: { legends: ['charlie-munger', 'ray-dalio', 'jeff-bezos'], expertise: 'decision making' },
62
+ mental: { legends: ['charlie-munger', 'naval-ravikant'], expertise: 'mental models' },
63
+ };
64
+ /**
65
+ * Find matching legends based on question content
66
+ */
67
+ function findMatches(question, maxMatches) {
68
+ const q = question.toLowerCase();
69
+ const matchScores = new Map();
70
+ // Score legends based on keyword matches
71
+ for (const [keyword, data] of Object.entries(EXPERTISE_KEYWORDS)) {
72
+ if (q.includes(keyword)) {
73
+ for (const legendId of data.legends) {
74
+ const current = matchScores.get(legendId) || { score: 0, reasons: [], expertise: [] };
75
+ current.score += 1;
76
+ if (!current.reasons.includes(data.expertise)) {
77
+ current.reasons.push(data.expertise);
78
+ }
79
+ current.expertise.push(data.expertise);
80
+ matchScores.set(legendId, current);
81
+ }
82
+ }
83
+ }
84
+ // If no keyword matches, use default diverse panel
85
+ if (matchScores.size === 0) {
86
+ return [
87
+ { legendId: 'naval-ravikant', reason: 'general wisdom and mental models', matchedExpertise: ['general wisdom'] },
88
+ { legendId: 'paul-graham', reason: 'startup and business insights', matchedExpertise: ['startups'] },
89
+ { legendId: 'charlie-munger', reason: 'decision making and thinking', matchedExpertise: ['mental models'] },
90
+ ].slice(0, maxMatches);
91
+ }
92
+ // Sort by score and return top matches
93
+ const sorted = Array.from(matchScores.entries())
94
+ .sort((a, b) => b[1].score - a[1].score)
95
+ .slice(0, maxMatches);
96
+ return sorted.map(([legendId, data]) => ({
97
+ legendId,
98
+ reason: data.reasons.join(', '),
99
+ matchedExpertise: [...new Set(data.expertise)],
100
+ }));
101
+ }
102
+ /**
103
+ * Extract a key insight from a legend's principles
104
+ */
105
+ function extractKeyInsight(legend) {
106
+ // Try to get a relevant principle or pattern
107
+ if (legend.principles?.length) {
108
+ return safeString(legend.principles[0], '');
109
+ }
110
+ if (legend.patterns?.length) {
111
+ const pattern = legend.patterns[0];
112
+ if (typeof pattern === 'object' && pattern.name) {
113
+ return `${pattern.name}: ${safeString(pattern.description || '', '')}`;
114
+ }
115
+ }
116
+ if (legend.anti_patterns?.length) {
117
+ const ap = legend.anti_patterns[0];
118
+ const apText = typeof ap === 'object' ? ap.pattern : String(ap);
119
+ return `Avoids: ${safeString(apText, '')}`;
120
+ }
121
+ return `${legend.name}'s perspective on ${(legend.owns || ['business']).slice(0, 2).join(' and ')}`;
122
+ }
123
+ /**
124
+ * Auto-match legends to a question
125
+ */
126
+ export function autoMatch(input) {
127
+ const { sanitized: question } = sanitizeContext(input.question);
128
+ const maxMatches = Math.min(input.max_matches || 2, 3);
129
+ const includePrompts = input.include_prompts || false;
130
+ // Find matching legends
131
+ const matches = findMatches(question, maxMatches);
132
+ // Build response
133
+ const matchedLegends = matches.map(match => {
134
+ const legend = getLegendById(match.legendId);
135
+ if (!legend)
136
+ return null;
137
+ const result = {
138
+ legend_id: legend.id,
139
+ name: legend.name,
140
+ relevance_reason: match.reason,
141
+ expertise_match: match.matchedExpertise,
142
+ key_insight: extractKeyInsight(legend),
143
+ };
144
+ if (includePrompts) {
145
+ result.system_prompt = buildLegendSystemPrompt(legend);
146
+ }
147
+ return result;
148
+ }).filter((m) => m !== null);
149
+ if (matchedLegends.length === 0) {
150
+ throw new Error('No matching legends found. Try rephrasing your question.');
151
+ }
152
+ // Generate suggested approach
153
+ const legendNames = matchedLegends.map(m => m.name);
154
+ const suggestedApproach = generateApproach(question, matchedLegends);
155
+ return {
156
+ question: escapeBackticks(question),
157
+ matches: matchedLegends,
158
+ suggested_approach: suggestedApproach,
159
+ };
160
+ }
161
+ /**
162
+ * Generate a suggested approach based on matched legends
163
+ */
164
+ function generateApproach(question, matches) {
165
+ if (matches.length === 1) {
166
+ return `Consider ${matches[0].name}'s perspective on ${matches[0].expertise_match.join(', ')}. Their insight: "${matches[0].key_insight}"`;
167
+ }
168
+ const names = matches.map(m => m.name).join(' and ');
169
+ const expertise = [...new Set(matches.flatMap(m => m.expertise_match))].join(', ');
170
+ return `Combine perspectives from ${names} (expertise: ${expertise}). Each brings unique frameworks - use \`summon_legend\` or \`party_mode\` to get their full responses.`;
171
+ }
172
+ /**
173
+ * Format auto-match response for display
174
+ */
175
+ export function formatAutoMatch(response) {
176
+ const lines = [
177
+ '# Auto-Matched Legends',
178
+ '',
179
+ `**Your Question:** ${response.question}`,
180
+ '',
181
+ '---',
182
+ '',
183
+ '## Best Matches',
184
+ '',
185
+ ];
186
+ response.matches.forEach((match, i) => {
187
+ lines.push(`### ${i + 1}. ${match.name}`);
188
+ lines.push(`- **Why matched:** ${match.relevance_reason}`);
189
+ lines.push(`- **Expertise:** ${match.expertise_match.join(', ')}`);
190
+ lines.push(`- **Key insight:** "${escapeBackticks(match.key_insight)}"`);
191
+ if (match.system_prompt) {
192
+ lines.push('');
193
+ lines.push('<details>');
194
+ lines.push('<summary>Full System Prompt</summary>');
195
+ lines.push('');
196
+ lines.push('```');
197
+ lines.push(escapeBackticks(match.system_prompt));
198
+ lines.push('```');
199
+ lines.push('</details>');
200
+ }
201
+ lines.push('');
202
+ });
203
+ lines.push('---');
204
+ lines.push('');
205
+ lines.push('## Suggested Approach');
206
+ lines.push('');
207
+ lines.push(response.suggested_approach);
208
+ lines.push('');
209
+ lines.push('---');
210
+ lines.push('');
211
+ lines.push('**Next Steps:**');
212
+ lines.push('- Use `summon_legend` to get advice from a specific legend');
213
+ lines.push('- Use `party_mode` to have all matched legends discuss together');
214
+ lines.push('');
215
+ lines.push('*DISCLAIMER: AI personas for educational purposes. Not affiliated with real individuals.*');
216
+ return lines.join('\n');
217
+ }
218
+ // MCP Tool Definition
219
+ export const autoMatchTool = {
220
+ name: 'auto_match',
221
+ description: `Automatically find the most relevant legends for your question.
222
+
223
+ **How it works:**
224
+ 1. Analyzes your question for topics and keywords
225
+ 2. Matches relevant legends based on their expertise
226
+ 3. Returns matched legends with key insights
227
+
228
+ **Use this when:**
229
+ - You're not sure which legend to ask
230
+ - You want to see who has expertise in your topic
231
+ - You want quick insights before a full conversation
232
+
233
+ **What you get:**
234
+ - Top 2-3 most relevant legends
235
+ - Why each was matched
236
+ - A key insight from each
237
+ - Suggested next steps
238
+
239
+ **Examples:**
240
+ - "How do I raise money for my startup?" → Paul Graham, Marc Andreessen
241
+ - "What's the future of AI?" → Sam Altman, Jensen Huang
242
+ - "How should I think about risk?" → Ray Dalio, Howard Marks
243
+
244
+ DISCLAIMER: AI personas for educational purposes only.`,
245
+ inputSchema: {
246
+ type: 'object',
247
+ properties: {
248
+ question: {
249
+ type: 'string',
250
+ description: 'Your question or topic to find relevant legends for',
251
+ },
252
+ max_matches: {
253
+ type: 'number',
254
+ description: 'Maximum legends to match (default: 2, max: 3)',
255
+ },
256
+ include_prompts: {
257
+ type: 'boolean',
258
+ description: 'Include full system prompts for each legend (default: false)',
259
+ },
260
+ },
261
+ required: ['question'],
262
+ },
263
+ };
264
+ //# sourceMappingURL=auto-match.js.map