@mohit-p41/athennian-mcp
v0.3.0
Published
MCP server connecting Claude to Athennian — query corporate records, governance, share capital, and registrations through natural language.
Downloads
274
Maintainers
Readme
Athennian Connector
Connects Claude to Athennian — the legal-entity management platform for corporate records, governance, and compliance. Ask Claude natural-language questions about your entities, directors, registrations, share capital and loans, and it answers using your live Athennian data.
v1 ships read-only by default. The 24 mutation tools (create entity, issue shares, record loan draws, etc.) stay in the source but are gated behind an env flag. Flip the flag when you're ready to allow writes. See Enabling write operations below.
What you get
15 read tools that cover entities, affiliations (officers/directors), shareholdings & cap tables, share transactions, documents, minute books, registrations, people, loans, loan transactions, tasks, access groups, share classes, users — plus two escape hatches (graphql raw passthrough, introspect_schema).
4 skills — playbooks that guide Claude through chained workflows:
| Skill | What it does | Mode |
|---|---|---|
| entity-consistency-check | Systematic audit of entity records for inconsistencies, missing documents, compliance gaps | Read-only |
| share-register-report | Cap-table analysis, certificate reconciliation, ownership breakdowns | Read-only |
| compliance-dashboard | Registration-expiry tracking, AGM and filing-status checks, board-composition review | Read-only |
| entity-management, onboard-entity, manage-loans, manage-registrations, manage-share-capital | Guided create/update flows | Require writes enabled |
Quick start (5 minutes)
1. Get an API key
Follow Athennian's API Setup guide. The key looks like <uuid>+<tenantId> (e.g. 3294a0a6-18b2-497b-8aca-f4a8c85c01fa+1111142).
2. Verify your setup with --doctor
Before touching Claude, run the preflight diagnostic. It checks Node version, key format, endpoint reachability, and runs a live sample query — all in about five seconds:
ATHENNIAN_API_KEY='<your-key>' \
npx @mohit-p41/athennian-mcp --doctorYou should see:
Athennian MCP — doctor
✓ Node v20.19.5 detected (need ≥ 20)
✓ Athennian MCP server v0.3.0
✓ ATHENNIAN_API_KEY set
✓ API key format looks valid (UUID + tenant suffix)
✓ Endpoint resolved: REGION=ca ENVIRONMENT=production → …
✓ Endpoint reachable — 200 OK in 142ms
✓ Sample query succeeded — entities(limit:1) returned 1 row
⚠ Writes: disabled (set ATHENNIAN_ENABLE_WRITES=1 to enable mutations)
All 7 checks passed. You're ready to connect Claude.If anything is red, the doctor tells you exactly what to fix. Once it's all green, proceed.
3. Wire it into Claude
Claude Desktop (macOS)
Edit ~/Library/Application Support/Claude/claude_desktop_config.json and add the athennian entry under mcpServers:
{
"mcpServers": {
"athennian": {
"command": "npx",
"args": ["-y", "@mohit-p41/athennian-mcp"],
"env": {
"ATHENNIAN_API_KEY": "<your-key>",
"ATHENNIAN_REGION": "ca",
"ATHENNIAN_ENVIRONMENT": "production"
}
}
}
}Fully quit Claude Desktop (⌘Q) and reopen it. The athennian tools appear in the tools picker.
Claude Code (CLI)
claude mcp add athennian -s user \
-e ATHENNIAN_API_KEY='<your-key>' \
-e ATHENNIAN_REGION=ca \
-e ATHENNIAN_ENVIRONMENT=production \
-- npx -y @mohit-p41/athennian-mcpThen start a new Claude Code session. /mcp shows athennian: connected.
4. Try it
| Ask Claude | What happens |
|---|---|
| "List the first 5 entities." | athennian_list_entities returns five rows. |
| "Show me all directors for Acme Holdings." | list_entities → find Acme → get_affiliations filtered to active directors. |
| "Generate a cap table for Acme Holdings." | Triggers the share-register-report skill — pulls share classes and holdings, produces a structured ownership report. |
| "What registrations are expiring in the next 90 days?" | Triggers the compliance-dashboard skill. |
| "Run a consistency check on our Luxembourg fund entities." | Triggers the entity-consistency-check skill — flags missing documents, governance gaps, and expired filings. |
Configuration reference
| Env var | Required | Default | Description |
|---|---|---|---|
| ATHENNIAN_API_KEY | yes | — | Athennian API key (<uuid>+<tenantId> format). |
| ATHENNIAN_REGION | no | ca | One of ca, us, me, eu. |
| ATHENNIAN_ENVIRONMENT | no | production | One of production, sandbox, labs. |
| ATHENNIAN_GRAPHQL_URL | no | — | Escape hatch for tenant-specific endpoints (e.g. https://<tenant>api.test.athennian.com/graphql). When set, overrides REGION/ENVIRONMENT. |
| ATHENNIAN_ENABLE_WRITES | no | unset (writes disabled) | Set to 1, true, or yes to expose the 24 mutation tools. |
| MONOCLE_ENABLED | no | unset (no tracing) | Set to 1, true, or yes to emit OTel spans via Monocle. See Observability. |
| MONOCLE_FILE_OUT_PATH | no | .monocle | When MONOCLE_ENABLED is set, directory where Monocle writes span JSON files. |
| MONOCLE_MCP_WORKFLOW | no | athennian-mcp | OTel service.name for spans this server emits. Override when running multiple MCP instances side-by-side. |
| MONOCLE_EXPORTER_DELAY | no | 5000 ms | Batch-flush interval for Monocle. Lower it (e.g. 500) in dev for faster feedback. |
Enabling write operations
V1 ships read-only by default — mutations are dark to Claude. To enable them:
- Confirm with whoever owns the Athennian tenant that automated writes are OK.
- Add
"ATHENNIAN_ENABLE_WRITES": "1"to theenvblock in your Claude config. - Restart Claude Desktop, or re-register the Claude Code MCP entry.
- Verify with
--doctor— the writes line flips from⚠ disabledto⚠ enabled.
Risks worth knowing:
- The mutation tools talk directly to your Athennian tenant. There's no built-in confirmation prompt, no audit log distinct from Athennian's own, no dry-run mode. Anything Claude calls is a real change.
- Workstream A coercion fixes mean malformed inputs throw a readable error before hitting the network, but they don't catch intent errors (Claude calling the wrong tool with valid args).
- Consider scoping the API key to a non-production tenant first, especially the first time you try a write skill.
When in doubt, leave the flag unset.
Observability (Monocle tracing)
The server can emit OpenTelemetry spans through Monocle so admins can query "which tools are slow?", "what's the 401 rate?", "which write call failed and why?". Disabled by default — opt-in via MONOCLE_ENABLED=1.
To enable — add to your Claude config env block:
"MONOCLE_ENABLED": "1",
"MONOCLE_FILE_OUT_PATH": "/path/to/.monocle"Restart Claude. The startup log line will include monocle ready · workflow=athennian-mcp …, and --doctor will report ⚠ Monocle: enabled.
What gets captured. Every tools/call produces a root span named athennian.tool.<name> (e.g. athennian.tool.athennian_list_entities). Each GraphQL request to Athennian produces a child span named athennian.graphql.<OperationName> (e.g. athennian.graphql.ListEntities). Both inherit scope attributes:
| Attribute | Example | Use |
|---|---|---|
| scope.tool | athennian_get_affiliations | Filter spans by tool |
| scope.request_id | UUID | Correlate parent + child spans for one tool call |
| scope.writes_mode | enabled | disabled | See whether writes were live when a span was emitted |
| mcp.arg_keys | entityId,roles,computedStatuses | Which args were supplied (keys only — values are never recorded, to avoid leaking entity data into traces) |
| http.status_code | 200, 401, 400 | GraphQL HTTP status (on the child span) |
| http.elapsed_ms | 1153 | GraphQL request latency |
| error.type / error.message | TypeError / Expected integer, got "x" | On failures, captured with the exception attached to the span |
Reading the traces. Point the monocle2ai-mcp server at the same MONOCLE_FILE_OUT_PATH and it'll answer admin questions like:
"Through monocle2ai-mcp, show me the slowest Athennian tool calls in the last hour."
"Group by
scope.tool— which tools are hit most often?""Find all traces with
error.type = TypeErrorto see coercion failures."
Notes:
- Spans are batched and flushed every
MONOCLE_EXPORTER_DELAYms (default 5000). Set it to500in dev for faster feedback. - Arg values are never traced — only the set of arg keys. This avoids leaking entity IDs, share counts, or PII into shared trace storage. If you need value-level detail for a specific debugging session, add it manually in a fork.
- The trace directory grows over time. Rotate or archive periodically.
- Disabling Monocle (unsetting the env var or setting
MONOCLE_ENABLED=0) is a no-op restart away — the tracing path becomes a zero-overhead pass-through.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Doctor: ✗ ATHENNIAN_API_KEY not set | Env var not passed to the shell | export ATHENNIAN_API_KEY=... (or set it in the Claude config env block) |
| Doctor: ✗ API key format unexpected | Pasted only the UUID portion | The +tenantID suffix is required; re-copy the full key from Athennian |
| Doctor: ✗ Endpoint returned 401 Unauthorized | Key valid format but rejected | Confirm the key is active and matches the region/environment you set |
| Doctor: ✗ Endpoint unreachable | DNS / VPN / tenant endpoint blocked | Check the URL; tenant test endpoints often require corporate VPN |
| Claude says it doesn't have Athennian tools | Claude wasn't fully restarted, or MCP config didn't load | Quit Claude entirely (⌘Q on macOS), reopen; check ~/Library/Logs/Claude/mcp-server-athennian.log |
| Tool call returns Error: Write tools are disabled. | Tried to create/update/delete without enabling writes | See Enabling write operations — but consider whether the action should really come from Claude |
| Read returns partial data with stderr "GraphQL partial errors" | Upstream has rows where Int fields are stored as "" | This is an Athennian-side data issue. The wrapper tolerates it and surfaces the good rows. File a ticket with Athennian. |
| node: bad option: --doctor | Running an old dist/ | Rebuild — npm run build in the servers/ directory, or npx -y @mohit-p41/athennian-mcp --doctor to fetch fresh |
For contributors
The MCP server is a single TypeScript file (~2.6k LOC) at servers/src/athennian-mcp.ts. It compiles to servers/dist/athennian-mcp.js and ships that as the only runtime artifact.
git clone <repo-url>
cd athennian-mcp/servers
npm install
npm run build # tsc → dist/, then chmod +x
npm run doctor # local preflight (set env vars first)
npm run typecheck # tsc --noEmitThe servers/dist/athennian-mcp.js output has a shebang and is chmod +x by build, so you can also invoke directly:
ATHENNIAN_API_KEY='...' ./servers/dist/athennian-mcp.js --doctorRepo layout
athennian-mcp/
├── README.md # this file (customer-facing)
├── servers/
│ ├── src/athennian-mcp.ts # all server logic (single file)
│ ├── dist/athennian-mcp.js # compiled, executable (ignored by git)
│ ├── package.json # build/start/doctor/typecheck scripts
│ └── tsconfig.json # strict ES2022 NodeNext
├── skills/ # markdown playbooks loaded by Claude
│ ├── entity-consistency-check/
│ ├── share-register-report/
│ ├── SKILL.md # compliance-dashboard (misnamed file — todo)
│ ├── entity-management/ # write-dependent (⚠ banner)
│ ├── onboard-entity/ # write-dependent
│ ├── manage-loans/ # write-dependent
│ ├── manage-registrations/ # write-dependent
│ └── manage-share-capital/ # write-dependent
└── claude/ # contributor working notes (gitignored)Coercion helpers
The wrapper defends against the typed-wrapper bug class (empty strings leaking into GraphQL Int/Float/Date slots) via four helpers in servers/src/athennian-mcp.ts:
asInt(value, fallback?)— coerce toInt, throws on garbage, returns fallback for empty.asFloat(value, fallback?)— same shape forFloat.asDate(value)— coerce to ISO-8601, returnsundefinedfor empty (use withomitEmpty).omitEmpty(obj)— strips""/null/undefinedrecursively from a mutationinput/optionspayload. Defends against the read-roundtrip bug where a read can returncancellationDate: ""and an unmodified update would re-trip the same schema error.
If you add a handler that takes numeric or date args, route them through these.
License
TBD — pending repository owner.
