@gfnord/mcp-d4h
v0.4.0
Published
Model Context Protocol (MCP) server exposing the D4H Team Manager API (spec v7.0.1, URL prefix /v3) to LLM hosts.
Maintainers
Readme
mcp-d4h
A Model Context Protocol server that lets LLM hosts (Claude Desktop, etc.) talk to the D4H Team Manager API (spec version 7.0.1, URL prefix
/v3) — read personnel, qualifications, and equipment — through one stdio MCP server.
┌─────────────────┐ stdio JSON-RPC ┌──────────────────┐ HTTPS ┌──────────────────────┐
│ Claude Desktop │ ◀───────────────▶ │ mcp-d4h │ ─────────▶ │ D4H Team Manager API │
│ (or any MCP │ │ (this server) │ │ (v7.0.1, /v3) │
│ host) │ │ │ └──────────────────────┘
└─────────────────┘ └──────────────────┘See D4H's own API Quick Start Guide for background on Personal Access Tokens and the Team Manager API surface.
Tools
26 tools total — 13 read, 10 mutating (default dry_run: true), and 3 stubs registered as unavailable (registered for LLM discoverability; return a structured "unavailable" response pointing at the D4H web interface).
Read tools (13)
| Tool | What it does |
|-----------------------------------|-------------------------------------------------------------------------------|
| get_members | List/search team members by status, role, contact info. |
| get_member | Get the full detail record for one team member by ID. |
| get_qualifications | List the qualification catalog (templates/definitions). |
| get_member_qualification_awards | List per-member qualification awards (who holds what, expiry dates). |
| get_incidents | List incidents (real responses). |
| get_incident | Get the full detail record for one incident by ID. |
| get_exercises | List training exercises. |
| get_events | List routine events (meetings, fundraisers, etc.). |
| get_attendance | List attendance records (who attended what, with duration). |
| get_groups | List personnel groups (sub-teams). |
| get_tasks | List tasks (action items, follow-ups, repairs). |
| get_equipment | Search equipment inventory by status, location, owner, kind, ref, etc. |
| search_team | Heterogeneous global search across all resource types. |
Mutating tools (10) — all default dry_run: true
| Tool | What it does |
|-------------------------------|------------------------------------------------------------------------------------|
| create_event | Create a routine event. Requires startsAt, endsAt, referenceDescription. |
| create_exercise | Create a training exercise. Same required floor as create_event. |
| create_incident | Create an incident. Requires startsAt, referenceDescription. endsAt optional. |
| update_event | Update an existing event. ≥1 field required. |
| update_exercise | Update an existing exercise. ≥1 field required. |
| update_incident | Update an existing incident. Most common use: set endsAt to close it out. |
| create_equipment | Create a new equipment item. To assign to a member at creation, use location: { resourceType: "Member", id }. |
| update_equipment | Update equipment status/notes/flags. RETIRED status NOT supported via API. |
| add_member_qualification | Award a qualification to a member. Supports memberId: "me" for the caller. |
| manage_attendance | Add / update / remove attendance (POST / PATCH / DELETE). Only DELETE in server — attendance is an edge, not an entity. |
Stubs registered as unavailable (3)
| Tool | Why unavailable |
|-----------------------------------|------------------------------------------------------------------------------------------------------------------------------|
| assign_equipment_to_member | PATCH /equipment/{id} rejects every variant of location/member/assignedTo (HTTP 400, live-probed). Use the web UI. |
| unassign_equipment_from_member | Same constraint as assign_equipment_to_member. Use the web UI. |
| update_member_qualification | /member-qualification-awards has no PATCH/PUT verb. Awards are immutable via API. Use the web UI. |
dry_run pattern: every mutating tool defaults to
dry_run: true. The tool validates inputs and returns a structured preview of the HTTP request that would be sent — without sending it. Setdry_run: falseto actually send. Missing required fields return aneedsMoreInforesponse phrased as a question (the LLM naturally relays it to the user instead of fabricating values).
All tools return structured JSON. Errors come back as MCP results with isError: true and a descriptive message — the server itself never crashes on a failed API call. See docs/tools.md for full input schemas, examples, dry-run previews, needsMoreInfo shape, and per-tool round-trip recipes.
Quick start
Option A — Install from npm (recommended for end users)
The package is published as @gfnord/mcp-d4h
on the public npm registry. No clone needed — point your MCP host directly at
it via npx. Skip to Wire it into Claude Desktop
below for the config snippet.
If you want the mcp-d4h command on your PATH:
npm install -g @gfnord/mcp-d4h
mcp-d4h --help # or just `mcp-d4h` to boot the stdio serverThe same package is also mirrored to GitHub Packages at
https://npm.pkg.github.com. Installing from there requires a GitHub PAT
with read:packages scope and an .npmrc entry — most users should prefer
public npm.
Option B — Clone and build from source (for development)
git clone https://github.com/gfnord/mcp-d4h.git
cd mcp-d4h
npm install
npm run build
cp .env.example .env # fill in PAT + team ID
npm start # boots the stdio serverThe compiled entry is dist/index.js and is also exposed as a mcp-d4h
bin if you npm link or npm install -g ..
Requirements: Node.js 20+ and a D4H Personal Access Token (how to generate).
Configuration
Minimum environment variables:
| Variable | Required | Description |
|----------------------------|----------|----------------------------------------------------------|
| D4H_TEAM_MANAGER_API_KEY | yes | PAT scoped for the Team Manager API. |
| D4H_TEAM_ID | yes | Numeric team ID (from your Team Manager URL). |
| D4H_REGION | no | US (default), EU, or CA. |
| D4H_HTTP_TIMEOUT_MS | no | Per-request HTTP timeout in ms. Default 30000. |
If credentials are missing, the server still boots — tool calls simply return a clean "client not configured" error.
Full reference: docs/configuration.md.
Wire it into Claude Desktop
Edit the host config:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Linux / WSL2:
~/.config/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Recommended (uses the published npm package — zero local setup):
{
"mcpServers": {
"d4h": {
"command": "npx",
"args": ["-y", "@gfnord/mcp-d4h"],
"env": {
"D4H_TEAM_MANAGER_API_KEY": "tm_pat_xxxxxxxxxxxxxxxx",
"D4H_TEAM_ID": "12345",
"D4H_REGION": "US"
}
}
}
}Alternative (point at a local clone):
{
"mcpServers": {
"d4h": {
"command": "node",
"args": ["/absolute/path/to/mcp-d4h/dist/index.js"],
"env": {
"D4H_TEAM_MANAGER_API_KEY": "tm_pat_xxxxxxxxxxxxxxxx",
"D4H_TEAM_ID": "12345",
"D4H_REGION": "US"
}
}
}
}Restart Claude Desktop. The three d4h tools will appear and become callable
by the model.
Documentation
| Doc | Topic | |-----|-------| | docs/claude-desktop.md | 📘 End-to-end Claude Desktop setup with WSL2 + Windows host walkthrough | | docs/tools.md | Per-tool reference: inputs, outputs, examples | | docs/configuration.md | Env vars, PAT generation, regions, troubleshooting | | docs/architecture.md | System design, request lifecycle, error model, security | | docs/development.md | Dev workflow, adding tools, code style, release |
Project layout
mcp-d4h/
├── src/
│ ├── d4h.ts # Typed axios client for the Team Manager API
│ └── index.ts # MCP server + tool registrations + stdio bootstrap
├── docs/ # Architecture, tools, config, dev docs
├── dist/ # tsc build output (gitignored)
├── .env.example
├── package.json
├── tsconfig.json
└── README.mdLicense
MIT — see LICENSE.
