Open sourceReleased

talent-mcp

An MCP server in C# that gives AI agents typed, secured tools for recruiting, built on the session-less 2026-07-28 protocol revision.

Six typed tools for job search, candidate-fit scoring and skill extraction, over stateless Streamable HTTP with OAuth 2.1 + PKCE, and the same six over stdio as a dotnet tool. Published on NuGet.

Role:
Design and development
Year:
2026
typed tools, each behind its own OAuth scope
6
LLM calls: deterministic, zero-cost scoring
0
cold start of the dotnet tool, measured in CI
323 ms
test levels that gate every merge
5

The problem

AI agents are only as useful as the tools they can call safely. The 2026-07-28 revision of the Model Context Protocol removed sessions and server-initiated requests, which breaks the usual ways of paging results and of asking the user for confirmation. talent-mcp is a reference server for that revision, in a domain where mistakes are costly: recruiting.

Constraints

  • No server sessions: any replica must be able to serve any request
  • Destructive actions need explicit confirmation, without server-initiated requests
  • Authorization per tool: read, write and destructive scopes are not interchangeable
  • Reproducible results, so the scoring can serve as a test oracle

How it works

  1. Clean Architecture with the dependency rule enforced by architecture tests in CI. Domain references nothing; Application holds the use cases and ports; Infrastructure holds the EF Core, Keycloak and OpenTelemetry adapters.
  2. The six tools live in one project that two hosts share verbatim: an ASP.NET Core Streamable HTTP server shipped as a container image, and a stdio host shipped as a dotnet tool.
  3. State between calls travels as a signed, time-limited handle passed back as an ordinary tool argument. The client’s trace context arrives in _meta, so a single trace spans client, server and PostgreSQL.

Key decisions

No LLM inside the server

Scoring and skill normalization are pure functions, so the server needs no API keys, costs nothing to run and returns the same answer every time.

Trade-off: Less flexible than asking a model; the agent on the other side brings the language understanding.

Signed handles instead of sessions

Pagination state is encoded, signed and time-limited inside the handle itself, so the HTTP host scales horizontally with no sticky sessions and no shared cache.

Trade-off: Handles are opaque and they expire; a client that holds one too long has to search again.

Tools registered explicitly, not by assembly scan

A trimmed build that silently drops its tools answers -32601 with no crash and no error log. Explicit registration, plus a conformance test that asserts all six tools by name, makes that failure loud.

Trade-off: Adding a tool means touching the registration as well as writing the tool.

Results

  • Published on NuGet as a reusable toolkit library and as the talent-mcp dotnet tool, with a container image on GHCR.
  • Five test levels gate every merge, from architecture rules to end-to-end runs through OAuth and PostgreSQL.
  • The Tasks store is verified to survive a database restart, recovering its connections in about a second.
  • Cold start of the installed dotnet tool measured in CI at 323 ms.

Stack

  • .NET 10
  • C#
  • Model Context Protocol
  • OAuth 2.1
  • Keycloak
  • PostgreSQL
  • OpenTelemetry
  • Docker