Skip to main content
Glama
jai2010
by jai2010
README.md
```
███████╗██╗  ██╗ ██████╗ ██████╗ ████████╗██╗  ██╗ █████╗ ███╗   ██╗██████╗     ███╗   ███╗███████╗███╗   ███╗
██╔════╝██║  ██║██╔═══██╗██╔══██╗╚══██╔══╝██║  ██║██╔══██╗████╗  ██║██╔══██╗    ████╗ ████║██╔════╝████╗ ████║
███████╗███████║██║   ██║██████╔╝   ██║   ███████║███████║██╔██╗ ██║██║  ██║    ██╔████╔██║█████╗  ██╔████╔██║
╚════██║██╔══██║██║   ██║██╔══██╗   ██║   ██╔══██║██╔══██║██║╚██╗██║██║  ██║    ██║╚██╔╝██║██╔══╝  ██║╚██╔╝██║
███████║██║  ██║╚██████╔╝██║  ██║   ██║   ██║  ██║██║  ██║██║ ╚████║██████╔╝    ██║ ╚═╝ ██║███████╗██║ ╚═╝ ██║
╚══════╝╚═╝  ╚═╝ ╚═════╝ ╚═╝  ╚═╝   ╚═╝   ╚═╝  ╚═╝╚═╝  ╚═╝╚═╝  ╚═══╝╚═════╝     ╚═╝     ╚═╝╚══════╝╚═╝     ╚═╝
```

<p align="center"><strong>Semantic compression for Claude — backed by a local MCP server</strong></p>
<p align="center">60–80% fewer tokens &nbsp;·&nbsp; persistent library &nbsp;·&nbsp; diff, merge, summarise &nbsp;·&nbsp; four document domains</p>

<p align="center">
  <a href="SKILL.md">Skill Docs</a> &nbsp;·&nbsp;
  <a href="shorthand-mem.skill">Install Skill</a> &nbsp;·&nbsp;
  <a href="https://github.com/jai2010/shorthand-mem/issues">Issues</a>
</p>

---

## What It Does

**shorthand-mem** compresses verbose documents into a structured symbolic notation (SHM), stores them in a local library, and reconstructs them on demand. It runs as a Claude skill in Claude.ai, backed by a local MCP server that handles all compression, retrieval, and library operations.

The skill itself is a thin routing layer — you type commands in Claude.ai, the skill calls your local MCP server, the server does the work, the result comes back to Claude.

```
Claude.ai (you type commands here)
         │
         ▼
shorthand-mem MCP server  ← runs on your machine
         │
         ├── SQUEEZE  → Claude Haiku (compression)
         ├── EXPAND   → Haiku / Sonnet / Opus (your choice, remembered)
         ├── DIFF     → structural token comparison
         ├── MERGE    → combine multiple squeezes
         └── SUMMARISE → 5-bullet plain English via Haiku
```

---

## ⚠️ What You Need

| Requirement | Why |
|---|---|
| **Claude.ai subscription** | To use the skill in chat |
| **Anthropic API key** | The MCP server calls Haiku/Sonnet directly from your machine |
| **Python 3.10+** | To run the MCP server |

The API key is set once as an environment variable — never stored in any file you push to GitHub. SQUEEZE always uses Haiku (~$0.0003 per 1 000-token document). EXPAND uses your chosen model.

---

## Installation

### 1. Clone and install

```bash
git clone https://github.com/jai2010/shorthand-mem.git
cd shorthand-mem
pip install -e .
```

### 2. Set your API key

```bash
cp .env.example .env
# Edit .env and add your key:
# ANTHROPIC_API_KEY=sk-ant-...

source .env
```

Or set it permanently in your shell profile:
```bash
echo 'export ANTHROPIC_API_KEY=sk-ant-your-key' >> ~/.zshrc
```

### 3. Register the MCP server with Claude

```bash
python install.py
```

This writes the server config to `~/.claude/claude_desktop_config.json` (Claude Desktop) and `~/.config/claude/mcp.json` (Claude Code). Restart Claude after running.

To uninstall:
```bash
python install.py uninstall
```

### 4. Install the skill in Claude.ai

1. Download [`shorthand-mem.skill`](./shorthand-mem.skill)
2. Go to **Claude.ai → Settings → Skills**
3. Click **Install Skill** and upload the file

---

## Commands

