MCP Server
Read-only access to over 150 years of Major League Baseball data through the Model Context Protocol, for use with AI assistants and agents.
How it works
The server exposes 12 read-only tools and 6 JSON resources over
streamable HTTP at http://localhost:5190. Start the server yourself with
dotnet run --project baseball-history-mcp (or let the Aspire AppHost host it), then point
your MCP client at the URL. Health endpoints are available at /healthz and /alive.
- Requires a
ConnectionStrings:Lahmanvalue at startup. Placeholder strings containing<are rejected. - Every tool is read-only; the server never mutates data.
- Start with the
get_server_diagnosticstool or thebaseball-history://server/inforesource to discover the surface before calling domain tools.
Connecting
First start the server so the HTTP endpoint is listening. The server reads its database connection
string from the ConnectionStrings__Lahman environment variable (the .NET double-underscore
convention) or from user-secrets during local development — the client does not supply it.
ConnectionStrings__Lahman="Host=your-host;Database=baseball-history;Username=user;Password=secret" \
dotnet run --project /path/to/baseball-history-mcp
Then point your MCP client at http://localhost:5190/.
Claude Desktop / Claude Code
Add the server to your MCP configuration:
{
"mcpServers": {
"baseball-history": {
"type": "http",
"url": "http://localhost:5190/"
}
}
}
VS Code
Add a .vscode/mcp.json file:
{
"servers": {
"baseball-history": {
"type": "http",
"url": "http://localhost:5190/"
}
}
}
Example prompts
Once connected, ask your AI assistant questions like these. It will choose and call the right tool:
| Ask your AI assistant | Tool(s) used |
|---|---|
| “Find players whose last name starts with R” | search_players |
| “Show me Babe Ruth's career stats” | get_player |
| “Career home run leaders since 2000” | get_batting_leaders |
| “Lowest career ERA, minimum 1000 innings” | get_pitching_leaders |
| “Who was inducted into the Hall of Fame in 1999?” | list_hall_of_fame_inductees |
| “Mike Trout's salary history” | get_player_salary_history |
Tools
Players
- search_players Search players by free-text query or last-name prefix with paging.
- get_player Get read-only detail for one player, including career batting, career pitching, and team tenures.
Franchises & Teams
- list_franchises List franchise summaries with optional filters and bounded paging.
- get_franchise Get one franchise with season-by-season history.
- get_team_season Get one exact team-season by team id, league, and year so franchise-era lookups stay deterministic.
Leaderboards
get_batting_leaders
Read batting leaderboards in career or single-season form.
| Parameter | Type | Default | Description |
|---|---|---|---|
stat | string | hr | Stat to rank by: hr, h, r, rbi, sb, 2b, 3b, bb, g, ab, avg, obp, slg, ops |
fromYear | int? | — | Lower year bound |
toYear | int? | — | Upper year bound |
league | string | — | League filter (AL, NL) |
minAtBats | int | 0 | Minimum at-bats threshold |
singleSeason | bool | false | Single-season vs. career totals |
page | int | 1 | 1-based page |
pageSize | int | 50 | Page size (max 100) |
get_pitching_leaders
Read pitching leaderboards in career or single-season form. ERA, WHIP, and BB9 sort ascending (lower is better); all others descending.
| Parameter | Type | Default | Description |
|---|---|---|---|
stat | string | w | Stat to rank by: w, l, so, sv, cg, sho, ip, g, gs, hr, k9, wpct, era, whip, bb9 |
fromYear | int? | — | Lower year bound |
toYear | int? | — | Upper year bound |
league | string | — | League filter (AL, NL) |
minInningsPitched | int | 0 | Minimum innings-pitched threshold |
singleSeason | bool | false | Single-season vs. career totals |
page | int | 1 | 1-based page |
pageSize | int | 50 | Page size (max 100) |
Hall of Fame
- list_hall_of_fame_inductees List inducted Hall of Fame rows with optional year/category filters and bounded paging.
- get_hall_of_fame_voting_history Get bounded Hall of Fame voting history for one player. Rows are Lahman HallOfFame ballot rows, not a prose biography.
Salaries
- get_player_salary_history Get bounded salary history for one player, ordered most recent to oldest.
- get_salary_leaders List highest salary rows with optional year filter and bounded paging.
Diagnostics
- get_server_diagnostics Inspect safe runtime posture, configured limits, and connectivity without exposing secrets.
Resources
Read-only JSON documents the client can fetch to discover the server surface and usage guidance.
| URI | Purpose |
|---|---|
baseball-history://server/info | Server identity, startup requirements, and configured limits. |
baseball-history://server/workflow-guide | Routing for common question types to the right tool or guide. |
baseball-history://server/stats-catalog | Supported batting and pitching stat categories plus the supported year span. |
baseball-history://server/diagnostics | Safe runtime posture, configured limits, and connectivity. |
baseball-history://hall-of-fame/guide | Hall of Fame tool limits, year coverage, and voting-history caveats. |
baseball-history://salary/guide | Salary tool limits, year coverage, and how salary rows are shaped. |
Calling the server from code
Use the official MCP client SDK to connect to the running server over HTTP and call tools directly.
This C# example uses the ModelContextProtocol.Client package:
using ModelContextProtocol.Client;
var transport = new HttpClientTransport(new HttpClientTransportOptions
{
Name = "baseball-history",
Endpoint = new Uri("http://localhost:5190/")
});
await using var client = await McpClientFactory.CreateAsync(transport);
// Discover the available tools
foreach (var tool in await client.ListToolsAsync())
{
Console.WriteLine($"{tool.Name}: {tool.Description}");
}
// Call a tool
var result = await client.CallToolAsync(
"get_batting_leaders",
new Dictionary<string, object?>
{
["stat"] = "hr",
["fromYear"] = 2000,
["singleSeason"] = true,
["pageSize"] = 5
});
Console.WriteLine(result.Content[0].Text);
The same connect → list → call flow is available from the official Python and TypeScript MCP SDKs.
Limits & data notes
- Page sizes are capped: player search 100, franchise list 50, Hall of Fame 50, batting/pitching leaderboards 100, salary leaderboard 50.
- History is bounded: Hall of Fame voting history returns up to 25 years; salary history up to 40 seasons.
- All data is from the Lahman Baseball Database; the server is read-only.
- Player IDs follow the Lahman convention (e.g.
ruthba01,troutmi01); franchise IDs match Lahman codes (e.g.NYY); team-season lookups use team id, league, and year (e.g.NYA,AL, 1927). - Salary data is available from 1985 onward. Innings pitched is stored as outs and converted to innings (outs / 3).