Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
47c7052
feat(parser): add Perl language support
shanemccarron-maker Mar 5, 2026
67f1f47
Add Swift language support (#23)
jgravelle Mar 5, 2026
ec659c0
Bump version to 0.2.14 — Swift language support
jgravelle Mar 5, 2026
6e7af7f
feat: add C++ language support (#24)
ivanmilov Mar 5, 2026
4d67c30
Bump version to 0.2.15 — C++ language support
jgravelle Mar 5, 2026
56d34b8
feat: add and harden cpp language support
Wes2000ley Mar 5, 2026
87be09d
test: align cpp hardening assertions with fixture
Wes2000ley Mar 5, 2026
dd4df02
Add CLI version flag support
snafu4 Mar 5, 2026
4edeb11
Merge pull request #4 from snafu4/codex/show-version-number-using-jco…
snafu4 Mar 5, 2026
8a31e3d
feat: make the indexing file cap configurable
allenguarnes Mar 5, 2026
84762a3
Merge pull request #26 from Wes2000ley/feat/cpp-hardening-pass2
jgravelle Mar 6, 2026
d182cb5
Merge pull request #28 from allenguarnes/main
jgravelle Mar 6, 2026
b6c5490
feat: add arrow function variable support for JS/TS
Mharbulous Mar 6, 2026
2157d79
Bump version to 0.2.16 — C++ hardening + configurable file cap
jgravelle Mar 6, 2026
5cf1bf3
Merge pull request #29 from Mharbulous/feat/arrow-function-support
jgravelle Mar 6, 2026
322082a
Bump version to 0.2.17 — arrow function variable support for JS/TS
jgravelle Mar 6, 2026
b5139d8
feat: add file-level heuristic summaries to index
josh-stephens Mar 6, 2026
6df79d0
feat: add Elixir language support (.ex, .exs)
JeffreyVdb Mar 6, 2026
ee99818
refactor: simplify Elixir parser with shared helpers and constants
JeffreyVdb Mar 6, 2026
76eecc7
Merge branch 'jgravelle:main' into main
snafu4 Mar 6, 2026
919ee23
Derive __version__ from package metadata
snafu4 Mar 6, 2026
f2bc099
Merge branch 'main' into codex/show-version-number-using-jcodemunch-m…
snafu4 Mar 6, 2026
36ddc77
Merge pull request #5 from snafu4/codex/show-version-number-using-jco…
snafu4 Mar 6, 2026
941dd38
Merge pull request #14 from josh-stephens/feat/file-summaries
jgravelle Mar 6, 2026
0612c34
Bump version to 0.2.18 — file-level summaries
jgravelle Mar 6, 2026
6dcec20
Merge pull request #27 from snafu4/main
jgravelle Mar 6, 2026
132e429
Merge pull request #30 from JeffreyVdb/feat/elixir-language-support
jgravelle Mar 6, 2026
9264038
Bump version to 0.2.19 — Elixir support + --version flag
jgravelle Mar 6, 2026
2f929cf
feat: add Ruby language support (.rb, .rake)
jgravelle Mar 6, 2026
5b02976
fix: improve get_file_outline tool description and error handling
gebeer Mar 6, 2026
706281f
fix(docs): add Perl to LANGUAGES.md
shanemccarron-maker Mar 6, 2026
3d1105e
feat(parser): add JCODEMUNCH_EXTRA_EXTENSIONS support
shanemccarron-maker Mar 6, 2026
63fe596
feat(docs): add JCODEMUNCH_EXTRA_EXTENSIONS startup log and documenta…
shanemccarron-maker Mar 6, 2026
a1c0c3d
test(parser): add test coverage for JCODEMUNCH_EXTRA_EXTENSIONS
shanemccarron-maker Mar 6, 2026
357ddde
chore(repo): add uv.lock and update .gitignore for VBW planning files
shanemccarron-maker Mar 6, 2026
72028b8
fix(indexer): raise file cap to 10k and fix SKIP_PATTERNS false posit…
shanemccarron-maker Mar 6, 2026
6aea871
fix(parser): address QA round 1 findings
shanemccarron-maker Mar 6, 2026
b9c9024
Merge pull request #32 from gebeer/fix/tool_description-get_file_outline
jgravelle Mar 6, 2026
bf258e5
chore(merge): resolve upstream conflicts, keep Perl + EXTRA_EXTENSIONS
shanemccarron-maker Mar 6, 2026
ece87b0
fix(indexer): restore segment-aware SKIP_PATTERNS fix lost in merge
shanemccarron-maker Mar 6, 2026
3a3c515
fix(security): raise DEFAULT_MAX_INDEX_FILES from 500 to 10,000
shanemccarron-maker Mar 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,8 @@ dmypy.json

# Local working notes (may contain sensitive info)
prompt.md

CLAUDE.md
.vbw-planning

.vbw-planning/
25 changes: 24 additions & 1 deletion LANGUAGE_SUPPORT.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@
| PHP | `.php` | tree-sitter-php | function, class, method, type (interface/trait/enum), constant | `#[Attribute]` | `/** */` PHPDoc | PHP 8+ attributes supported; language-file `<?php` tag required |
| Dart | `.dart` | tree-sitter-dart | function, class (class/mixin/extension), method, type (enum/typedef) | `@annotation` | `///` doc comments | Constructors and top-level constants are not indexed |
| C# | `.cs` | tree-sitter-csharp | class (class/record), method (method/constructor), type (interface/enum/struct/delegate) | `[Attribute]` | `/// <summary>` XML doc comments | Properties and `const` fields not indexed |
| C | `.c`, `.h` | tree-sitter-c | function, type (struct/enum/union), constant | — | `/* */` and `//` comments | `#define` macros extracted as constants; no class/method hierarchy |
| C | `.c` | tree-sitter-c | function, type (struct/enum/union), constant | — | `/* */` and `//` comments | `#define` macros extracted as constants; no class/method hierarchy |
| C++ | `.cpp`, `.cc`, `.cxx`, `.hpp`, `.hh`, `.hxx`, `.h`* | tree-sitter-cpp | function, class, method, type (struct/enum/union/alias), constant | — | `/* */` and `//` comments | Namespace symbols are used for qualification but not emitted as standalone symbols |
| Elixir | `.ex`, `.exs` | tree-sitter-elixir | class (defmodule/defimpl), type (defprotocol/@type/@callback), method (def/defp/defmacro/defguard inside module), function (top-level def) | — | `@doc`/`@moduledoc` strings | Homoiconic grammar; custom walker required. `defstruct`, `use`, `import`, `alias` not indexed |
| Ruby | `.rb`, `.rake` | tree-sitter-ruby | class, type (module), method (instance + `self.` singleton), function (top-level def) | — | `#` preceding comments | `attr_accessor`, constants, and `include`/`extend` not indexed |

\* `.h` uses C++ parsing first, then falls back to C when no C++ symbols are extracted.

---

Expand Down Expand Up @@ -105,3 +110,21 @@ print_tree(tree.root_node)
```

This inspection process helps identify the correct `symbol_node_types`, `name_fields`, and extraction rules when adding support for a new language.


## Configuration

### `JCODEMUNCH_EXTRA_EXTENSIONS`

Map additional file extensions to languages at startup without modifying source:

```
JCODEMUNCH_EXTRA_EXTENSIONS=".cgi:perl,.psgi:perl,.mjs:javascript"
```

- Comma-separated `.ext:lang` pairs
- Overrides built-in mappings on collision
- Unknown languages and malformed entries are skipped with a warning
- Valid language names: `python`, `javascript`, `typescript`, `go`, `rust`, `java`, `php`, `dart`, `csharp`, `c`, `cpp`, `swift`, `elixir`, `ruby`, `perl`

Set via `.mcp.json` `env` block or any environment mechanism supported by your MCP client.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,12 @@ Every tool response includes a `_meta` envelope with timing, token savings, and
| PHP | `.php` | function, class, method, type, constant |
| Dart | `.dart` | function, class, method, type |
| C# | `.cs` | class, method, type, record |
| C | `.c`, `.h` | function, type, constant |
| C | `.c` | function, type, constant |
| C++ | `.cpp`, `.cc`, `.cxx`, `.hpp`, `.hh`, `.hxx`, `.h`* | function, class, method, type, constant |
| Elixir | `.ex`, `.exs` | class (module/impl), type (protocol/@type/@callback), method, function |
| Ruby | `.rb`, `.rake` | class, type (module), method, function |

\* `.h` is parsed as C++ first, then falls back to C when no C++ symbols are extracted.

See LANGUAGE_SUPPORT.md for full semantics.

Expand Down Expand Up @@ -373,6 +378,7 @@ For **LM Studio**, ensure the Local Server is running (usually on port 1234):
| `OPENAI_MODEL` | Model name for local LLMs (default: `qwen3-coder`) | No |
| `OPENAI_TIMEOUT` | Timeout in seconds for local requests (default: `60.0`) | No |
| `CODE_INDEX_PATH` | Custom cache path | No |
| `JCODEMUNCH_MAX_INDEX_FILES`| Maximum files to index per repo/folder (default: `500`) | No |
| `JCODEMUNCH_SHARE_SAVINGS` | Set to `0` to disable anonymous community token savings reporting | No |
| `JCODEMUNCH_LOG_LEVEL` | Log level: `DEBUG`, `INFO`, `WARNING`, `ERROR` (default: `WARNING`) | No |
| `JCODEMUNCH_LOG_FILE` | Path to log file. If unset, logs go to stderr. Use a file to avoid polluting MCP stdio. | No |
Expand Down
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ When a secret file is detected, a warning is included in the indexing response.

* **Default maximum:** 500 KB per file (configurable via `max_file_size`).
* Files exceeding the limit are skipped during discovery.
* A configurable **file count limit** (default: 500 files) prevents runaway indexing of extremely large repositories.
* A configurable **file count limit** (default: 500 files) prevents runaway indexing of extremely large repositories. Can be overridden using the `JCODEMUNCH_MAX_INDEX_FILES` environment variable.

---

Expand Down
4 changes: 2 additions & 2 deletions SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ class Symbol:
name: str # Symbol name
qualified_name: str # Dot-separated with parent context
kind: str # function | class | method | constant | type
language: str # python | javascript | typescript | go | rust | java | php | c
language: str # python | javascript | typescript | go | rust | java | php | dart | csharp | c | cpp
signature: str # Full signature line(s)
content_hash: str = "" # SHA-256 of source bytes (drift detection)
docstring: str = ""
Expand Down Expand Up @@ -212,7 +212,7 @@ Recursive directory walk with the full security pipeline.

### Filtering Pipeline (Both Paths)

1. **Extension filter** — must be in `LANGUAGE_EXTENSIONS` (.py, .js, .jsx, .ts, .tsx, .go, .rs, .java, .php, .c, .h)
1. **Extension filter** — must be in `LANGUAGE_EXTENSIONS` (.py, .js, .jsx, .ts, .tsx, .go, .rs, .java, .php, .c, .h, .cpp, .cc, .cxx, .hpp, .hh, .hxx)
2. **Skip patterns** — `node_modules/`, `vendor/`, `.git/`, `build/`, `dist/`, lock files, minified files, etc.
3. **`.gitignore`** — respected via the `pathspec` library
4. **Secret detection** — `.env`, `*.pem`, `*.key`, `*.p12`, credentials files excluded
Expand Down
2 changes: 1 addition & 1 deletion USER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ To disable, set `JCODEMUNCH_SHARE_SAVINGS=0` in your MCP server env:
Check the URL format (`owner/repo` or full GitHub URL). For private repositories, set `GITHUB_TOKEN`.

**"No source files found"**
The repository may not contain supported language files (`.py`, `.js`, `.ts`, `.go`, `.rs`, `.java`, `.c`, `.h`), or files may be excluded by skip patterns.
The repository may not contain supported language files (`.py`, `.js`, `.ts`, `.go`, `.rs`, `.java`, `.c`, `.h`, `.cpp`, `.cc`, `.cxx`, `.hpp`, `.hh`, `.hxx`), or files may be excluded by skip patterns.

**Rate limiting**
Set `GITHUB_TOKEN` to increase GitHub API limits (5,000 requests/hour vs 60 unauthenticated).
Expand Down
9 changes: 8 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "jcodemunch-mcp"
version = "0.2.13"
version = "0.2.20"
description = "Token-efficient MCP server for source code exploration via tree-sitter AST parsing"
readme = "README.md"
requires-python = ">=3.10"
Expand Down Expand Up @@ -33,3 +33,10 @@ exclude = [".claude/"]
[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"

[dependency-groups]
dev = [
"pytest>=9.0.2",
"pytest-asyncio>=1.3.0",
"pytest-cov>=7.0.0",
]
7 changes: 6 additions & 1 deletion src/jcodemunch_mcp/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
"""github-codemunch-mcp - Token-efficient MCP server for GitHub source code exploration."""

__version__ = "0.1.0"
from importlib.metadata import PackageNotFoundError, version

try:
__version__ = version("jcodemunch-mcp")
except PackageNotFoundError:
__version__ = "unknown"
Loading