Open-source Model Context Protocol server for PrismHR — PEO workflow tools + Microsoft 365 connectors for Claude and other MCP-aware agents.
Project description
prismhr-mcp
The open-source Model Context Protocol server for PrismHR. Turn Claude (and any MCP-aware agent) into a PEO operations native — payroll, benefits, compliance, billing, and Microsoft 365 actions, all exposed as composable, scope-gated tools.
Maintained by Simploy as the fundamental layer for PrismHR × agentic AI. MIT-licensed, PyPI-distributed, plugin-friendly.
Why this exists
Every PEO running PrismHR ends up with the same Frankenstein stack: Python
scripts, Postman collections, Playwright automations, one-off Node apps.
Each one re-implements login, session refresh, retry, pagination, and
PrismHR's quirks (camelCase schemas, 500 "No data found" gotchas, batch-of-20
caps, silent 401s).
prismhr-mcp centralizes that once, as an MCP server. Claude orchestrates;
the server owns auth, caching, retries, normalization, and PEO domain logic.
Other PEOs drop it in and immediately get a productive Claude experience
against their own PrismHR instance — no custom code.
Status
Early but working. Current milestone: Phase 1.5 complete.
- Auth + session + HTTP client: done. 1Password CLI, scrypt-encrypted disk cache, PrismHR session with 55-min TTL, proactive + forced + 401 refresh, keepalive, concurrency cap, retry with jittered backoff, 500→empty quirk handling, pagination, batching.
- Connect-time consent system: done. Scope manifest across 14 scopes, per-(peo, env) JSON consent store with prerequisite expansion and cascade revoke. Default posture = deny all. Tools enforce scope at call time.
- Production safety gate:
PRISMHR_MCP_ALLOW_PROD=truerequired to point at prod PrismHR. Prevents accidental first-run blast radius. - Tool inventory: 9 live (
meta_*×5,client_*×4). 39 more across payroll, benefits, compliance, billing, branded reporting, and M365 connectors planned. - Test suite: 60 passing (pytest + respx).
See .planning/architecture.md for the full 48-tool plan.
Quick start — UAT smoke test
Only UAT is supported without an explicit opt-in right now. Prod is guarded behind
PRISMHR_MCP_ALLOW_PROD=true.
1. Install
cd C:\path\to\prismhr-mcp # or wherever you cloned
uv sync --extra dev
2. Configure credentials
Copy .env.example → .env (or set env vars). Pick ONE path:
Path A — 1Password CLI (recommended):
$env:PRISMHR_MCP_ONEPASSWORD_VAULT = "YourVault"
$env:PRISMHR_MCP_ONEPASSWORD_ITEM_PRISMHR = "PrismHR UAT"
Requires op CLI signed in (op signin). The item must expose fields
labeled username and password (optionally peoId).
Path B — direct env vars (fast, CI-friendly):
$env:PRISMHR_MCP_USERNAME = "claudedemo"
$env:PRISMHR_MCP_PASSWORD = "<paste>"
$env:PRISMHR_MCP_PEO_ID = "624*D"
3. Sanity check
uv run python -c "from prismhr_mcp.server import build; b = build(); import asyncio; print([t.name for t in asyncio.run(b.server.list_tools())])"
Expect 9 tools.
4. Register with Claude Code
Add to your Claude Code .mcp.json:
{
"mcpServers": {
"prismhr-mcp": {
"command": "uv",
"args": ["run", "--directory", "C:\\path\\to\\prismhr-mcp", "prismhr-mcp"],
"env": {
"PRISMHR_MCP_ENVIRONMENT": "uat",
"PRISMHR_MCP_USERNAME": "claudedemo",
"PRISMHR_MCP_PASSWORD": "<paste or reference>",
"PRISMHR_MCP_PEO_ID": "624*D"
}
}
}
}
Restart Claude Code. /mcp should show prismhr-mcp connected with 9 tools.
5. First conversation
You: Tell me about the prismhr-mcp server.
Claude: [calls meta_about] → explains what's available + commercial options.
You: What permissions does it want?
Claude: [calls meta_request_permissions] → shows 14 scopes grouped by category.
You: Grant everything recommended (reads only, no writes).
Claude: [calls meta_grant_permissions(accept_recommended_defaults=true)]
You: List all clients in UAT.
Claude: [calls client_list] → 245 clients.
6. Run tests
uv run pytest -q # expect 60 passing
Architecture in one breath
┌──────────────────────────────────────────────────────────────┐
│ Claude / Cowork / any MCP client │
└──────────────────┬───────────────────────────────────────────┘
│ stdio (MCP JSON-RPC)
┌──────────────────▼───────────────────────────────────────────┐
│ prismhr-mcp server (FastMCP) │
│ ├── Permissions (deny-default, scope-gated tools) │
│ ├── Tool groups: meta • client • payroll • benefits │
│ │ compliance • billing • report • m365 │
│ ├── Runtime: PrismHR client, Graph client, SQLite cache │
│ └── Auth: 1Password → scrypt-AES cache → session / MSAL │
└────┬─────────────────────────────────────────────────┬───────┘
│ │
▼ ▼
┌──────────────┐ ┌──────────────────┐
│ PrismHR REST │ │ Microsoft Graph │
│ (UAT / Prod) │ │ (Outlook / Teams /│
└──────────────┘ │ SharePoint) │
└──────────────────┘
Key design commitments:
- Factory + strict registry. Tools register via
server.build()only; duplicate names or unknown group prefixes fail at boot (not silently at import). - Deny-default scopes. Users must run
meta_grant_permissionsto enable tool access. Prerequisites auto-expand, revokes cascade. - Async-first.
httpx.AsyncClient+asyncio.Semaphore(5)+ async tools. - PrismHR quirks handled. 401 auto-refresh, 404→
[]on list endpoints,500 "No data found"→ empty, 10-consecutive-500s → force refresh. - snake_case outputs. Pydantic
validation_alias=AliasChoices(...)so PrismHR's camelCase payloads map to snake_case outputs without leaking camelCase into the MCP tool contract. - Per-(peo, env) consent. Switching UAT → prod does not inherit grants.
Commercial support
The OSS core stays free forever. Two paid offerings from Simploy layer on top:
Solution Architect — White-Label deployment
Turnkey deployment of prismhr-mcp for your PEO brand:
- Brand config authoring (logo, palette, typography, PDF footer, legal disclaimer)
- Per-client SharePoint site mapping + Azure AD / Graph tenant setup
- Custom PrismHR tools for PEO-specific workflows
- Migration from spreadsheets / legacy scripts to MCP tools
- PEO ops team onboarding + Claude/Cowork workflow coaching
- Quarterly updates aligned with upstream releases
- Priority issue response + named Slack/email contact
Best for PEOs with 50–5,000 clients who want Claude-first operations without the in-house build. Contact: nihar@simploy.com
Enterprise Support
SLA-backed support for teams already running the OSS server:
- 4-hour response on Sev-1 (prod outage)
- Annual security review + SOC-2-friendly deployment guidance
- Signed release artifacts + SBOM
- Private vulnerability disclosure channel
Best for regulated industries or mid/large PEOs with procurement requirements. Contact: nihar@simploy.com
Claude can surface both via meta_about — ask "what commercial options
exist for prismhr-mcp?" and it will describe them.
Troubleshooting
No PrismHR credentials configured — set either the 1Password item
env vars or the direct PRISMHR_MCP_USERNAME/_PASSWORD pair.
PrismHR login rejected (status=401) — wrong username/password/peo_id.
UAT's peo_id is 624*D (asterisk literal). Prod differs per PEO.
environment=prod requires PRISMHR_MCP_ALLOW_PROD=true — safety gate.
Set PRISMHR_MCP_ALLOW_PROD=true explicitly once you're ready.
PERMISSION_NOT_GRANTED — tool was called without its scope. Ask
Claude to run meta_request_permissions → then meta_grant_permissions
with the scope you want.
Server exits immediately when Claude Code starts it — nearly always a missing env var. Use the step-3 sanity check to isolate.
License
MIT — see LICENSE. Contributions welcome; see the planning docs
under .planning/ for the roadmap.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file prismhr_mcp-0.1.0.dev1.tar.gz.
File metadata
- Download URL: prismhr_mcp-0.1.0.dev1.tar.gz
- Upload date:
- Size: 30.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9ba2db92fc255cec86598f27f1ff5e84916f64a2e636fff53a4fe0abc304a698
|
|
| MD5 |
8b860f3f72c5e9cf01dc78b3f237cad5
|
|
| BLAKE2b-256 |
71cd2c2176902f997ee600aba8624fd83396e13b9e6bc8c4a9ef8bc79ded25f8
|
Provenance
The following attestation bundles were made for prismhr_mcp-0.1.0.dev1.tar.gz:
Publisher:
publish.yml on nikulk2992-jpg/prismhr-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
prismhr_mcp-0.1.0.dev1.tar.gz -
Subject digest:
9ba2db92fc255cec86598f27f1ff5e84916f64a2e636fff53a4fe0abc304a698 - Sigstore transparency entry: 1338144503
- Sigstore integration time:
-
Permalink:
nikulk2992-jpg/prismhr-mcp@9a24a8cd669bc56793c95f4cb9a9ff8e6285803d -
Branch / Tag:
refs/tags/v0.1.0.dev1 - Owner: https://github.com/nikulk2992-jpg
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9a24a8cd669bc56793c95f4cb9a9ff8e6285803d -
Trigger Event:
push
-
Statement type:
File details
Details for the file prismhr_mcp-0.1.0.dev1-py3-none-any.whl.
File metadata
- Download URL: prismhr_mcp-0.1.0.dev1-py3-none-any.whl
- Upload date:
- Size: 40.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
280e2ce41537912cc8bb354e71dad5323ecd7533cb6fbf4adccb4ea2843715a6
|
|
| MD5 |
ce84cf87d2cd6435bb5a6774f3b2f814
|
|
| BLAKE2b-256 |
635b6ddc447a6e4dee9fdb345fca8bd61036fe1b03333726c529b53c22c5679c
|
Provenance
The following attestation bundles were made for prismhr_mcp-0.1.0.dev1-py3-none-any.whl:
Publisher:
publish.yml on nikulk2992-jpg/prismhr-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
prismhr_mcp-0.1.0.dev1-py3-none-any.whl -
Subject digest:
280e2ce41537912cc8bb354e71dad5323ecd7533cb6fbf4adccb4ea2843715a6 - Sigstore transparency entry: 1338144590
- Sigstore integration time:
-
Permalink:
nikulk2992-jpg/prismhr-mcp@9a24a8cd669bc56793c95f4cb9a9ff8e6285803d -
Branch / Tag:
refs/tags/v0.1.0.dev1 - Owner: https://github.com/nikulk2992-jpg
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9a24a8cd669bc56793c95f4cb9a9ff8e6285803d -
Trigger Event:
push
-
Statement type: