Skip to main content
Glama
Packi1992

CalisthenicsCompanion-MCP

by Packi1992
README.md
# 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

A4.3/5.0

Scored across 19 tools

Disambiguation4/5

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.

Naming Consistency5/5

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.

Tool Count4/5

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.

Completeness5/5

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.