Skip to main content

Code Therapy

"Lie back. Tell me about your repo."

PyPI Python versions CI License: MIT

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

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).

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. uv installs Python for you if you need it.
  • A free ngrok account, or your own tunnel.
  • Windows, macOS or Linux.

Quick start

  1. Before you start, do these once.
    • Install uv.
    • Set up ngrok: install it, run ngrok config add-authtoken <token>, and copy your free static domain. See ngrok, once for the details.
  2. 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 ….
  3. Run codetherapy setup. It checks your prerequisites and asks for your ngrok domain.
  4. Run codetherapy start, and leave it running. It prints your connector URL and copies it to the clipboard.
  5. 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:

  3. Copy your authtoken from https://dashboard.ngrok.com/get-started/your-authtoken and run:

    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.
--no-tunnel means you bring your own tunnel and requires a public host.
--ngrok switches back to the built-in ngrok tunnel. You can't combine it with --no-tunnel.
--port N sets the local port, 1–65535 (default 8765).
--projects-dir DIR sets where Claude Code's projects live.
--rotate generates a new token.
--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.
--port N uses a different local port for this run.
--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, 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.

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:

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:

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:

# ~/.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
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 for dev setup and the PR checklist, and CHANGELOG.md for what's changed. Code Therapy is released under the MIT License.

Metadata

Release files for codetherapy 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for codetherapy 0.1.0
File Size Uploaded
codetherapy-0.1.0.tar.gz 50.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for codetherapy 0.1.0
File Interpreter ABI Platform
codetherapy-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 87.0 kB

Release files / codetherapy-0.1.0.tar.gz

Download URL codetherapy-0.1.0.tar.gz
Size 50.0 kB
Tags Source
SHA-256 checksum
How to use checksums
78b50609c55c5527a56f1eaf2f144ba68fa53ff7bf3bfef392bbe763563c213c
BLAKE2b-256 checksum
How to use checksums
c90f08822dd8836233e28befc593ffed06fef12d4ba2fae8b944828c10548998
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.

Transparency log

Release files / codetherapy-0.1.0-py3-none-any.whl

Download URL codetherapy-0.1.0-py3-none-any.whl
Size 37.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c960df6d028ab043892e39b799467d49046d9595a5af902f5751205af858c1cd
BLAKE2b-256 checksum
How to use checksums
be1e1003f429e38820f48b6a84f16def5b362db8e643a16ae37c81829a47af1c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page