olympus-mcp 1.0.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 +45 -0
- package/index.js +591 -0
- package/package.json +27 -0
package/README.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Olympus MCP
|
|
2
|
+
|
|
3
|
+
Warren Buffett-style value investing analysis for Claude AI.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx olympus-mcp
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
This will:
|
|
12
|
+
1. Install the package
|
|
13
|
+
2. Auto-configure Claude Desktop
|
|
14
|
+
3. No manual setup required!
|
|
15
|
+
|
|
16
|
+
After installation, restart Claude Desktop.
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
Ask Claude:
|
|
21
|
+
- "Analyze Apple using value investing"
|
|
22
|
+
- "Show me the value investing framework"
|
|
23
|
+
- "Calculate earnings yield for..."
|
|
24
|
+
|
|
25
|
+
## Features
|
|
26
|
+
|
|
27
|
+
- Earnings Yield Analysis (>10% threshold)
|
|
28
|
+
- ROIC Evaluation (5-year average)
|
|
29
|
+
- Investment Classification (Lists 1-4)
|
|
30
|
+
- Based on Buffett & Munger principles
|
|
31
|
+
|
|
32
|
+
## The 4 Lists
|
|
33
|
+
|
|
34
|
+
1. **LIST 1**: Good at Wonderful Price
|
|
35
|
+
2. **LIST 2**: Wonderful at Fair Price ⭐
|
|
36
|
+
3. **LIST 3**: FAT PITCH 🎯 (Rare opportunity!)
|
|
37
|
+
4. **LIST 4**: Wonderful but Overvalued (Study & wait)
|
|
38
|
+
|
|
39
|
+
## License
|
|
40
|
+
|
|
41
|
+
MIT
|
|
42
|
+
|
|
43
|
+
## Author
|
|
44
|
+
|
|
45
|
+
Owen Taylor - Pallas AI
|
package/index.js
ADDED
|
@@ -0,0 +1,591 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Olympus MCP Server
|
|
4
|
+
* Warren Buffett-style value investing analysis for Claude AI
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
8
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
9
|
+
import {
|
|
10
|
+
CallToolRequestSchema,
|
|
11
|
+
ListToolsRequestSchema,
|
|
12
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
13
|
+
|
|
14
|
+
// Framework constants
|
|
15
|
+
const EARNINGS_YIELD_THRESHOLD = 0.10; // 10%
|
|
16
|
+
const ROIC_THRESHOLD = 0.15; // 15%
|
|
17
|
+
const ROIC_WONDERFUL_THRESHOLD = 0.25; // 25%
|
|
18
|
+
|
|
19
|
+
// Initialize the MCP server
|
|
20
|
+
const server = new Server(
|
|
21
|
+
{
|
|
22
|
+
name: "olympus-mcp",
|
|
23
|
+
version: "1.0.0",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
capabilities: {
|
|
27
|
+
tools: {},
|
|
28
|
+
},
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
// List available tools
|
|
33
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
34
|
+
return {
|
|
35
|
+
tools: [
|
|
36
|
+
{
|
|
37
|
+
name: "analyze_stock",
|
|
38
|
+
description:
|
|
39
|
+
"Performs comprehensive value investing analysis on a stock using the Buffett-style framework. " +
|
|
40
|
+
"Requires: company ticker/name, operating income (3-year data), enterprise value, " +
|
|
41
|
+
"ROIC data (5-year), and current stock price. Returns quantitative screening results, " +
|
|
42
|
+
"qualitative assessment, and classification (List 1-4).",
|
|
43
|
+
inputSchema: {
|
|
44
|
+
type: "object",
|
|
45
|
+
properties: {
|
|
46
|
+
company_name: {
|
|
47
|
+
type: "string",
|
|
48
|
+
description: "Company name or ticker symbol",
|
|
49
|
+
},
|
|
50
|
+
operating_income_y1: {
|
|
51
|
+
type: "number",
|
|
52
|
+
description: "Operating income (GAAP) for year 1 (oldest of 3 years)",
|
|
53
|
+
},
|
|
54
|
+
operating_income_y2: {
|
|
55
|
+
type: "number",
|
|
56
|
+
description: "Operating income (GAAP) for year 2",
|
|
57
|
+
},
|
|
58
|
+
operating_income_y3: {
|
|
59
|
+
type: "number",
|
|
60
|
+
description: "Operating income (GAAP) for year 3 (most recent)",
|
|
61
|
+
},
|
|
62
|
+
enterprise_value: {
|
|
63
|
+
type: "number",
|
|
64
|
+
description: "Current enterprise value (market cap + debt - cash)",
|
|
65
|
+
},
|
|
66
|
+
roic_data: {
|
|
67
|
+
type: "array",
|
|
68
|
+
items: { type: "number" },
|
|
69
|
+
description: "Array of 5 years of ROIC percentages (as decimals, e.g., 0.25 for 25%)",
|
|
70
|
+
},
|
|
71
|
+
current_price: {
|
|
72
|
+
type: "number",
|
|
73
|
+
description: "Current stock price",
|
|
74
|
+
},
|
|
75
|
+
currency: {
|
|
76
|
+
type: "string",
|
|
77
|
+
description: "Currency symbol (e.g., '$', '₹', '€')",
|
|
78
|
+
default: "$",
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
required: [
|
|
82
|
+
"company_name",
|
|
83
|
+
"operating_income_y1",
|
|
84
|
+
"operating_income_y2",
|
|
85
|
+
"operating_income_y3",
|
|
86
|
+
"enterprise_value",
|
|
87
|
+
"roic_data",
|
|
88
|
+
"current_price",
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: "calculate_earnings_yield",
|
|
94
|
+
description:
|
|
95
|
+
"Calculates the earnings yield for a stock. " +
|
|
96
|
+
"Earnings Yield = (3-year average operating income) / Enterprise Value. " +
|
|
97
|
+
"Returns whether it passes the >10% threshold.",
|
|
98
|
+
inputSchema: {
|
|
99
|
+
type: "object",
|
|
100
|
+
properties: {
|
|
101
|
+
operating_income_y1: { type: "number" },
|
|
102
|
+
operating_income_y2: { type: "number" },
|
|
103
|
+
operating_income_y3: { type: "number" },
|
|
104
|
+
enterprise_value: { type: "number" },
|
|
105
|
+
},
|
|
106
|
+
required: ["operating_income_y1", "operating_income_y2", "operating_income_y3", "enterprise_value"],
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: "calculate_roic",
|
|
111
|
+
description:
|
|
112
|
+
"Calculates the average ROIC over 5 years and determines if it meets " +
|
|
113
|
+
"the threshold (>15% for good business, >25% for wonderful business).",
|
|
114
|
+
inputSchema: {
|
|
115
|
+
type: "object",
|
|
116
|
+
properties: {
|
|
117
|
+
roic_data: {
|
|
118
|
+
type: "array",
|
|
119
|
+
items: { type: "number" },
|
|
120
|
+
description: "Array of 5 years of ROIC percentages (as decimals)",
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
required: ["roic_data"],
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: "classify_investment",
|
|
128
|
+
description:
|
|
129
|
+
"Classifies an investment into one of 4 lists based on the framework:\n" +
|
|
130
|
+
"LIST 1: Good business at wonderful price (ROIC 15-25%, earnings yield >10%)\n" +
|
|
131
|
+
"LIST 2: Wonderful business at fair price (ROIC >25%, fair valuation)\n" +
|
|
132
|
+
"LIST 3: FAT PITCH - Wonderful business at wonderful price (ROIC >25%, earnings yield >10%)\n" +
|
|
133
|
+
"LIST 4: Wonderful business overvalued (ROIC >25%, earnings yield <10%)",
|
|
134
|
+
inputSchema: {
|
|
135
|
+
type: "object",
|
|
136
|
+
properties: {
|
|
137
|
+
earnings_yield: {
|
|
138
|
+
type: "number",
|
|
139
|
+
description: "Earnings yield as a decimal (e.g., 0.12 for 12%)",
|
|
140
|
+
},
|
|
141
|
+
avg_roic: {
|
|
142
|
+
type: "number",
|
|
143
|
+
description: "Average ROIC as a decimal (e.g., 0.30 for 30%)",
|
|
144
|
+
},
|
|
145
|
+
business_quality: {
|
|
146
|
+
type: "string",
|
|
147
|
+
enum: ["good", "wonderful"],
|
|
148
|
+
description: "Business quality assessment",
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
required: ["earnings_yield", "avg_roic", "business_quality"],
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
name: "get_framework",
|
|
156
|
+
description:
|
|
157
|
+
"Returns the complete value investing framework documentation, " +
|
|
158
|
+
"including all classification criteria and investment philosophy.",
|
|
159
|
+
inputSchema: {
|
|
160
|
+
type: "object",
|
|
161
|
+
properties: {},
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
],
|
|
165
|
+
};
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// Handle tool calls
|
|
169
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
170
|
+
const { name, arguments: args } = request.params;
|
|
171
|
+
|
|
172
|
+
try {
|
|
173
|
+
switch (name) {
|
|
174
|
+
case "calculate_earnings_yield": {
|
|
175
|
+
const avgOI = (args.operating_income_y1 + args.operating_income_y2 + args.operating_income_y3) / 3;
|
|
176
|
+
const ev = args.enterprise_value;
|
|
177
|
+
const earningsYield = avgOI / ev;
|
|
178
|
+
const passes = earningsYield >= EARNINGS_YIELD_THRESHOLD;
|
|
179
|
+
|
|
180
|
+
const result = {
|
|
181
|
+
average_operating_income: Math.round(avgOI * 100) / 100,
|
|
182
|
+
enterprise_value: ev,
|
|
183
|
+
earnings_yield: Math.round(earningsYield * 10000) / 100,
|
|
184
|
+
earnings_yield_decimal: Math.round(earningsYield * 10000) / 10000,
|
|
185
|
+
threshold: EARNINGS_YIELD_THRESHOLD * 100,
|
|
186
|
+
passes: passes,
|
|
187
|
+
verdict: passes ? "✅ PASSES" : "❌ FAILS",
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
return {
|
|
191
|
+
content: [
|
|
192
|
+
{
|
|
193
|
+
type: "text",
|
|
194
|
+
text: JSON.stringify(result, null, 2),
|
|
195
|
+
},
|
|
196
|
+
],
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
case "calculate_roic": {
|
|
201
|
+
const roicData = args.roic_data;
|
|
202
|
+
|
|
203
|
+
if (roicData.length !== 5) {
|
|
204
|
+
return {
|
|
205
|
+
content: [
|
|
206
|
+
{
|
|
207
|
+
type: "text",
|
|
208
|
+
text: JSON.stringify({
|
|
209
|
+
error: "ROIC data must contain exactly 5 years of data",
|
|
210
|
+
}),
|
|
211
|
+
},
|
|
212
|
+
],
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const avgROIC = roicData.reduce((a, b) => a + b, 0) / roicData.length;
|
|
217
|
+
const passesGood = avgROIC >= ROIC_THRESHOLD;
|
|
218
|
+
const passesWonderful = avgROIC >= ROIC_WONDERFUL_THRESHOLD;
|
|
219
|
+
|
|
220
|
+
const result = {
|
|
221
|
+
roic_data_percentages: roicData.map((r) => Math.round(r * 10000) / 100),
|
|
222
|
+
average_roic: Math.round(avgROIC * 10000) / 100,
|
|
223
|
+
average_roic_decimal: Math.round(avgROIC * 10000) / 10000,
|
|
224
|
+
threshold_good_business: ROIC_THRESHOLD * 100,
|
|
225
|
+
threshold_wonderful_business: ROIC_WONDERFUL_THRESHOLD * 100,
|
|
226
|
+
passes_good_threshold: passesGood,
|
|
227
|
+
passes_wonderful_threshold: passesWonderful,
|
|
228
|
+
classification: passesWonderful
|
|
229
|
+
? "Wonderful Business (>25%)"
|
|
230
|
+
: passesGood
|
|
231
|
+
? "Good Business (15-25%)"
|
|
232
|
+
: "Below Threshold (<15%)",
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
return {
|
|
236
|
+
content: [
|
|
237
|
+
{
|
|
238
|
+
type: "text",
|
|
239
|
+
text: JSON.stringify(result, null, 2),
|
|
240
|
+
},
|
|
241
|
+
],
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
case "classify_investment": {
|
|
246
|
+
const ey = args.earnings_yield;
|
|
247
|
+
const roic = args.avg_roic;
|
|
248
|
+
|
|
249
|
+
let classification, description, action;
|
|
250
|
+
|
|
251
|
+
if (roic >= ROIC_WONDERFUL_THRESHOLD) {
|
|
252
|
+
if (ey >= EARNINGS_YIELD_THRESHOLD) {
|
|
253
|
+
classification = "LIST 3: FAT PITCH 🎯";
|
|
254
|
+
description = "Wonderful business at wonderful price - SWING HARD!";
|
|
255
|
+
action = "BUY AGGRESSIVELY - Size positions large";
|
|
256
|
+
} else if (ey >= 0.08) {
|
|
257
|
+
classification = "LIST 2: Wonderful at Fair Price";
|
|
258
|
+
description = "Wonderful business at reasonable valuation";
|
|
259
|
+
action = "BUY and HOLD FOREVER - Let quality compound";
|
|
260
|
+
} else {
|
|
261
|
+
classification = "LIST 4: Wonderful but Overvalued 📋";
|
|
262
|
+
description = "Study now, wait for better price";
|
|
263
|
+
action = "WATCHLIST - Monitor for price decline";
|
|
264
|
+
}
|
|
265
|
+
} else if (roic >= ROIC_THRESHOLD) {
|
|
266
|
+
if (ey >= EARNINGS_YIELD_THRESHOLD) {
|
|
267
|
+
classification = "LIST 1: Good Business at Wonderful Price";
|
|
268
|
+
description = "Solid fundamentals with margin of safety";
|
|
269
|
+
action = "BUY with discipline - 3-5 year hold";
|
|
270
|
+
} else {
|
|
271
|
+
classification = "PASS";
|
|
272
|
+
description = "Good business but insufficient margin of safety";
|
|
273
|
+
action = "Skip - wait for better opportunity";
|
|
274
|
+
}
|
|
275
|
+
} else {
|
|
276
|
+
classification = "PASS";
|
|
277
|
+
description = "Fails ROIC threshold";
|
|
278
|
+
action = "Skip entirely - poor business quality";
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const result = {
|
|
282
|
+
classification,
|
|
283
|
+
description,
|
|
284
|
+
recommended_action: action,
|
|
285
|
+
earnings_yield: Math.round(ey * 10000) / 100,
|
|
286
|
+
avg_roic: Math.round(roic * 10000) / 100,
|
|
287
|
+
passes_quantitative_screens: roic >= ROIC_THRESHOLD && ey >= EARNINGS_YIELD_THRESHOLD,
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
return {
|
|
291
|
+
content: [
|
|
292
|
+
{
|
|
293
|
+
type: "text",
|
|
294
|
+
text: JSON.stringify(result, null, 2),
|
|
295
|
+
},
|
|
296
|
+
],
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
case "analyze_stock": {
|
|
301
|
+
const currency = args.currency || "$";
|
|
302
|
+
const company = args.company_name;
|
|
303
|
+
|
|
304
|
+
// Calculate earnings yield
|
|
305
|
+
const avgOI = (args.operating_income_y1 + args.operating_income_y2 + args.operating_income_y3) / 3;
|
|
306
|
+
const ev = args.enterprise_value;
|
|
307
|
+
const earningsYield = avgOI / ev;
|
|
308
|
+
|
|
309
|
+
// Calculate ROIC
|
|
310
|
+
const roicData = args.roic_data;
|
|
311
|
+
const avgROIC = roicData.reduce((a, b) => a + b, 0) / roicData.length;
|
|
312
|
+
|
|
313
|
+
// Determine business quality
|
|
314
|
+
const isWonderful = avgROIC >= ROIC_WONDERFUL_THRESHOLD;
|
|
315
|
+
const isGood = avgROIC >= ROIC_THRESHOLD;
|
|
316
|
+
|
|
317
|
+
// Classification
|
|
318
|
+
let classification, action;
|
|
319
|
+
if (isWonderful) {
|
|
320
|
+
if (earningsYield >= EARNINGS_YIELD_THRESHOLD) {
|
|
321
|
+
classification = "LIST 3: FAT PITCH 🎯";
|
|
322
|
+
action = "BUY AGGRESSIVELY";
|
|
323
|
+
} else if (earningsYield >= 0.08) {
|
|
324
|
+
classification = "LIST 2: Wonderful at Fair Price";
|
|
325
|
+
action = "BUY and HOLD FOREVER";
|
|
326
|
+
} else {
|
|
327
|
+
classification = "LIST 4: Wonderful but Overvalued";
|
|
328
|
+
action = "WATCHLIST";
|
|
329
|
+
}
|
|
330
|
+
} else if (isGood) {
|
|
331
|
+
if (earningsYield >= EARNINGS_YIELD_THRESHOLD) {
|
|
332
|
+
classification = "LIST 1: Good at Wonderful Price";
|
|
333
|
+
action = "BUY with Discipline";
|
|
334
|
+
} else {
|
|
335
|
+
classification = "PASS - Insufficient Margin of Safety";
|
|
336
|
+
action = "Skip";
|
|
337
|
+
}
|
|
338
|
+
} else {
|
|
339
|
+
classification = "PASS - Poor Business Quality";
|
|
340
|
+
action = "Skip Entirely";
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Build comprehensive report
|
|
344
|
+
let report = `
|
|
345
|
+
═══════════════════════════════════════════════════════════════
|
|
346
|
+
VALUE INVESTING ANALYSIS: ${company}
|
|
347
|
+
═══════════════════════════════════════════════════════════════
|
|
348
|
+
|
|
349
|
+
📊 QUANTITATIVE SCREENING
|
|
350
|
+
───────────────────────────────────────────────────────────────
|
|
351
|
+
|
|
352
|
+
1. EARNINGS YIELD TEST (Threshold: >10%)
|
|
353
|
+
Operating Income (3-year avg): ${currency}${avgOI.toLocaleString("en-US", { maximumFractionDigits: 0 })}
|
|
354
|
+
Enterprise Value: ${currency}${ev.toLocaleString("en-US", { maximumFractionDigits: 0 })}
|
|
355
|
+
Earnings Yield: ${(earningsYield * 100).toFixed(2)}%
|
|
356
|
+
Status: ${earningsYield >= EARNINGS_YIELD_THRESHOLD ? "✅ PASSES" : "❌ FAILS"}
|
|
357
|
+
|
|
358
|
+
2. ROIC TEST (Threshold: >15% good, >25% wonderful)
|
|
359
|
+
Year 1: ${(roicData[0] * 100).toFixed(1)}%
|
|
360
|
+
Year 2: ${(roicData[1] * 100).toFixed(1)}%
|
|
361
|
+
Year 3: ${(roicData[2] * 100).toFixed(1)}%
|
|
362
|
+
Year 4: ${(roicData[3] * 100).toFixed(1)}%
|
|
363
|
+
Year 5: ${(roicData[4] * 100).toFixed(1)}%
|
|
364
|
+
5-Year Average: ${(avgROIC * 100).toFixed(1)}%
|
|
365
|
+
Status: ${
|
|
366
|
+
isWonderful
|
|
367
|
+
? "✅ Wonderful Business (>25%)"
|
|
368
|
+
: isGood
|
|
369
|
+
? "✅ Good Business (15-25%)"
|
|
370
|
+
: "❌ Below Threshold"
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
───────────────────────────────────────────────────────────────
|
|
374
|
+
📋 CLASSIFICATION
|
|
375
|
+
───────────────────────────────────────────────────────────────
|
|
376
|
+
|
|
377
|
+
${classification}
|
|
378
|
+
|
|
379
|
+
Recommended Action: ${action}
|
|
380
|
+
|
|
381
|
+
───────────────────────────────────────────────────────────────
|
|
382
|
+
💡 FRAMEWORK GUIDANCE
|
|
383
|
+
───────────────────────────────────────────────────────────────
|
|
384
|
+
`;
|
|
385
|
+
|
|
386
|
+
if (classification.includes("FAT PITCH")) {
|
|
387
|
+
report += `
|
|
388
|
+
🎯 FAT PITCH OPPORTUNITY
|
|
389
|
+
This is a rare combination of wonderful business quality at a
|
|
390
|
+
wonderful price. "Back up the truck" - size this position aggressively.
|
|
391
|
+
These opportunities appear briefly during market dislocations.
|
|
392
|
+
|
|
393
|
+
Key: High ROIC + High Earnings Yield = Exceptional opportunity
|
|
394
|
+
`;
|
|
395
|
+
} else if (classification.includes("LIST 2")) {
|
|
396
|
+
report += `
|
|
397
|
+
📈 QUALITY COMPOUNDER
|
|
398
|
+
Wonderful business at fair price. Quality compounds over time -
|
|
399
|
+
entry price matters less with sustained high ROIC. Hold 10+ years.
|
|
400
|
+
This is where you spend most of your time per Charlie Munger.
|
|
401
|
+
|
|
402
|
+
Key: Let quality compound, minimize trading
|
|
403
|
+
`;
|
|
404
|
+
} else if (classification.includes("LIST 1")) {
|
|
405
|
+
report += `
|
|
406
|
+
💰 CLASSICAL VALUE PLAY
|
|
407
|
+
Good business with margin of safety. Price compensates for business
|
|
408
|
+
limitations. Requires 3-5 year horizon per Benjamin Graham approach.
|
|
409
|
+
|
|
410
|
+
Key: Solid fundamentals + discount = acceptable risk/reward
|
|
411
|
+
`;
|
|
412
|
+
} else if (classification.includes("LIST 4")) {
|
|
413
|
+
report += `
|
|
414
|
+
⏳ STUDY AND WAIT
|
|
415
|
+
Wonderful business but trading above intrinsic value. Study deeply NOW:
|
|
416
|
+
- Read 10-Ks and understand the moat
|
|
417
|
+
- Set your buy price (target >10% earnings yield)
|
|
418
|
+
- Monitor patiently with cash reserves ready
|
|
419
|
+
|
|
420
|
+
When market offers your price, you'll be prepared to act immediately.
|
|
421
|
+
|
|
422
|
+
Key: Patience is profitable - wait for fat pitch
|
|
423
|
+
`;
|
|
424
|
+
} else {
|
|
425
|
+
report += `
|
|
426
|
+
🚫 PASS ENTIRELY
|
|
427
|
+
Either business quality insufficient (ROIC <15%) or valuation doesn't
|
|
428
|
+
provide adequate margin of safety. Hold cash and wait for better
|
|
429
|
+
opportunities. Remember: sometimes the best investment decision is
|
|
430
|
+
saying "no."
|
|
431
|
+
|
|
432
|
+
Key: Capital preservation > forced deployment
|
|
433
|
+
`;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
report += `
|
|
437
|
+
|
|
438
|
+
───────────────────────────────────────────────────────────────
|
|
439
|
+
Current Price: ${currency}${args.current_price.toFixed(2)}
|
|
440
|
+
Analysis Date: ${new Date().toISOString().split("T")[0]}
|
|
441
|
+
═══════════════════════════════════════════════════════════════
|
|
442
|
+
`;
|
|
443
|
+
|
|
444
|
+
return {
|
|
445
|
+
content: [
|
|
446
|
+
{
|
|
447
|
+
type: "text",
|
|
448
|
+
text: report,
|
|
449
|
+
},
|
|
450
|
+
],
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
case "get_framework": {
|
|
455
|
+
const framework = `
|
|
456
|
+
═══════════════════════════════════════════════════════════════
|
|
457
|
+
VALUE INVESTING CLASSIFICATION FRAMEWORK
|
|
458
|
+
Based on Warren Buffett & Charlie Munger's Principles
|
|
459
|
+
═══════════════════════════════════════════════════════════════
|
|
460
|
+
|
|
461
|
+
"The big money is not in the buying and selling, but in the waiting."
|
|
462
|
+
— Charlie Munger
|
|
463
|
+
|
|
464
|
+
───────────────────────────────────────────────────────────────
|
|
465
|
+
📊 QUANTITATIVE SCREENS (REQUIRED)
|
|
466
|
+
───────────────────────────────────────────────────────────────
|
|
467
|
+
|
|
468
|
+
1. EARNINGS YIELD TEST: >10%
|
|
469
|
+
Calculation: 3-year average operating income / Enterprise Value
|
|
470
|
+
Purpose: Ensures adequate margin of safety
|
|
471
|
+
|
|
472
|
+
2. ROIC TEST: >15% over 5 years
|
|
473
|
+
Good Business: 15-25% ROIC
|
|
474
|
+
Wonderful Business: >25% ROIC
|
|
475
|
+
Purpose: Identifies capital efficiency and competitive moats
|
|
476
|
+
|
|
477
|
+
───────────────────────────────────────────────────────────────
|
|
478
|
+
📋 THE FOUR LISTS
|
|
479
|
+
───────────────────────────────────────────────────────────────
|
|
480
|
+
|
|
481
|
+
LIST 1: Good Businesses at Wonderful Price
|
|
482
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
483
|
+
• Quality: ROIC 15-25% (solid, not exceptional)
|
|
484
|
+
• Price: Earnings yield >10% (significant discount)
|
|
485
|
+
• Strategy: Classical Graham value - 3-5 year hold
|
|
486
|
+
• Examples: Good companies with capital intensity or competitive pressures
|
|
487
|
+
|
|
488
|
+
LIST 2: Wonderful Businesses at Fair Price ⭐
|
|
489
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
490
|
+
• Quality: ROIC >25%, durable moats, pricing power
|
|
491
|
+
• Price: Fair valuation (15-25x earnings), modest margin of safety
|
|
492
|
+
• Strategy: Buy and hold "forever" - let quality compound
|
|
493
|
+
• Note: Munger's sweet spot - where you spend most time
|
|
494
|
+
|
|
495
|
+
LIST 3: FAT PITCH - Wonderful at Wonderful Price 🎯
|
|
496
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
497
|
+
• Quality: ROIC >25%, strong moats, exceptional business
|
|
498
|
+
• Price: Bargain prices despite quality (<15x earnings typically)
|
|
499
|
+
• Strategy: "Back up the truck" - size positions aggressively
|
|
500
|
+
• Frequency: Rare - appears during market panics every few years
|
|
501
|
+
|
|
502
|
+
LIST 4: Wonderful Business Overvalued (Watchlist) 📋
|
|
503
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
504
|
+
• Quality: ROIC >25%, wonderful characteristics
|
|
505
|
+
• Price: Above intrinsic value (often >30x earnings)
|
|
506
|
+
• Strategy: Study deeply NOW, monitor patiently, maintain cash
|
|
507
|
+
• Action: When market offers your price, act immediately
|
|
508
|
+
|
|
509
|
+
───────────────────────────────────────────────────────────────
|
|
510
|
+
🎯 QUICK CLASSIFICATION GUIDE
|
|
511
|
+
───────────────────────────────────────────────────────────────
|
|
512
|
+
|
|
513
|
+
1. Passes quantitative screens? → If NO, PASS entirely
|
|
514
|
+
2. Is it wonderful (ROIC >25%)? → Determines List 2/3/4 vs List 1
|
|
515
|
+
3. What's the price?
|
|
516
|
+
• Significant discount + wonderful → LIST 3 (Buy aggressively)
|
|
517
|
+
• Fair price + wonderful → LIST 2 (Buy and hold forever)
|
|
518
|
+
• Discount + good (not wonderful) → LIST 1 (Buy with discipline)
|
|
519
|
+
• Premium + wonderful → LIST 4 (Study and wait)
|
|
520
|
+
|
|
521
|
+
───────────────────────────────────────────────────────────────
|
|
522
|
+
⚠️ CRITICAL PRINCIPLES
|
|
523
|
+
───────────────────────────────────────────────────────────────
|
|
524
|
+
|
|
525
|
+
• High historical ROIC alone ≠ wonderful business
|
|
526
|
+
• Must be SUSTAINABLE and IMPROVING
|
|
527
|
+
• A shrinking business with great past returns is NOT wonderful
|
|
528
|
+
• Margin of safety is PRIMARY criterion
|
|
529
|
+
• Sometimes best decision is holding cash and saying "no"
|
|
530
|
+
• "Wait for the fat pitch" - patience is often highest-return decision
|
|
531
|
+
|
|
532
|
+
───────────────────────────────────────────────────────────────
|
|
533
|
+
💡 PHILOSOPHY
|
|
534
|
+
───────────────────────────────────────────────────────────────
|
|
535
|
+
|
|
536
|
+
This framework emphasizes:
|
|
537
|
+
1. Buying wonderful businesses at wonderful prices (rare but powerful)
|
|
538
|
+
2. Holding quality forever when purchased at fair prices
|
|
539
|
+
3. NEVER overpaying, even for quality
|
|
540
|
+
4. Capital preservation through disciplined screening
|
|
541
|
+
5. Patient opportunism over constant activity
|
|
542
|
+
|
|
543
|
+
"It's far better to buy a wonderful company at a fair price than
|
|
544
|
+
a fair company at a wonderful price." — Warren Buffett
|
|
545
|
+
|
|
546
|
+
═══════════════════════════════════════════════════════════════
|
|
547
|
+
`;
|
|
548
|
+
|
|
549
|
+
return {
|
|
550
|
+
content: [
|
|
551
|
+
{
|
|
552
|
+
type: "text",
|
|
553
|
+
text: framework,
|
|
554
|
+
},
|
|
555
|
+
],
|
|
556
|
+
};
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
default:
|
|
560
|
+
return {
|
|
561
|
+
content: [
|
|
562
|
+
{
|
|
563
|
+
type: "text",
|
|
564
|
+
text: JSON.stringify({ error: `Unknown tool: ${name}` }),
|
|
565
|
+
},
|
|
566
|
+
],
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
} catch (error) {
|
|
570
|
+
return {
|
|
571
|
+
content: [
|
|
572
|
+
{
|
|
573
|
+
type: "text",
|
|
574
|
+
text: JSON.stringify({ error: error.message }),
|
|
575
|
+
},
|
|
576
|
+
],
|
|
577
|
+
isError: true,
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
});
|
|
581
|
+
|
|
582
|
+
// Start the server
|
|
583
|
+
async function main() {
|
|
584
|
+
const transport = new StdioServerTransport();
|
|
585
|
+
await server.connect(transport);
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
main().catch((error) => {
|
|
589
|
+
console.error("Server error:", error);
|
|
590
|
+
process.exit(1);
|
|
591
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "olympus-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Warren Buffett-style value investing analysis for Claude AI",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"bin": "index.js",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"start": "node index.js"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"mcp",
|
|
13
|
+
"value-investing",
|
|
14
|
+
"warren-buffett",
|
|
15
|
+
"stock-analysis",
|
|
16
|
+
"claude",
|
|
17
|
+
"olympus"
|
|
18
|
+
],
|
|
19
|
+
"author": "Owen Taylor",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
23
|
+
},
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=18"
|
|
26
|
+
}
|
|
27
|
+
}
|