| Command | What It Does | Model |
|---|---|---|
| `SQUEEZE PRD \| CODE \| PAPER \| MEETING <text>` | Compress document into SHM notation | Haiku (always) |
| `EXPAND [label or SHM block]` | Reconstruct full prose | Your preference |
| `SET MODEL haiku \| sonnet \| opus` | Save EXPAND model preference | — |
| `LIST SQUEEZES` | Show library with compression stats | — |
| `RECALL [label]` | Retrieve a saved squeeze | — |
| `SEARCH [keyword or RISK( or REQ:]` | Search library — keyword or token-level | — |
| `DELETE [label]` | Remove a squeeze (asks for confirmation) | — |
| `EXPORT ALL` | Dump full library to `.shm` file | — |
| `DIFF [label1] [label2]` | Structural diff between two versions | — |
| `MERGE [label1] [label2] ...` | Combine squeezes under SCOPE headers | — |
| `SUMMARISE [label]` | 5-bullet executive summary (lossy) | Haiku (always) |

---

## Token Reference

### Universal — All Domains

| Token | Meaning |
|---|---|
| `OBJ(Name)` | Core entity, system, module, or actor |
| `SCOPE: Name` | Module or domain boundary |
| `GOAL(Action)` | Primary intent |
| `REQ: action()` | Strict functional mandate |
| `RULE: constraint` | Business logic, rate limit, or guardrail |
| `DEP(X)` | Dependency — `++` for hard/critical |
| `RISK(Factor)` | Failure mode — `++` for high severity |
| `ERR(Type) → THROW(Behaviour)` | Failure boundary |

**Conditional syntax:**
```
IF (condition) → THEN (action) ! EXCEPT (override_condition)
ELSE → (fallback_action)
```

### PAPER Domain

| `HYP` | `METH` | `RESULT` | `LIMIT` |
|---|---|---|---|
| Hypothesis | Methodology | Outcome | Limitation |

### MEETING Domain

| Token | Meaning |
|---|---|
| `DEC(Decision)` | Decision made |
| `ACT(Owner → Action → Date)` | Action item with owner and due date |
| `ESC(Risk → Owner)` | Escalation raised |
| `BLOCK(Item → Blocker → ETA)` | Blocker with expected resolution |

---

## Full Example: PRD Compression

### Input (~880 tokens)

> The Notification Delivery Service (NDS) routes alerts across in-app, email, and push. Critical notifications must be delivered within 5 seconds; Standard within 60 seconds. Email is routed through SendGrid — on a 5xx error or 3-second timeout, retry up to 3 times with exponential backoff starting at 500ms. After 3 failures, write to DeadLetterQueue and page PagerDuty. Push via FCM — if `push_enabled=false`, skip silently. If FCM returns token-expired, delete the stale token from UserDevices and skip. Hard dependency on UserPreferences — if unavailable, suspend all dispatches and queue for replay. Soft dependency on Analytics — if unavailable, send notification but drop the delivery event with a warning log. Rate limit: 50 notifications/user/hr across all channels. Excess: silently dropped + EventLog entry. Critical delivery failures must escalate to the engineering lead immediately.

### SQUEEZE PRD output (~195 tokens — 78% reduction)

```shm
@ASSET:PRD | @TARGET:60-80% | @CCR:a3f2b1c9 | @DATE:2025-06-24

OBJ(Notification_Delivery_Svc)
GOAL: Multi_channel_alert_routing(in-app, email, push)

IF (priority == Critical) → THEN (deliver <= 5s)
IF (priority == Standard) → THEN (deliver <= 60s)

REQ: Email_via_SendGrid
ERR(SendGrid_5xx || timeout>3s) → RETRY x3 | backoff(500ms, exponential)
IF (retry_count == 3 && fail) → WRITE(DeadLetterQueue) + PAGE(PagerDuty)

RULE: user.push_enabled == false → SKIP silently
ERR(FCM_token_expired) → DELETE(UserDevices.token) + SKIP

DEP(UserPreferences_Svc)++ → IF (unavailable) → SUSPEND_ALL + QUEUE_replay
RULE: NO notification WITHOUT confirmed_preference_lookup

DEP(Analytics_Svc) → IF (unavailable) → SEND + DROP(delivery_event) + WARN_LOG

REQ: RateLimit == 50 notifications/user/hr (all channels)
IF (rate_exceeded) → DROP silently + WRITE(EventLog.RateLimitExceeded)

RISK(Critical_delivery_failure)++ → ESCALATE(engineering_lead)
```

📊 Compression: ~880 → ~195 tokens (78% reduction)
🎯 Fidelity: 📅 0/0 dates · 💰 2/2 amounts · 🚦 0/0 statuses · 👤 6/6 entities

