Featured project
MCP server for resume tools
At a glance: Protocol-layer surface for the same tool contracts as the chat loop, with cross-language schema parity tests—not a second ad hoc integration.
Same seven resume tools as the web chat, exposed over the Model Context Protocol for Claude Desktop and other MCP hosts—load the same resume.json, get the same JSON tool results. Schema files are parity-tested against the .NET API so contracts cannot drift quietly.
What it is
A small Node.js stdio server using @modelcontextprotocol/sdk. It registers the same seven tools the portfolio chat uses, reads the same resume.json, and returns JSON tool results Claude Desktop (or any MCP client) can cite—no duplicate business logic in a second HTTP API.
Why I built it
Recruiters and hiring managers increasingly live in agent hosts, not just browsers. MCP is the protocol those hosts use to attach structured capabilities. Shipping a server that exposes my résumé as tools is the smallest credible proof that I can work at the protocol layer—not only behind a bespoke SSE endpoint.
Capability claim
What this shows about how I work
Contracts stay honest when one schema source feeds both surfaces. The .NET test suite loads mcp/schemas/*.json and asserts deep equality with ResumeToolInputSchemas, so Anthropic tool definitions and MCP tool definitions cannot drift silently. That is the same instinct as evals on the chat loop: make regressions a failing test, not a surprise in prod.
Try it
Build the server, then wire Claude Desktop (or Claude Code) to run node dist/index.js with --data pointing at your checkout of resume.json. Full copy-paste config lives in the repo README below.
"mcpServers": {
"portfolio-resume": {
"command": "node",
"args": [
"<absolute-path>/mcp/dist/index.js",
"--data",
"<absolute-path>/api/Portfolio.Api/Data/resume.json"
]
}
}See mcp/README.md in the repository for build steps and notes.
How it works
- On startup the process parses
--dataand loads JSON once (local path or HTTPS). tools/listreturns the seven tools with descriptions aligned toResumeToolDefinitions.tools/callvalidates arguments (same shape as the API), runs the handler, and responds with a text content block containing JSON—matching what the chat loop expects from tool results.
Risks and tradeoffs
Handlers are ported to TypeScript, so behavioral parity relies on tests and code review—not a shared library. The schema parity tests lock the wire contract; golden fixtures against the .NET ResumeTools would be the next tightening step if this grows.
What I learned
MCP wants stdio discipline: anything printed to stdout corrupts the JSON-RPC stream, so logging belongs on stderr. Keeping schemas as checked-in JSON files makes cross-language contract tests trivial compared to codegen from a single IDL—good enough for seven tools and a stable résumé payload.
What is next
Optional npm publish under a scoped name, plus a short recorded walkthrough for this page. If the handlers ever diverge, add shared JSON golden outputs from the API test suite and assert equality from both runtimes.
Source
Main files for this project:
mcp/src/index.ts— stdio server and tool registration.mcp/src/resumeTools.ts— tool handlers mirroring the API.mcp/schemas/*.json— Anthropic-compatible input schemas shared with parity tests.