← Back to portfolio

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 --data and loads JSON once (local path or HTTPS).
  • tools/list returns the seven tools with descriptions aligned to ResumeToolDefinitions.
  • tools/call validates 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.
Node.jsTypeScriptMCPJSON Schema.NET parity tests

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.
View on GitHub →