---

## MEETING Domain Example

```
SQUEEZE MEETING
Attendees: Jai, Priya, Rohan
Decision: Migrate billing to Stripe by Q3 2025.
Action: Rohan to complete API contract by Jul 15.
Action: Priya to sign off on compliance review by Jul 10.
Blocker: Legal approval pending — ETA Jul 8.
Escalation: Stripe SLA risk escalated to CTO.
```

```shm
@ASSET:MEETING | @TARGET:60-80% | @CCR:b7e3d2f1 | @DATE:2025-06-24

OBJ(Billing_Migration_Meeting)
DEC(Migrate billing to Stripe by Q3 2025)
ACT(Rohan → Complete API contract → Jul 15)
ACT(Priya → Sign off compliance review → Jul 10)
BLOCK(Legal_approval → Pending → Jul 8)
ESC(Stripe_SLA_risk → CTO)
```

📊 Compression: ~196 → ~42 tokens (79% reduction)
🎯 Fidelity: 📅 3/3 dates · 💰 0/0 amounts · 🚦 0/0 statuses · 👤 3/3 entities

---

## DIFF Example

Track what changed week-over-week in a SteerCo doc:

```
DIFF MEETING_steerco_2025-06-17 MEETING_steerco_2025-06-24
```

```
Summary: 🟢 2 added · 🔴 1 removed · 🟡 1 changed · ⚪ 8 unchanged

🟢 Added
  + ACT(Priya → Sign off compliance review → Jul 10)
  + ESC(Stripe_SLA_risk → CTO)

🔴 Removed
  - BLOCK(Procurement → Vendor shortlist → Jun 28)

🟡 Changed
  before: DEC(Evaluate Stripe migration)
  after:  DEC(Migrate billing to Stripe by Q3 2025)
```

---

## Token-Level SEARCH

Search your entire library for all instances of a specific token type:

```
SEARCH RISK(       → all risks across all squeezes
SEARCH DEC(        → all decisions across all meetings
SEARCH REQ:        → all requirements across all PRDs
SEARCH ACT(Rohan   → all actions assigned to Rohan
```

---

## Persistence & Library

```
LIST SQUEEZES

| # | Label                             | Domain  | Date       | Original   | Compressed | Saved |
|---|-----------------------------------|---------|------------|------------|------------|-------|
| 1 | PRD_notification_delivery_2025-06 | PRD     | 2025-06-24 | ~880 tok   | ~195 tok   | 78%   |
| 2 | MEETING_billing_migration_2025-06 | MEETING | 2025-06-24 | ~196 tok   | ~42 tok    | 79%   |
| 3 🧩 | PRD_large_spec_2025-06-24     | PRD     | 2025-06-24 | ~12,400 tok| ~890 tok   | 93%   |
```

🧩 = document was automatically chunked (exceeded single-context limit)

All squeezes stored at `~/.shorthand-mem/library.json`.
Original documents cached at `~/.shorthand-mem/ccr/` for lossless retrieval.

---

## File Structure

```
shorthand-mem/
├── SKILL.md                    ← Skill instructions (install in Claude.ai)
├── shorthand-mem.skill         ← Packaged skill file
├── install.py                  ← One-command MCP registration
├── requirements.txt
├── setup.py
├── .env.example                ← API key template
└── server/
    ├── main.py                 ← MCP server entry point (FastMCP)
    ├── store.py                ← Library, Settings, CCR store
    ├── utils.py                ← Chunking, fidelity, labelling, SHA-8
    └── tools/
        ├── squeeze.py          ← Haiku compression + chunking + fidelity
        ├── expand.py           ← Model-selectable expansion
        ├── library.py          ← LIST, RECALL, SEARCH, DELETE, EXPORT
        ├── diff.py             ← Structural token diff
        ├── merge.py            ← Multi-block merge
        └── summarise.py        ← 5-bullet executive summary
```

---

## Cost Reference

| Operation | Model | Approx. cost per 1 000-token doc |
|---|---|---|
| SQUEEZE | Haiku | ~$0.0003 |
| EXPAND | Haiku | ~$0.0003 |
| EXPAND | Sonnet | ~$0.003 |
| EXPAND | Opus | ~$0.015 |
| SUMMARISE | Haiku | ~$0.0001 |

Once compressed, RECALL, SEARCH, LIST, DIFF, and MERGE are free (no API calls).

---

## License

MIT