Metadata-Version: 2.5
Name: codetherapy
Version: 0.1.0
Summary: Talk to your Claude Code projects — by voice, from the Claude app — about how they're doing.
Project-URL: Homepage, https://github.com/Rapideo/codetherapy
Project-URL: Issues, https://github.com/Rapideo/codetherapy/issues
Project-URL: Changelog, https://github.com/Rapideo/codetherapy/blob/main/CHANGELOG.md
Author: Rapideo
License-Expression: MIT
License-File: LICENSE
Keywords: claude,claude-code,connector,mcp,mcp-server,project-management,voice
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development
Requires-Python: >=3.12
Requires-Dist: mcp<3,>=2.3
Requires-Dist: uvicorn>=0.31
Description-Content-Type: text/markdown

# Code Therapy

*"Lie back. Tell me about your repo."*

[![PyPI](https://img.shields.io/pypi/v/codetherapy)](https://pypi.org/project/codetherapy/)
[![Python versions](https://img.shields.io/pypi/pyversions/codetherapy)](https://pypi.org/project/codetherapy/)
[![CI](https://github.com/Rapideo/codetherapy/actions/workflows/ci.yml/badge.svg)](https://github.com/Rapideo/codetherapy/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/Rapideo/codetherapy/blob/main/LICENSE)

Code Therapy is an MCP connector that lets you talk with an AI project manager that knows every Claude Code project on your machine. You can talk to it by voice in the Claude app, or type to it on claude.ai. It runs on your computer and reads your Claude Code session history, git, and project docs. From that it tells you where each project stands and what you worked on, finds things in the code, answers deeper questions, and writes your decisions back into the repo for your next coding session.

You're the manager. This is you checking in with your code about how it's doing.

## A session, in practice

> **You:** How's acme-api doing?
>
> **Claude:** acme-api is on the `rate-limits` branch with two uncommitted files. Your last session was "Add per-key rate limiting", and one to-do is still open: write the migration for the keys table.
>
> **You:** And what did I get done on storefront this week?
>
> **Claude:** Four sessions and nine commits. You finished the checkout redesign, fixed the coupon rounding bug, and started on order emails.
>
> **You:** Where's the rate limiter in acme-api? And how does it decide a key is over the limit?
>
> **Claude:** It's in `src/middleware/rate_limit.py`. For the how, I'll have Claude Code read the code, which can take up to a minute... It keeps a sliding one-minute window per API key and returns a 429 once the count passes that key's plan limit.
>
> **You:** Let's make the free tier 100 requests a minute. Write that down as a decision.
>
> **Claude:** Saved to acme-api's `PM_NOTES.md`: "DECISION: Free tier is 100 requests a minute."

## How it works

```mermaid
flowchart LR
  claudeApp["claude.ai / Claude app<br/>(via Anthropic's cloud)"] -->|HTTPS| tunnel["ngrok static domain<br/>name.ngrok-free.dev"]
  subgraph machine["Your machine"]
    ctServer["codetherapy<br/>127.0.0.1:8765"]
    sessionLogs["~/.claude/projects<br/>session logs"]
    gitRepo["git"]
    projectDocs["CLAUDE.md / README.md"]
    pmNotes["PM_NOTES.md"]
    claudeP["claude -p<br/>(read-only)"]
    ctServer --> sessionLogs
    ctServer --> gitRepo
    ctServer --> projectDocs
    ctServer -->|append only| pmNotes
    ctServer --> claudeP
  end
  tunnel --> ctServer
```

Claude calls your connector from Anthropic's cloud over HTTPS, and ngrok forwards each request to the `codetherapy` server, which listens only on 127.0.0.1. The server finds your projects in Claude Code's own session logs under `~/.claude/projects`, then builds briefs, activity and search results from those logs, git, and the project files, without calling any AI model. Deep questions run your own `claude` CLI headless and read-only inside the project folder, and decisions are appended to `PM_NOTES.md`. Nothing is uploaded on its own: tool results go to Claude in your conversation, and `ask_project`'s Claude Code sends the files it reads to Anthropic, just like a normal Claude Code session. ngrok relays the traffic and can see it (see the [security model](https://github.com/Rapideo/codetherapy#security-model)).

## Requirements

- A Claude **Pro, Max, Team or Enterprise** plan, for custom connectors.
- **Claude Code**, installed and used at least once in each project you want to talk about. The `claude` CLI must be on your PATH and logged in for `ask_project`. The other tools work without it.
- **Python 3.12+** via [uv](https://docs.astral.sh/uv/). uv installs Python for you if you need it.
- A free [ngrok](https://ngrok.com) account, or [your own tunnel](https://github.com/Rapideo/codetherapy#bring-your-own-tunnel).
- Windows, macOS or Linux.

## Quick start

0. **Before you start, do these once.**
   - Install [uv](https://docs.astral.sh/uv/getting-started/installation/).
   - Set up ngrok: install it, run `ngrok config add-authtoken <token>`, and copy your free static domain. See [ngrok, once](https://github.com/Rapideo/codetherapy#ngrok-once) for the details.
1. Install it with `uv tool install codetherapy`. If your shell then can't find `codetherapy`, run `uv tool update-shell` and open a new terminal. You can also run any command without installing, as `uvx codetherapy …`.
2. Run `codetherapy setup`. It checks your prerequisites and asks for your ngrok domain.
3. Run `codetherapy start`, and leave it running. It prints your connector URL and copies it to the clipboard.
4. Open <https://claude.ai/settings/connectors>, choose **Add custom connector**, and paste the URL. Then ask Claude, "What projects do I have?"

## Detailed setup

### ngrok, once

1. Sign up at <https://dashboard.ngrok.com/signup>. The free plan is enough.
2. Install ngrok:
   - **Windows:** `winget install ngrok.ngrok`
   - **macOS:** `brew install ngrok`
   - **Linux:** follow <https://ngrok.com/download>
3. Copy your authtoken from <https://dashboard.ngrok.com/get-started/your-authtoken> and run:

   ```sh
   ngrok config add-authtoken <token>
   ```

4. Find your free static domain under **Dashboard → Domains**. It looks like `name.ngrok-free.dev`. Using that domain keeps your connector URL the same every time you start.

### `codetherapy setup`

`setup` prints the config file it's using, then checks:

- that `claude` is on your PATH. If it isn't, you get a warning only, because only `ask_project` needs it.
- that ngrok is installed. On Windows it also looks in winget's install folders, since winget doesn't update the PATH of the shell you're already in.
- that ngrok has an authtoken.

It then asks for your ngrok static domain, unless you passed `--public-host` or saved one before. You can paste it with or without `https://`. It generates a random token and saves everything. If you run `setup` again, it keeps your token and any setting you don't change. Pass `--rotate` if you want a new token.

The config file is `config.env` in your per-user config folder:

| OS | Location |
|---|---|
| Windows | `%APPDATA%\codetherapy\config.env` |
| macOS | `~/Library/Application Support/codetherapy/config.env` |
| Linux | `$XDG_CONFIG_HOME/codetherapy/config.env` (default `~/.config/codetherapy/config.env`) |

On macOS and Linux the file is created with mode 600. It holds these keys:

- `CODETHERAPY_TOKEN`
- `CODETHERAPY_PUBLIC_HOST`
- `CODETHERAPY_PORT`, which defaults to 8765
- `CODETHERAPY_TUNNEL`, which is `ngrok` (the default) or `none`
- `CODETHERAPY_PROJECTS_DIR`, which defaults to `~/.claude/projects`

Environment variables with the same names override the file. To use a different file, pass `--config PATH` or set `CODETHERAPY_CONFIG`.

### Connecting claude.ai

- **Add the connector on the web.** Go to <https://claude.ai/settings/connectors> → **Add custom connector**, name it "Code Therapy", and paste the URL from `codetherapy start` (or `codetherapy url`). Leave the OAuth fields empty. On Team and Enterprise plans, an owner may need to allow custom connectors first.
- **Use it anywhere.** Once added, the connector appears in the Claude mobile and desktop apps too. You don't add it again there.
- **Turn it on in a chat.** Enable Code Therapy from the tools menu in the chat composer.
- **Allow it on first use.** The first time Claude calls one of its tools, claude.ai asks for permission. Allow it, or choose to always allow it.

### Voice mode

Many people use custom connectors in the Claude app's voice mode, and Code Therapy is written for it: answers are short, spoken-style, and lead with the status. However, Anthropic doesn't officially document voice-mode support for custom connectors. If voice doesn't call the tools for you, text chat always works.

## What to say

| Tool | What it's for | Try saying | Speed |
|---|---|---|---|
| `list_projects` | Your Claude Code projects, most recently active first, with each one's latest session title | "What projects do I have?" | Fast |
| `get_project_brief` | Where a project stands: overview from `CLAUDE.md` or `README.md`, git branch and recent commits, recent sessions, and open notes | "How's acme-api doing?" | Fast |
| `get_recent_activity` | Sessions and commits over the last N days (7 by default) | "What did I do on storefront this week?" | Fast |
| `search_project` | Literal, case-insensitive search of file names and contents. It returns up to 20 matches | "Where's the rate limiter in acme-api?" | About 1 second |
| `ask_project` | A deep answer about how the code works, from read-only Claude Code | "How does storefront calculate shipping?" | Slow, 20–90 seconds |
| `record_note` | Saves a decision, to-do or note to the project's `PM_NOTES.md` | "Write that down as a decision." | Fast |

You don't need to say tool names. Just talk about your projects, and Claude picks the tool. Project names are matched loosely, so "acme api" finds `acme-api`. Claude says so before it starts a slow `ask_project` lookup.

## Notes back into your coding session

`record_note` appends timestamped lines like `- [2026-10-16 09:30] **DECISION:** …` to `PM_NOTES.md` in the project folder. That's the only file Code Therapy writes in your projects. Its own config file lives elsewhere. Open notes also show up in `get_project_brief`.

Claude Code doesn't load `PM_NOTES.md` by itself, and Code Therapy never edits your `CLAUDE.md`. To have your next coding session pick up the notes, add this line to the project's `CLAUDE.md` once:

```
@PM_NOTES.md
```

Or just start the session with "read PM_NOTES.md".

## Commands

All commands accept `--config PATH` before the command name, as in `codetherapy --config ./dev.env start`. Use `codetherapy --version` to print the version.

| Command | What it does | Flags |
|---|---|---|
| `setup` | Checks prerequisites and writes the config file | `--public-host HOST` sets your public hostname, such as your ngrok domain.<br>`--no-tunnel` means you bring your own tunnel and requires a public host.<br>`--ngrok` switches back to the built-in ngrok tunnel. You can't combine it with `--no-tunnel`.<br>`--port N` sets the local port, 1–65535 (default 8765).<br>`--projects-dir DIR` sets where Claude Code's projects live.<br>`--rotate` generates a new token.<br>`--yes` never prompts. |
| `start` | Runs the server and ngrok, prints the connector URL and copies it. Press Ctrl+C to stop both | `--no-tunnel` skips ngrok for this run.<br>`--port N` uses a different local port for this run.<br>`--public-host HOST` uses a different public hostname for this run. |
| `url` | Prints the connector URL | `--copy` also copies it to the clipboard. |
| `rotate` | Replaces the token. This revokes the old URL once you restart `codetherapy start` | None. |
| `doctor` | Checks the config, prerequisites, and the local and public endpoints | `--port N` checks this port, if you ran `start --port N`. |
| `serve` | Runs only the server, with no tunnel, for your own process manager | None. |

## Security model

- **The URL is the password.** The connector URL contains a 256-bit random secret, and it's the only credential. Treat it like a password and don't share it. `codetherapy rotate` replaces it. This revokes the old URL once you restart `codetherapy start`. Then update the URL on claude.ai.
- **Small attack surface.** The server binds to 127.0.0.1 only. Every path except the secret one returns 404, and DNS-rebinding protection is on, so only your public host and localhost are accepted. Request paths are never logged.
- **Read-only.** The only exception is appending to `PM_NOTES.md`.
- **`ask_project` is locked down.**
  - It runs `claude -p` with only the Read, Grep and Glob tools, and they're confined to the project folder.
  - Reading `~/.claude`, `~/.claude.json`, `~/.ssh` and `~/AppData` is always denied, as is reading the config of Code Therapy, ngrok, `gh`, Docker, kubectl and PyPI. So is reading the secret files listed in the next point.
  - Claude Code applies these Read deny rules to Grep and Glob too, but only on a best-effort basis.
  - A project that is your whole home folder (because you ran `claude` from `~`), or a folder above it, is refused. `search_project` refuses it too. Open Claude Code in a specific project folder instead.
  - It runs in restricted mode with no MCP servers, and it can't run commands, edit files or browse the web.
  - At most 2 lookups run at once, each with a 90-second timeout.
- **Secret files are skipped by name.** `search_project` never reads them, and `ask_project` is denied reading them (best-effort for Grep and Glob, as above). The list is:
  - `.env` and `.env.*`
  - `.envrc`, `.npmrc`, `.netrc` and `.pgpass`
  - keys and certificates: `*.pem`, `*.key`, `*.p12`, `*.pfx`, `*.keystore`, `*.jks`, `id_rsa*` and `id_ed25519*`
  - any file with "credentials" or "secret" in its name
  - anything inside `.ssh`, `.aws` or `.gnupg` folders
- **What it can see.** It can read anything else inside your project folders. That includes secrets committed under other names, such as a token in `config.yaml`. If a project holds something you wouldn't read aloud, keep it out of that folder.
- **Your tunnel provider can see your traffic.** ngrok terminates TLS at its edge, and so does a Cloudflare tunnel. That means the provider can see request paths, including the token, as well as tool results. Tailscale Funnel is the exception among the [tunnels described here](https://github.com/Rapideo/codetherapy#bring-your-own-tunnel), because it terminates TLS on your own device.
- **No telemetry.** Code Therapy doesn't phone home.
- **OAuth sign-in is on the roadmap**, as an alternative to the secret URL.

To report a vulnerability, see [SECURITY.md](https://github.com/Rapideo/codetherapy/blob/main/SECURITY.md).

## Bring your own tunnel

Any tunnel works as long as it gives you a **stable public HTTPS hostname** that forwards to `http://127.0.0.1:8765`. First tell Code Therapy the hostname and that it shouldn't start ngrok:

```sh
codetherapy setup --no-tunnel --public-host <your hostname>
```

Then start your tunnel, and run `codetherapy start` as usual.

**Tailscale Funnel.** This gives you a stable `*.ts.net` name:

```sh
codetherapy setup --no-tunnel --public-host box.tailnet.ts.net
tailscale funnel 8765
codetherapy start
```

Run `tailscale funnel` in its own terminal, or add `--bg` to keep it running in the background. Funnel needs to be enabled for your tailnet. See <https://tailscale.com/kb/1223/funnel>.

**Cloudflare named tunnel.** If you have a domain on Cloudflare, point a named tunnel's ingress at the server:

```yaml
# ~/.cloudflared/config.yml
tunnel: <tunnel-id>
credentials-file: /path/to/<tunnel-id>.json
ingress:
  - hostname: codetherapy.example.com
    service: http://127.0.0.1:8765
  - service: http_status:404
```

```sh
codetherapy setup --no-tunnel --public-host codetherapy.example.com
cloudflared tunnel run <tunnel-name>
codetherapy start
```

**Cloudflare quick tunnels won't work.** A quick tunnel (`trycloudflare.com`) gets a new URL every time it starts, so your connector would break on every restart.

To go back to ngrok, run `codetherapy setup --ngrok`.

## Troubleshooting

Run **`codetherapy doctor`** first. It checks:

- that your config loads and `claude` is installed
- that ngrok is installed and has its authtoken, if you use the ngrok tunnel
- whether the server is running
- that the local endpoint answers with all six tools
- that the public endpoint answers through your tunnel

It reports each problem in plain language.

**"port 8765 is in use — is Code Therapy already running?"**

- Another `codetherapy start` is probably still running, perhaps in another terminal. Stop it with Ctrl+C.
- If something else owns the port, use another one: `codetherapy start --port 8766` for one run, or `codetherapy setup --port 8766` to keep it. Use the same port with `doctor --port`.

**ngrok errors.** `start` translates ngrok's errors into hints:

- **No authtoken, or a rejected one.** Copy it again from <https://dashboard.ngrok.com/get-started/your-authtoken> and run `ngrok config add-authtoken <token>`.
- **Already running, or the domain is already online.** The free plan allows one ngrok agent at a time. Stop the other ngrok (another terminal, another computer, or an old `start` still running), then try again.

**claude.ai says it couldn't connect.**

- `codetherapy start` must be running when you use the connector. Your computer has to be awake.
- Run `codetherapy doctor`. If the local endpoint works but the public one doesn't, the problem is the tunnel.
- Make sure you pasted the whole URL, including the `/mcp/…` part. `codetherapy url` prints it again.
- If you ran `rotate`, update the connector URL on claude.ai.

**A project is missing from `list_projects`.**

- Projects are discovered from Claude Code's session logs, and Claude Code deletes old logs (after 30 days by default). So only folders with Claude Code session history in roughly the last 30 days show up. To bring one back, open Claude Code in that folder once. It appears within a minute.
- `list_projects` shows the 15 most recent projects. Ask for an older one by name.

**`ask_project` times out or fails.**

- Lookups stop after 90 seconds. For questions that big, ask in Claude Code directly.
- Only 2 lookups run at once. If another is running, Claude is told to try again shortly.
- Check that `claude` is on your PATH and logged in. Try `claude -p "hello"` in a terminal.
- For "where is…" questions, `search_project` is much faster.

## FAQ

**Does my code go to Anthropic?**
Only what's needed to answer you. Tool results go to Claude in your conversation: briefs include paths, commit messages and recent session prompts, and searches include matching lines. When `ask_project` runs, Claude Code sends the files it reads to Anthropic, the same as any Claude Code session. Nothing is uploaded on its own.

**Does it cost API credits?**
The fast tools don't call any model. `ask_project` runs your own logged-in `claude` CLI, so it uses your Claude Code plan, or your API key if your `claude` is configured with one. It's the same as running Claude Code yourself.

**Can my team use one instance?**
No. It's single-user: one person's machine, one person's projects, one secret URL. Each person runs their own.

**Why "therapy"?**
You lie back (on the couch, on the bus, on a walk) and ask your repos how they're doing. They tell you what's been on their mind this week, what's bothering them, and the decisions they keep putting off. There's no couch fee, and the notes go into `PM_NOTES.md` instead of a file folder.

## Roadmap

- OAuth sign-in for claude.ai, as an alternative to the secret URL
- An autostart service, so the connector is running whenever your machine is
- Discovering older projects from Claude Code memory files, not just recent session logs
- A listing in the MCP Registry
- More PM tools

## Contributing and license

Contributions are welcome. See [CONTRIBUTING.md](https://github.com/Rapideo/codetherapy/blob/main/CONTRIBUTING.md) for dev setup and the PR checklist, and [CHANGELOG.md](https://github.com/Rapideo/codetherapy/blob/main/CHANGELOG.md) for what's changed. Code Therapy is released under the [MIT License](https://github.com/Rapideo/codetherapy/blob/main/LICENSE).

<!-- mcp-name: io.github.rapideo/codetherapy -->
