CalisthenicsCompanion-MCP
# CalisthenicsCompanion-MCP
Local stdio MCP server for CalisthenicsCompanion.
**Package name:** `@gehlich/calicomp-mcp`
## Purpose
Allows an LLM client (e.g. Claude Desktop) to read a user's locally-decrypted
training data and propose plan updates — without any direct mutations.
## Repository Layout
```
CalisthenicsCompanion-MCP/
├── src/
│ ├── index.ts # Fail-fast entry point, MCP server setup
│ ├── crypto.ts # AES-256-GCM decrypt (parity with Android CryptoManager)
│ ├── http.ts # Authenticated HTTP client for /api/mcp/data/pull
│ ├── cache.ts # In-memory snapshot cache (TTL 60 s)
│ ├── types.ts # TypeScript types (DecryptedSnapshot, etc.)
│ ├── schemas.ts # Zod schemas for tool inputs
│ ├── e1rm.ts # Epley e1RM formula (parity with Android)
│ └── tools/ # Tool handlers (get_profile, list_templates, …)
├── tests/
│ ├── startup.test.ts # Fail-fast env-check spawn tests
│ ├── crypto.test.ts # AES-256-GCM cross-language parity fixture test
│ └── …
├── package.json
├── tsconfig.json
├── tsup.config.ts
├── vitest.config.ts
└── .eslintrc.json
```
## Required Environment Variables
| Variable | Description |
|----------|-------------|
| `CALICOMP_PAT` | Personal Access Token (prefixed `calicomp_pat_`). Created in the CalisthenicsCompanion app. |
| `CALICOMP_KEY` | AES-256 encryption key in raw base64 (no prefix). Exported from the app alongside the PAT. |
| `CALICOMP_SERVER_URL` | *(Optional)* Override the API base URL. Defaults to `https://api.calicompanion.de`. |
## Transport
Runs as a local stdio MCP server. The LLM client communicates via JSON-RPC 2.0
over stdin/stdout. All diagnostics are written to stderr only — stdout is the
exclusive JSON-RPC channel.
## Usage
```json
{
"mcpServers": {
"calicomp": {
"command": "npx",
"args": ["-y", "@gehlich/calicomp-mcp"],
"env": {
"CALICOMP_PAT": "<your-pat>",
"CALICOMP_KEY": "<your-key-base64>"
}
}
}
}
```
## Building
```bash
npm install
npm run build # tsup → dist/index.js (shebang'd, single-file ESM)
npm run lint # ESLint no-console gate
npm run typecheck # tsc --noEmit
npm test # vitest run
```
TDQS
Scored across 19 tools
The read-path tools (get_training_state, get_stats, get_adherence, get_progress, get_history) share statistical scope, but each has explicit carve-outs for what it does and does not return, which prevents serious misselection. The propose_* and suggestion tools are cleanly distinct from each other and from the reads.
All tool names follow a consistent verb_noun snake_case pattern: get_* for reads, list_* for collections, propose_* for proposals, set_* for parameters, and withdraw_* for the one mutating exception. There is no mixed casing or vague verb usage.
At 19 tools, the server is slightly above the ideal 3-15 band, but the count is justified by the breadth of the coach workflow: reads, analytics, parameters, proposals, and suggestion management. The set feels dense rather than bloated.
The tool surface covers the full coach workflow: raw history, computed training state, adherence, progress, templates, planned workouts, catalog, coach parameters, and proposal-based changes for plans, exercises, and calendar events, plus suggestion lifecycle management. Intentional gaps like accept/reject are external to the MCP boundary and clearly documented.