Metadata-Version: 2.4
Name: claude-pyls
Version: 0.1.0
Summary: Lightweight Python LSP MCP server + grep-intercept hook for Claude Code
Project-URL: Homepage, https://github.com/hyang0129/claude-pyls
Project-URL: Repository, https://github.com/hyang0129/claude-pyls
Project-URL: Issues, https://github.com/hyang0129/claude-pyls/issues
License: MIT
Keywords: claude,claude-code,grep,hook,jedi,language-server,lsp,mcp,model-context-protocol,python
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Utilities
Requires-Python: >=3.11
Provides-Extra: dev
Requires-Dist: pytest-timeout; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Provides-Extra: lsp
Requires-Dist: jedi>=0.19; extra == 'lsp'
Description-Content-Type: text/markdown

# claude-pyls

A lightweight Python LSP MCP server + grep-intercept hook for Claude Code. Gives Claude token-efficient symbol navigation in any Python project.

## Why

When Claude Code searches for a Python symbol using `Grep`, it reads large swaths of source into context. A targeted LSP lookup costs a fraction of that.

Measured savings (Haiku, `claude -p`, 400-file project):

| Metric | Without (Grep) | With (pyls) | Savings |
|---|---|---|---|
| Cost | $0.0586 | $0.0119 | **80% cheaper** |
| Cache creation tokens | 39,124 | 2,953 | **92% less** |
| Duration | 10.6s | 5.7s | **46% faster** |

## Modes

### Small (single-repo, zero-startup)
Regex scan over `class`/`def` lines. Starts in **0.2s** (raw JSON-RPC, no MCP SDK). Optionally enhances with jedi for precise goto/references. Ideal for per-project activation.

### Big (environment-wide, daemon)
A persistent LSP daemon that starts on boot and serves an entire Python environment. Longer startup, higher accuracy, multi-repo awareness. Good for large monorepos or shared dev environments. _(Planned — not yet implemented.)_

## Install

```bash
pip install claude-pyls          # small mode (regex scan)
pip install claude-pyls[lsp]     # + jedi for enhanced accuracy
```

## Quick start

```bash
# Scaffold .mcp.json + hook into your project
claude-pyls setup

# Or manually add to .mcp.json:
# {"mcpServers": {"pyls": {"command": "claude-pyls", "args": ["serve"]}}}
```

## Tools exposed

| Tool | Description |
|---|---|
| `find_definition` | File + line where a symbol is defined |
| `find_references` | All sites where a symbol is used |
| `find_symbols` | All definitions matching a name pattern |

## Known limitations

- Textual scan only (small mode) — won't resolve dynamic attributes, decorated names, or re-exports
- jedi (when enabled) is lazy-loaded on first call (~3–4s first call, fast after)
- File cache is not invalidated mid-session — restart the server after large refactors
- Hook catches bare symbol names (PascalCase, camelCase, snake_case 2+ segments) — prefixed patterns pass through

## Releasing

Publishing is manual for now (no CI/CD). The PyPI API token lives in a local `.env` file (gitignored) in the format `pypi=pypi-...`.

```bash
# one-time: install hatch into the dev venv
pip install hatch

# build wheel + sdist
hatch build

# publish — reads the token out of .env WITHOUT exporting every line
# of .env into your shell (avoids leaking unrelated vars). Never commit .env.
HATCH_INDEX_USER=__token__ \
  HATCH_INDEX_AUTH="$(grep '^pypi=' .env | cut -d= -f2-)" \
  hatch publish

# tag the release (replace X.Y.Z with the version you just bumped
# in src/claude_pyls/__init__.py and pyproject.toml — see below)
git tag vX.Y.Z && git push origin vX.Y.Z
```

### Version bump procedure

Before each release, bump the version in **both** locations (they must stay in sync):

1. `src/claude_pyls/__init__.py` — `__version__ = "x.y.z"`
2. `pyproject.toml` — `version = "x.y.z"`

Then commit, build, publish, and tag as shown above.

## License

MIT
