career-compass-mcp 2.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/LICENSE +21 -0
- package/README.md +340 -0
- package/build/bin/cli.d.ts +9 -0
- package/build/bin/cli.d.ts.map +1 -0
- package/build/bin/cli.js +134 -0
- package/build/bin/cli.js.map +1 -0
- package/build/src/index.d.ts +3 -0
- package/build/src/index.d.ts.map +1 -0
- package/build/src/index.js +18 -0
- package/build/src/index.js.map +1 -0
- package/build/src/prompts/index.d.ts +3 -0
- package/build/src/prompts/index.d.ts.map +1 -0
- package/build/src/prompts/index.js +122 -0
- package/build/src/prompts/index.js.map +1 -0
- package/build/src/resources/career-kb.d.ts +3 -0
- package/build/src/resources/career-kb.d.ts.map +1 -0
- package/build/src/resources/career-kb.js +143 -0
- package/build/src/resources/career-kb.js.map +1 -0
- package/build/src/schemas/career-schema.d.ts +361 -0
- package/build/src/schemas/career-schema.d.ts.map +1 -0
- package/build/src/schemas/career-schema.js +146 -0
- package/build/src/schemas/career-schema.js.map +1 -0
- package/build/src/server.d.ts +3 -0
- package/build/src/server.d.ts.map +1 -0
- package/build/src/server.js +30 -0
- package/build/src/server.js.map +1 -0
- package/build/src/storage/file-store.d.ts +22 -0
- package/build/src/storage/file-store.d.ts.map +1 -0
- package/build/src/storage/file-store.js +163 -0
- package/build/src/storage/file-store.js.map +1 -0
- package/build/src/tools/career-kb.d.ts +3 -0
- package/build/src/tools/career-kb.d.ts.map +1 -0
- package/build/src/tools/career-kb.js +148 -0
- package/build/src/tools/career-kb.js.map +1 -0
- package/build/src/tools/interview.d.ts +3 -0
- package/build/src/tools/interview.d.ts.map +1 -0
- package/build/src/tools/interview.js +194 -0
- package/build/src/tools/interview.js.map +1 -0
- package/build/src/tools/opportunity.d.ts +3 -0
- package/build/src/tools/opportunity.d.ts.map +1 -0
- package/build/src/tools/opportunity.js +137 -0
- package/build/src/tools/opportunity.js.map +1 -0
- package/build/src/tools/pipeline.d.ts +11 -0
- package/build/src/tools/pipeline.d.ts.map +1 -0
- package/build/src/tools/pipeline.js +295 -0
- package/build/src/tools/pipeline.js.map +1 -0
- package/build/src/tools/resume.d.ts +3 -0
- package/build/src/tools/resume.d.ts.map +1 -0
- package/build/src/tools/resume.js +222 -0
- package/build/src/tools/resume.js.map +1 -0
- package/build/src/types/tool-args.d.ts +52 -0
- package/build/src/types/tool-args.d.ts.map +1 -0
- package/build/src/types/tool-args.js +2 -0
- package/build/src/types/tool-args.js.map +1 -0
- package/data/example/career/experience.yaml +67 -0
- package/data/example/career/profile.yaml +31 -0
- package/data/example/career/skills.yaml +71 -0
- package/data/example/career/testimonials.yaml +26 -0
- package/data/example/pipeline/applications.yaml +312 -0
- package/package.json +82 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { loadCareerData, loadPipeline } from "../storage/file-store.js";
|
|
3
|
+
export function registerInterviewTools(server) {
|
|
4
|
+
server.registerTool("prepare_interview", {
|
|
5
|
+
title: "Prepare Interview",
|
|
6
|
+
description: "Generate comprehensive interview prep: STAR stories, likely questions, company alignment, and bridge topics — tailored to interview type.",
|
|
7
|
+
inputSchema: {
|
|
8
|
+
applicationId: z.string().optional().describe("Pipeline application ID"),
|
|
9
|
+
company: z.string().optional().describe("Company name (if no application ID)"),
|
|
10
|
+
role: z.string().optional().describe("Role title (if no application ID)"),
|
|
11
|
+
interviewType: z.enum(["phone_screen", "behavioral", "technical", "panel", "final", "negotiation"]).describe("Type of interview"),
|
|
12
|
+
interviewerInfo: z.string().optional().describe("Interviewer name, title, LinkedIn — helps personalize prep"),
|
|
13
|
+
postingText: z.string().optional().describe("Job posting text for this role"),
|
|
14
|
+
focusAreas: z.string().optional().describe("Specific topics or concerns to focus on"),
|
|
15
|
+
},
|
|
16
|
+
}, async ({ applicationId, company, role, interviewType, interviewerInfo, postingText, focusAreas }) => {
|
|
17
|
+
const career = await loadCareerData();
|
|
18
|
+
let appContext = "";
|
|
19
|
+
if (applicationId) {
|
|
20
|
+
const pipeline = await loadPipeline();
|
|
21
|
+
const app = pipeline.applications.find(a => a.id === applicationId);
|
|
22
|
+
if (app) {
|
|
23
|
+
company = company ?? app.company;
|
|
24
|
+
role = role ?? app.role;
|
|
25
|
+
postingText = postingText ?? app.postingText;
|
|
26
|
+
appContext = `
|
|
27
|
+
**Application context:**
|
|
28
|
+
- Status: ${app.status}
|
|
29
|
+
- Applied: ${app.dateApplied ?? "Unknown"}
|
|
30
|
+
- Rounds completed: ${app.interviewRounds.length}
|
|
31
|
+
- Notes: ${app.notes.join("; ") || "None"}
|
|
32
|
+
- Contacts: ${app.contacts.map(c => `${c.name} (${c.title})`).join(", ") || "None"}`;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (!career) {
|
|
36
|
+
return {
|
|
37
|
+
content: [{ type: "text", text: "⚠️ No career data found. Please populate your Career KB first." }],
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
const achievements = career.experience
|
|
41
|
+
.flatMap(e => e.achievements.map(a => ({
|
|
42
|
+
role: e.role,
|
|
43
|
+
company: e.company,
|
|
44
|
+
metric: a.metric,
|
|
45
|
+
context: a.context,
|
|
46
|
+
impact: a.impact,
|
|
47
|
+
})))
|
|
48
|
+
.slice(0, 20);
|
|
49
|
+
return {
|
|
50
|
+
content: [{
|
|
51
|
+
type: "text",
|
|
52
|
+
text: `# Interview Prep: ${interviewType.replace("_", " ").toUpperCase()}
|
|
53
|
+
|
|
54
|
+
**Company:** ${company ?? "Not specified"}
|
|
55
|
+
**Role:** ${role ?? "Not specified"}
|
|
56
|
+
**Interview type:** ${interviewType}
|
|
57
|
+
${interviewerInfo ? `**Interviewer:** ${interviewerInfo}` : ""}
|
|
58
|
+
${appContext}
|
|
59
|
+
${focusAreas ? `**Focus areas:** ${focusAreas}` : ""}
|
|
60
|
+
|
|
61
|
+
## Career Highlights (for STAR stories)
|
|
62
|
+
${achievements.map(a => `- **${a.role} @ ${a.company}**: ${a.metric} — ${a.context} → ${a.impact}`).join("\n")}
|
|
63
|
+
|
|
64
|
+
## Full Career KB
|
|
65
|
+
${JSON.stringify(career, null, 2)}
|
|
66
|
+
|
|
67
|
+
${postingText ? `## Job Posting\n${postingText}` : ""}
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
**Instructions for Claude:**
|
|
72
|
+
Generate complete interview prep tailored to a ${interviewType.replace("_", " ")} at ${company ?? "this company"}:
|
|
73
|
+
|
|
74
|
+
### 1. Opening Pitch (60-90 seconds)
|
|
75
|
+
"Tell me about yourself" — tailored specifically to this role and company. Bridge my background to their context.
|
|
76
|
+
|
|
77
|
+
### 2. STAR Stories (7-10 stories)
|
|
78
|
+
For each story, provide:
|
|
79
|
+
- **Situation:** Brief context
|
|
80
|
+
- **Task:** What I was responsible for
|
|
81
|
+
- **Action:** What I specifically did (not "we")
|
|
82
|
+
- **Result:** Quantified outcome
|
|
83
|
+
- **Best used for:** Which question types this answers
|
|
84
|
+
|
|
85
|
+
Match stories to the likely question themes for ${interviewType}:
|
|
86
|
+
${interviewType === "behavioral" ? "- Leadership, conflict, failure, ambiguity, collaboration, influence, growth" : ""}
|
|
87
|
+
${interviewType === "technical" ? "- System design, problem-solving approach, debugging, technical decisions" : ""}
|
|
88
|
+
${interviewType === "phone_screen" ? "- Background, motivation, salary expectations, availability, logistics" : ""}
|
|
89
|
+
${interviewType === "panel" ? "- Cross-functional influence, stakeholder management, communication style" : ""}
|
|
90
|
+
${interviewType === "final" ? "- Vision, leadership, company fit, long-term goals, strategic thinking" : ""}
|
|
91
|
+
|
|
92
|
+
### 3. Likely Questions (10-15)
|
|
93
|
+
Questions specific to ${company ?? "this company"} and ${role ?? "this role"}, with suggested answer angles from my background.
|
|
94
|
+
|
|
95
|
+
### 4. Questions to Ask (7-10)
|
|
96
|
+
Thoughtful questions that demonstrate genuine insight about the role, team, and company. Not generic.
|
|
97
|
+
|
|
98
|
+
### 5. Company & Role Alignment
|
|
99
|
+
How my background specifically connects to ${company ?? "their"} mission, product, and current challenges.
|
|
100
|
+
|
|
101
|
+
### 6. Bridge Topics
|
|
102
|
+
Surprising connections between my experience and their world — things that will make me memorable.
|
|
103
|
+
|
|
104
|
+
### 7. Watch-outs & Reframes
|
|
105
|
+
Likely concerns they'll have about my background, and how to address them proactively and honestly.`,
|
|
106
|
+
}],
|
|
107
|
+
};
|
|
108
|
+
});
|
|
109
|
+
server.registerTool("evaluate_offer", {
|
|
110
|
+
title: "Evaluate Offer",
|
|
111
|
+
description: "Analyze a job offer: break down total compensation, compare to market, build negotiation strategy, and draft counter scripts.",
|
|
112
|
+
inputSchema: {
|
|
113
|
+
applicationId: z.string().optional().describe("Pipeline application ID"),
|
|
114
|
+
company: z.string().optional(),
|
|
115
|
+
role: z.string().optional(),
|
|
116
|
+
offerDetails: z.string().describe("Full offer: base salary, bonus, equity, benefits, start date, title"),
|
|
117
|
+
location: z.string().optional().describe("Work location (affects cost of living calc)"),
|
|
118
|
+
currentComp: z.string().optional().describe("Your current total comp for comparison"),
|
|
119
|
+
marketData: z.string().optional().describe("Salary research from Levels.fyi, Glassdoor, LinkedIn, etc."),
|
|
120
|
+
priorities: z.string().optional().describe("What matters most: cash, equity, flexibility, title, growth?"),
|
|
121
|
+
otherOffers: z.string().optional().describe("Competing offers or processes (for leverage)"),
|
|
122
|
+
},
|
|
123
|
+
}, async ({ applicationId, company, role, offerDetails, location, currentComp, marketData, priorities, otherOffers }) => {
|
|
124
|
+
if (applicationId) {
|
|
125
|
+
const pipeline = await loadPipeline();
|
|
126
|
+
const app = pipeline.applications.find(a => a.id === applicationId);
|
|
127
|
+
if (app) {
|
|
128
|
+
company = company ?? app.company;
|
|
129
|
+
role = role ?? app.role;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
content: [{
|
|
134
|
+
type: "text",
|
|
135
|
+
text: `# Offer Evaluation: ${role ?? "Role"} at ${company ?? "Company"}
|
|
136
|
+
|
|
137
|
+
## Offer Details
|
|
138
|
+
${offerDetails}
|
|
139
|
+
|
|
140
|
+
${location ? `**Location:** ${location}` : ""}
|
|
141
|
+
${currentComp ? `**Current comp:** ${currentComp}` : ""}
|
|
142
|
+
${marketData ? `**Market data:** ${marketData}` : ""}
|
|
143
|
+
${priorities ? `**My priorities:** ${priorities}` : ""}
|
|
144
|
+
${otherOffers ? `**Other offers/processes:** ${otherOffers}` : ""}
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
**Instructions for Claude:**
|
|
149
|
+
|
|
150
|
+
### 1. Total Compensation Breakdown
|
|
151
|
+
Break down every component with annualized values:
|
|
152
|
+
- Base salary
|
|
153
|
+
- Target bonus (% and $ amount)
|
|
154
|
+
- Equity (value at current valuation, vesting schedule, cliff)
|
|
155
|
+
- Benefits (health, 401k match, PTO, etc. — assign approximate $ values)
|
|
156
|
+
- **Total Year 1 comp**
|
|
157
|
+
- **Total Year 4 comp** (fully vested)
|
|
158
|
+
|
|
159
|
+
### 2. Market Comparison
|
|
160
|
+
Compare to market rate for ${role ?? "this role"} at ${company ?? "this company type"}'s stage/size${location ? ` in ${location}` : ""}:
|
|
161
|
+
- P25, P50, P75 benchmarks (cite sources if market data provided)
|
|
162
|
+
- How does this offer rank?
|
|
163
|
+
- Is this competitive, low, or above market?
|
|
164
|
+
|
|
165
|
+
### 3. Negotiation Strategy
|
|
166
|
+
- What should I push on first?
|
|
167
|
+
- What's likely moveable vs. fixed?
|
|
168
|
+
- What's my target and walk-away?
|
|
169
|
+
- How does leverage from ${otherOffers ? "competing offers" : "my position"} play in?
|
|
170
|
+
|
|
171
|
+
### 4. Counter Script
|
|
172
|
+
Exact words for the negotiation call:
|
|
173
|
+
> "Thank you so much for the offer — I'm genuinely excited about the opportunity at ${company ?? "the company"}. I've done some research on market rates for this role, and I was hoping we could discuss the compensation a bit. Based on [X], I was hoping we could get to [specific number]. Is there flexibility there?"
|
|
174
|
+
|
|
175
|
+
Provide 2-3 variations depending on their response.
|
|
176
|
+
|
|
177
|
+
### 5. Alternative Asks
|
|
178
|
+
If base is firm, what else to ask for:
|
|
179
|
+
- Signing bonus
|
|
180
|
+
- Equity acceleration or refresh schedule
|
|
181
|
+
- Earlier first review
|
|
182
|
+
- Additional PTO
|
|
183
|
+
- Remote flexibility
|
|
184
|
+
- Title adjustment
|
|
185
|
+
- Equipment/home office budget
|
|
186
|
+
|
|
187
|
+
### 6. Decision Framework
|
|
188
|
+
Score this offer on: compensation, growth, culture fit, role scope, company trajectory, risk
|
|
189
|
+
Overall recommendation: Accept / Negotiate / Decline?`,
|
|
190
|
+
}],
|
|
191
|
+
};
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=interview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interview.js","sourceRoot":"","sources":["../../../src/tools/interview.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExE,MAAM,UAAU,sBAAsB,CAAC,MAAiB;IAEtD,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;QACE,KAAK,EAAE,mBAAmB;QAC1B,WAAW,EAAE,2IAA2I;QACxJ,WAAW,EAAE;YACX,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;YACxE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;YAC9E,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;YACzE,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,mBAAmB,CAAC;YACjI,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4DAA4D,CAAC;YAC7G,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;YAC7E,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;SACtF;KACF,EACD,KAAK,EAAE,EAAE,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,EAAE;QAClG,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAC;QACtC,IAAI,UAAU,GAAG,EAAE,CAAC;QAEpB,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAC;YACtC,MAAM,GAAG,GAAG,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,aAAa,CAAC,CAAC;YACpE,IAAI,GAAG,EAAE,CAAC;gBACR,OAAO,GAAG,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC;gBACjC,IAAI,GAAG,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC;gBACxB,WAAW,GAAG,WAAW,IAAI,GAAG,CAAC,WAAW,CAAC;gBAC7C,UAAU,GAAG;;YAEX,GAAG,CAAC,MAAM;aACT,GAAG,CAAC,WAAW,IAAI,SAAS;sBACnB,GAAG,CAAC,eAAe,CAAC,MAAM;WACrC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM;cAC3B,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,EAAE,CAAC;YAC7E,CAAC;QACH,CAAC;QAED,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,gEAAgE,EAAE,CAAC;aACpG,CAAC;QACJ,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,CAAC,UAAU;aACnC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACrC,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,MAAM,EAAE,CAAC,CAAC,MAAM;SACjB,CAAC,CAAC,CAAC;aACH,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAEhB,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,qBAAqB,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE;;eAEnE,OAAO,IAAI,eAAe;YAC7B,IAAI,IAAI,eAAe;sBACb,aAAa;EACjC,eAAe,CAAC,CAAC,CAAC,oBAAoB,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE;EAC5D,UAAU;EACV,UAAU,CAAC,CAAC,CAAC,oBAAoB,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE;;;EAGlD,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;;EAG5G,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;;EAE/B,WAAW,CAAC,CAAC,CAAC,mBAAmB,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE;;;;;iDAKJ,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,OAAO,IAAI,cAAc;;;;;;;;;;;;;kDAa9D,aAAa;EAC7D,aAAa,KAAK,YAAY,CAAC,CAAC,CAAC,8EAA8E,CAAC,CAAC,CAAC,EAAE;EACpH,aAAa,KAAK,WAAW,CAAC,CAAC,CAAC,2EAA2E,CAAC,CAAC,CAAC,EAAE;EAChH,aAAa,KAAK,cAAc,CAAC,CAAC,CAAC,wEAAwE,CAAC,CAAC,CAAC,EAAE;EAChH,aAAa,KAAK,OAAO,CAAC,CAAC,CAAC,2EAA2E,CAAC,CAAC,CAAC,EAAE;EAC5G,aAAa,KAAK,OAAO,CAAC,CAAC,CAAC,wEAAwE,CAAC,CAAC,CAAC,EAAE;;;wBAGnF,OAAO,IAAI,cAAc,QAAQ,IAAI,IAAI,WAAW;;;;;;6CAM/B,OAAO,IAAI,OAAO;;;;;;oGAMqC;iBAC3F,CAAC;SACH,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,gBAAgB,EAChB;QACE,KAAK,EAAE,gBAAgB;QACvB,WAAW,EAAE,+HAA+H;QAC5I,WAAW,EAAE;YACX,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;YACxE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAC9B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAC3B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qEAAqE,CAAC;YACxG,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;YACvF,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;YACrF,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4DAA4D,CAAC;YACxG,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8DAA8D,CAAC;YAC1G,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC;SAC5F;KACF,EACD,KAAK,EAAE,EAAE,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,EAAE,EAAE;QACnH,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAC;YACtC,MAAM,GAAG,GAAG,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,aAAa,CAAC,CAAC;YACpE,IAAI,GAAG,EAAE,CAAC;gBAAC,OAAO,GAAG,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC;gBAAC,IAAI,GAAG,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC;YAAC,CAAC;QACzE,CAAC;QAED,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,uBAAuB,IAAI,IAAI,MAAM,OAAO,OAAO,IAAI,SAAS;;;EAG9E,YAAY;;EAEZ,QAAQ,CAAC,CAAC,CAAC,iBAAiB,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE;EAC3C,WAAW,CAAC,CAAC,CAAC,qBAAqB,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE;EACrD,UAAU,CAAC,CAAC,CAAC,oBAAoB,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE;EAClD,UAAU,CAAC,CAAC,CAAC,sBAAsB,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE;EACpD,WAAW,CAAC,CAAC,CAAC,+BAA+B,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;6BAgBpC,IAAI,IAAI,WAAW,OAAO,OAAO,IAAI,mBAAmB,gBAAgB,QAAQ,CAAC,CAAC,CAAC,OAAO,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE;;;;;;;;;2BAS3G,WAAW,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,aAAa;;;;sFAIW,OAAO,IAAI,aAAa;;;;;;;;;;;;;;;;sDAgBxD;iBAC7C,CAAC;SACH,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opportunity.d.ts","sourceRoot":"","sources":["../../../src/tools/opportunity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAqIhE"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { loadCareerData } from "../storage/file-store.js";
|
|
3
|
+
export function registerOpportunityTools(server) {
|
|
4
|
+
server.registerTool("explore_opportunity", {
|
|
5
|
+
title: "Explore Opportunity",
|
|
6
|
+
description: "Analyze a job posting against your Career KB. Returns fit score, matched strengths, gaps, talking points, and a 'day in the life' brief.",
|
|
7
|
+
inputSchema: {
|
|
8
|
+
posting: z.string().describe("Full job posting text, or paste the raw text from a job board"),
|
|
9
|
+
company: z.string().optional().describe("Company name (if not in posting)"),
|
|
10
|
+
notes: z.string().optional().describe("Any additional context about this opportunity"),
|
|
11
|
+
},
|
|
12
|
+
}, async ({ posting, company, notes }) => {
|
|
13
|
+
const career = await loadCareerData();
|
|
14
|
+
if (!career) {
|
|
15
|
+
return {
|
|
16
|
+
content: [{
|
|
17
|
+
type: "text",
|
|
18
|
+
text: "⚠️ No career data found. Please populate your Career KB first by running `ingest_document` or adding YAML files to data/career/.",
|
|
19
|
+
}],
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
const careerSummary = buildCareerSummary(career);
|
|
23
|
+
return {
|
|
24
|
+
content: [{
|
|
25
|
+
type: "text",
|
|
26
|
+
text: `# Opportunity Analysis
|
|
27
|
+
|
|
28
|
+
## Career Context
|
|
29
|
+
${careerSummary}
|
|
30
|
+
|
|
31
|
+
## Job Posting
|
|
32
|
+
${posting}
|
|
33
|
+
${company ? `\n**Company:** ${company}` : ""}
|
|
34
|
+
${notes ? `\n**Notes:** ${notes}` : ""}
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
**Instructions for Claude:**
|
|
39
|
+
Using the career context above and the job posting, provide a structured analysis:
|
|
40
|
+
|
|
41
|
+
### 1. Fit Score (X/10)
|
|
42
|
+
Overall match assessment with a one-line rationale.
|
|
43
|
+
|
|
44
|
+
### 2. Strong Matches
|
|
45
|
+
List 5-7 specific points where my background directly maps to what they're asking for. Be specific — quote from both the posting and my career history.
|
|
46
|
+
|
|
47
|
+
### 3. Gaps & Growth Areas
|
|
48
|
+
Honest assessment of where I fall short. For each gap, note: (a) how significant it is, (b) whether it's a dealbreaker, (c) how to address it.
|
|
49
|
+
|
|
50
|
+
### 4. Talking Points
|
|
51
|
+
5 things to lead with in conversations about this role, framing my background in their language.
|
|
52
|
+
|
|
53
|
+
### 5. Day in the Life
|
|
54
|
+
Based on the posting, describe what my first 90 days and typical week would look like in this role. What problems would I own? What would success look like?
|
|
55
|
+
|
|
56
|
+
### 6. Red Flags / Questions
|
|
57
|
+
Anything in the posting that warrants clarification or concern.
|
|
58
|
+
|
|
59
|
+
### 7. Verdict
|
|
60
|
+
Should I pursue this? What's the strategic case for or against?`,
|
|
61
|
+
}],
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
server.registerTool("research_company", {
|
|
65
|
+
title: "Research Company",
|
|
66
|
+
description: "Build an intelligence brief on a company: product, funding, culture, tech stack, interview process, and strategic fit with your goals.",
|
|
67
|
+
inputSchema: {
|
|
68
|
+
company: z.string().describe("Company name"),
|
|
69
|
+
role: z.string().optional().describe("The role you're targeting"),
|
|
70
|
+
applicationId: z.string().optional().describe("Pipeline application ID for additional context"),
|
|
71
|
+
},
|
|
72
|
+
}, async ({ company, role, applicationId }) => {
|
|
73
|
+
const career = await loadCareerData();
|
|
74
|
+
const profile = career?.profile;
|
|
75
|
+
return {
|
|
76
|
+
content: [{
|
|
77
|
+
type: "text",
|
|
78
|
+
text: `# Company Research Brief: ${company}
|
|
79
|
+
|
|
80
|
+
**Target role:** ${role ?? "Not specified"}
|
|
81
|
+
${applicationId ? `**Application:** career://pipeline/${applicationId}` : ""}
|
|
82
|
+
|
|
83
|
+
**My target criteria (from Career KB):**
|
|
84
|
+
${profile ? `- Target roles: ${profile.targetRoles.join(", ") || "Not specified"}
|
|
85
|
+
- Target industries: ${profile.targetIndustries.join(", ") || "Not specified"}
|
|
86
|
+
- Remote preference: ${profile.openToRemote ? "Open to remote" : "Prefers onsite"}` : "Career KB not loaded"}
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
**Instructions for Claude:**
|
|
91
|
+
Use web search to build a comprehensive company brief covering:
|
|
92
|
+
|
|
93
|
+
### 1. Company Overview
|
|
94
|
+
- What they do (product/service, customer, business model)
|
|
95
|
+
- Stage: founding year, funding, headcount, public/private
|
|
96
|
+
- Recent news (last 6 months)
|
|
97
|
+
|
|
98
|
+
### 2. Culture & Environment
|
|
99
|
+
- Glassdoor / Blind sentiment (themes, not just score)
|
|
100
|
+
- Leadership style and management philosophy
|
|
101
|
+
- Known for: what do employees rave about? Complain about?
|
|
102
|
+
|
|
103
|
+
### 3. Tech & Process
|
|
104
|
+
- Tech stack (if engineering role)
|
|
105
|
+
- Known engineering practices / processes
|
|
106
|
+
- Product maturity: hypergrowth vs. scaled
|
|
107
|
+
|
|
108
|
+
### 4. Interview Process
|
|
109
|
+
- Known interview stages and format
|
|
110
|
+
- Common questions (from Glassdoor, Blind, LeetCode forums)
|
|
111
|
+
- Timeline from application to offer
|
|
112
|
+
|
|
113
|
+
### 5. Strategic Fit
|
|
114
|
+
- How does this company connect to my target roles and industries?
|
|
115
|
+
- What's the career trajectory from this role?
|
|
116
|
+
- Risks: stability, runway, market position
|
|
117
|
+
|
|
118
|
+
### 6. Conversation Starters
|
|
119
|
+
5 things I can mention in interviews that show I've done my homework.`,
|
|
120
|
+
}],
|
|
121
|
+
};
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
function buildCareerSummary(career) {
|
|
125
|
+
if (!career)
|
|
126
|
+
return "No career data available.";
|
|
127
|
+
const { profile, experience, skills } = career;
|
|
128
|
+
const topSkills = skills.slice(0, 10).map(s => s.name).join(", ");
|
|
129
|
+
const recentRoles = experience.slice(0, 3).map(e => `${e.role} at ${e.company}`).join("; ");
|
|
130
|
+
return `**Name:** ${profile.name}
|
|
131
|
+
**Summary:** ${profile.summary}
|
|
132
|
+
**Recent roles:** ${recentRoles || "None listed"}
|
|
133
|
+
**Key skills:** ${topSkills || "None listed"}
|
|
134
|
+
**Target roles:** ${profile.targetRoles.join(", ") || "Not specified"}
|
|
135
|
+
**Target industries:** ${profile.targetIndustries.join(", ") || "Not specified"}`;
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=opportunity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opportunity.js","sourceRoot":"","sources":["../../../src/tools/opportunity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { Pipeline } from "../schemas/career-schema.js";
|
|
3
|
+
import type { PipelineAddArgs, PipelineUpdateArgs, PipelineGetArgs, PipelineListArgs, ToolResponse } from "../types/tool-args.js";
|
|
4
|
+
export declare function handleAdd(args: PipelineAddArgs, pipeline: Pipeline): Promise<ToolResponse>;
|
|
5
|
+
export declare function handleUpdate(args: PipelineUpdateArgs, pipeline: Pipeline): Promise<ToolResponse>;
|
|
6
|
+
export declare function handleGet(args: PipelineGetArgs, pipeline: Pipeline): ToolResponse;
|
|
7
|
+
export declare function handleList(args: PipelineListArgs, pipeline: Pipeline): ToolResponse;
|
|
8
|
+
export declare function handleStats(pipeline: Pipeline): ToolResponse;
|
|
9
|
+
export declare function handleNextActions(pipeline: Pipeline): ToolResponse;
|
|
10
|
+
export declare function registerPipelineTools(server: McpServer): void;
|
|
11
|
+
//# sourceMappingURL=pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../../src/tools/pipeline.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EAAkC,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEvF,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,YAAY,EACb,MAAM,uBAAuB,CAAC;AAI/B,wBAAsB,SAAS,CAAC,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC,CA4BhG;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,kBAAkB,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC,CAqBtG;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,QAAQ,GAAG,YAAY,CAIjF;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,gBAAgB,EAAE,QAAQ,EAAE,QAAQ,GAAG,YAAY,CA4BnF;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,QAAQ,GAAG,YAAY,CA8B5D;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,YAAY,CAsClE;AAID,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAkJ7D"}
|