cicada-mcp 0.1.4__tar.gz → 0.1.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cicada-mcp might be problematic. Click here for more details.
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/PKG-INFO +30 -3
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/README.md +29 -2
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/install.py +22 -5
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/setup.py +9 -2
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada_mcp.egg-info/PKG-INFO +30 -3
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada_mcp.egg-info/SOURCES.txt +1 -1
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada_mcp.egg-info/entry_points.txt +1 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/pyproject.toml +4 -2
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_install_comprehensive.py +19 -5
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_install_detection.py +29 -3
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_keyword_search.py +10 -2
- cicada_mcp-0.1.5/tests/test_mcp_e2e.py +773 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_setup.py +24 -4
- cicada_mcp-0.1.4/cicada/keyword_extractor.py +0 -364
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/LICENSE +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/__init__.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/clean.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/command_logger.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/dead_code_analyzer.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/extractors/__init__.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/extractors/base.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/extractors/call.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/extractors/dependency.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/extractors/doc.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/extractors/function.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/extractors/module.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/extractors/spec.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/find_dead_code.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/formatter.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/git_helper.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/indexer.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/keyword_search.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/lightweight_keyword_extractor.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/mcp_server.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/mcp_tools.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/parser.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/pr_finder.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/pr_indexer/__init__.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/pr_indexer/cli.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/pr_indexer/github_api_client.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/pr_indexer/indexer.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/pr_indexer/line_mapper.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/pr_indexer/pr_index_builder.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/utils/__init__.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/utils/call_site_formatter.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/utils/function_grouper.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/utils/hash_utils.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/utils/index_utils.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/utils/path_utils.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/utils/signature_builder.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/utils/storage.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/utils/subprocess_runner.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/utils/text_utils.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada/version_check.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada_mcp.egg-info/dependency_links.txt +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada_mcp.egg-info/requires.txt +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/cicada_mcp.egg-info/top_level.txt +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/setup.cfg +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_acceptance.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_call_sites.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_claude_md_update.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_clean.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_command_logger.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_dead_code_analyzer.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_e2e.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_find_dead_code.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_formatter.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_git_extended_history.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_git_helper.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_github_api_client.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_gitignore_integration.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_hash_utils.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_index_utils.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_indexer_comprehensive.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_install_summary.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_intelligent_mcp_config.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_line_mapper.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_mcp_git_integration.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_mcp_logging_integration.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_mcp_pr_tools.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_mcp_server_core.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_mcp_server_formatting.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_mcp_server_pr_history.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_module_usage_categories.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_multi_editor_setup.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_parser.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_parser_comprehensive.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_path_utils.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_pr_finder.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_pr_index_builder.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_pr_indexer_integration.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_pr_indexer_unit.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_search_function.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_server_cli.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_signal_handling.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_stdout_redirect.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_storage.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_subprocess_runner.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_test_files_filter.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_version_check.py +0 -0
- {cicada_mcp-0.1.4 → cicada_mcp-0.1.5}/tests/test_with_aliases.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cicada-mcp
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
4
4
|
Summary: An Elixir module search MCP server
|
|
5
5
|
Author-email: wende <wende@hey.com>
|
|
6
6
|
Maintainer-email: wende <wende@hey.com>
|
|
@@ -138,7 +138,7 @@ cicada claude # or: cicada cursor, cicada vs
|
|
|
138
138
|
|
|
139
139
|
**Available commands after installation:**
|
|
140
140
|
- `cicada [claude|cursor|vs]` - One-command setup per project
|
|
141
|
-
- `cicada-
|
|
141
|
+
- `cicada-mcp` - MCP server (auto-started by editor)
|
|
142
142
|
- `cicada-index` - Re-index code with custom options (medium/large spaCy models)
|
|
143
143
|
- `cicada-index-pr` - Index pull requests for PR attribution
|
|
144
144
|
- `cicada-install` - Legacy setup (creates `.cicada/` in repo)
|
|
@@ -169,6 +169,33 @@ uvx --from git+https://github.com/wende/cicada.git@latest cicada vs
|
|
|
169
169
|
|
|
170
170
|
Once you're convinced, install permanently with `uv tool install` above!
|
|
171
171
|
|
|
172
|
+
### Quick Setup for Cursor and Claude Code
|
|
173
|
+
|
|
174
|
+
**For Cursor:**
|
|
175
|
+
|
|
176
|
+
Click the install button at the top of this README or visit:
|
|
177
|
+
[](https://cursor.com/en-US/install-mcp?name=cicada&config=eyJjb21tYW5kIjoidXZ4IC0tZnJvbSBnaXQraHR0cHM6Ly9naXRodWIuY29tL3dlbmRlL2NpY2FkYS5naXRAbGF0ZXN0IGNpY2FkYS1zZXJ2ZXIgLiJ9)
|
|
178
|
+
|
|
179
|
+
**For Claude Code:**
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
# Option 1: Using claude mcp add command
|
|
183
|
+
claude mcp add cicada -- uvx --from git+https://github.com/wende/cicada.git@latest cicada-mcp ./path/to/your/codebase
|
|
184
|
+
|
|
185
|
+
# Option 2: Using setup script
|
|
186
|
+
uvx --from git+https://github.com/wende/cicada.git@latest cicada claude
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Then for both editors,** run these commands in your codebase to generate keyword lookup and GitHub PR lookup databases:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
# Generate keyword lookup database
|
|
193
|
+
uvx --from git+https://github.com/wende/cicada.git@latest cicada-index .
|
|
194
|
+
|
|
195
|
+
# Generate GitHub PR lookup database
|
|
196
|
+
uvx --from git+https://github.com/wende/cicada.git@latest cicada-index-pr .
|
|
197
|
+
```
|
|
198
|
+
|
|
172
199
|
---
|
|
173
200
|
|
|
174
201
|
## Quick Start
|
|
@@ -221,7 +248,7 @@ your-project/
|
|
|
221
248
|
{
|
|
222
249
|
"mcpServers": {
|
|
223
250
|
"cicada": {
|
|
224
|
-
"command": "cicada-
|
|
251
|
+
"command": "cicada-mcp",
|
|
225
252
|
"env": {
|
|
226
253
|
"CICADA_REPO_PATH": "/path/to/project",
|
|
227
254
|
"CICADA_CONFIG_DIR": "/home/user/.cicada/projects/<hash>"
|
|
@@ -94,7 +94,7 @@ cicada claude # or: cicada cursor, cicada vs
|
|
|
94
94
|
|
|
95
95
|
**Available commands after installation:**
|
|
96
96
|
- `cicada [claude|cursor|vs]` - One-command setup per project
|
|
97
|
-
- `cicada-
|
|
97
|
+
- `cicada-mcp` - MCP server (auto-started by editor)
|
|
98
98
|
- `cicada-index` - Re-index code with custom options (medium/large spaCy models)
|
|
99
99
|
- `cicada-index-pr` - Index pull requests for PR attribution
|
|
100
100
|
- `cicada-install` - Legacy setup (creates `.cicada/` in repo)
|
|
@@ -125,6 +125,33 @@ uvx --from git+https://github.com/wende/cicada.git@latest cicada vs
|
|
|
125
125
|
|
|
126
126
|
Once you're convinced, install permanently with `uv tool install` above!
|
|
127
127
|
|
|
128
|
+
### Quick Setup for Cursor and Claude Code
|
|
129
|
+
|
|
130
|
+
**For Cursor:**
|
|
131
|
+
|
|
132
|
+
Click the install button at the top of this README or visit:
|
|
133
|
+
[](https://cursor.com/en-US/install-mcp?name=cicada&config=eyJjb21tYW5kIjoidXZ4IC0tZnJvbSBnaXQraHR0cHM6Ly9naXRodWIuY29tL3dlbmRlL2NpY2FkYS5naXRAbGF0ZXN0IGNpY2FkYS1zZXJ2ZXIgLiJ9)
|
|
134
|
+
|
|
135
|
+
**For Claude Code:**
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# Option 1: Using claude mcp add command
|
|
139
|
+
claude mcp add cicada -- uvx --from git+https://github.com/wende/cicada.git@latest cicada-mcp ./path/to/your/codebase
|
|
140
|
+
|
|
141
|
+
# Option 2: Using setup script
|
|
142
|
+
uvx --from git+https://github.com/wende/cicada.git@latest cicada claude
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Then for both editors,** run these commands in your codebase to generate keyword lookup and GitHub PR lookup databases:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
# Generate keyword lookup database
|
|
149
|
+
uvx --from git+https://github.com/wende/cicada.git@latest cicada-index .
|
|
150
|
+
|
|
151
|
+
# Generate GitHub PR lookup database
|
|
152
|
+
uvx --from git+https://github.com/wende/cicada.git@latest cicada-index-pr .
|
|
153
|
+
```
|
|
154
|
+
|
|
128
155
|
---
|
|
129
156
|
|
|
130
157
|
## Quick Start
|
|
@@ -177,7 +204,7 @@ your-project/
|
|
|
177
204
|
{
|
|
178
205
|
"mcpServers": {
|
|
179
206
|
"cicada": {
|
|
180
|
-
"command": "cicada-
|
|
207
|
+
"command": "cicada-mcp",
|
|
181
208
|
"env": {
|
|
182
209
|
"CICADA_REPO_PATH": "/path/to/project",
|
|
183
210
|
"CICADA_CONFIG_DIR": "/home/user/.cicada/projects/<hash>"
|
|
@@ -251,7 +251,15 @@ def detect_installation_method():
|
|
|
251
251
|
".local/share/uv/tools" in script_path_str
|
|
252
252
|
or ".local/bin/cicada-" in script_path_str
|
|
253
253
|
):
|
|
254
|
-
# Installed via uv tool install
|
|
254
|
+
# Installed via uv tool install - check for cicada-mcp first
|
|
255
|
+
if shutil.which("cicada-mcp"):
|
|
256
|
+
return (
|
|
257
|
+
"cicada-mcp",
|
|
258
|
+
[],
|
|
259
|
+
None,
|
|
260
|
+
"uv tool install (ensure ~/.local/bin is in PATH)",
|
|
261
|
+
)
|
|
262
|
+
# Fall back to cicada-server for backwards compatibility
|
|
255
263
|
return (
|
|
256
264
|
"cicada-server",
|
|
257
265
|
[],
|
|
@@ -259,7 +267,11 @@ def detect_installation_method():
|
|
|
259
267
|
"uv tool install (ensure ~/.local/bin is in PATH)",
|
|
260
268
|
)
|
|
261
269
|
|
|
262
|
-
# Check if cicada-
|
|
270
|
+
# Check if cicada-mcp is in PATH first (from uv tool install)
|
|
271
|
+
if shutil.which("cicada-mcp"):
|
|
272
|
+
return ("cicada-mcp", [], None, "uv tool install (permanent, fast)")
|
|
273
|
+
|
|
274
|
+
# Fall back to cicada-server for backwards compatibility
|
|
263
275
|
if shutil.which("cicada-server"):
|
|
264
276
|
return ("cicada-server", [], None, "uv tool install (permanent, fast)")
|
|
265
277
|
|
|
@@ -279,8 +291,13 @@ def check_tools_in_path():
|
|
|
279
291
|
"""Check if cicada tools are in PATH."""
|
|
280
292
|
import shutil
|
|
281
293
|
|
|
282
|
-
|
|
294
|
+
# Check for cicada-mcp (new) or cicada-server (backwards compat)
|
|
295
|
+
has_mcp_server = shutil.which("cicada-mcp") or shutil.which("cicada-server")
|
|
296
|
+
tools = ["cicada-index"]
|
|
283
297
|
visible_tools = [tool for tool in tools if shutil.which(tool)]
|
|
298
|
+
if has_mcp_server:
|
|
299
|
+
visible_tools.insert(0, "cicada-mcp/cicada-server")
|
|
300
|
+
tools.insert(0, "cicada-mcp/cicada-server")
|
|
284
301
|
|
|
285
302
|
if len(visible_tools) == len(tools):
|
|
286
303
|
return "all_visible"
|
|
@@ -351,8 +368,8 @@ def create_mcp_config(repo_path, _cicada_dir, _python_bin):
|
|
|
351
368
|
print(f"✓ MCP configuration updated at {mcp_config_path}")
|
|
352
369
|
|
|
353
370
|
# Show what was configured
|
|
354
|
-
if command
|
|
355
|
-
print("✅ Using '
|
|
371
|
+
if command in ("cicada-mcp", "cicada-server"):
|
|
372
|
+
print(f"✅ Using '{command}' command (fast, no paths needed)")
|
|
356
373
|
else:
|
|
357
374
|
print(f"ℹ️ Using Python: {command}")
|
|
358
375
|
|
|
@@ -102,9 +102,15 @@ def get_mcp_config_for_editor(
|
|
|
102
102
|
# Detect installation method
|
|
103
103
|
import shutil
|
|
104
104
|
|
|
105
|
+
# Check for cicada-mcp first (new name), fall back to cicada-server (backwards compat)
|
|
106
|
+
has_cicada_mcp = shutil.which("cicada-mcp") is not None
|
|
105
107
|
has_cicada_server = shutil.which("cicada-server") is not None
|
|
106
108
|
|
|
107
|
-
if
|
|
109
|
+
if has_cicada_mcp:
|
|
110
|
+
command = "cicada-mcp"
|
|
111
|
+
args = []
|
|
112
|
+
cwd = None
|
|
113
|
+
elif has_cicada_server:
|
|
108
114
|
command = "cicada-server"
|
|
109
115
|
args = []
|
|
110
116
|
cwd = None
|
|
@@ -275,7 +281,8 @@ def setup(editor: EditorType, repo_path: Path | None = None) -> None:
|
|
|
275
281
|
import shutil
|
|
276
282
|
from cicada import __version__
|
|
277
283
|
|
|
278
|
-
|
|
284
|
+
# Check for either cicada-mcp or cicada-server (backwards compat)
|
|
285
|
+
if not (shutil.which("cicada-mcp") or shutil.which("cicada-server")):
|
|
279
286
|
print("💡 Tip: For best experience, install Cicada permanently:")
|
|
280
287
|
print(
|
|
281
288
|
f" uv tool install git+https://github.com/wende/cicada.git@v{__version__}"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cicada-mcp
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
4
4
|
Summary: An Elixir module search MCP server
|
|
5
5
|
Author-email: wende <wende@hey.com>
|
|
6
6
|
Maintainer-email: wende <wende@hey.com>
|
|
@@ -138,7 +138,7 @@ cicada claude # or: cicada cursor, cicada vs
|
|
|
138
138
|
|
|
139
139
|
**Available commands after installation:**
|
|
140
140
|
- `cicada [claude|cursor|vs]` - One-command setup per project
|
|
141
|
-
- `cicada-
|
|
141
|
+
- `cicada-mcp` - MCP server (auto-started by editor)
|
|
142
142
|
- `cicada-index` - Re-index code with custom options (medium/large spaCy models)
|
|
143
143
|
- `cicada-index-pr` - Index pull requests for PR attribution
|
|
144
144
|
- `cicada-install` - Legacy setup (creates `.cicada/` in repo)
|
|
@@ -169,6 +169,33 @@ uvx --from git+https://github.com/wende/cicada.git@latest cicada vs
|
|
|
169
169
|
|
|
170
170
|
Once you're convinced, install permanently with `uv tool install` above!
|
|
171
171
|
|
|
172
|
+
### Quick Setup for Cursor and Claude Code
|
|
173
|
+
|
|
174
|
+
**For Cursor:**
|
|
175
|
+
|
|
176
|
+
Click the install button at the top of this README or visit:
|
|
177
|
+
[](https://cursor.com/en-US/install-mcp?name=cicada&config=eyJjb21tYW5kIjoidXZ4IC0tZnJvbSBnaXQraHR0cHM6Ly9naXRodWIuY29tL3dlbmRlL2NpY2FkYS5naXRAbGF0ZXN0IGNpY2FkYS1zZXJ2ZXIgLiJ9)
|
|
178
|
+
|
|
179
|
+
**For Claude Code:**
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
# Option 1: Using claude mcp add command
|
|
183
|
+
claude mcp add cicada -- uvx --from git+https://github.com/wende/cicada.git@latest cicada-mcp ./path/to/your/codebase
|
|
184
|
+
|
|
185
|
+
# Option 2: Using setup script
|
|
186
|
+
uvx --from git+https://github.com/wende/cicada.git@latest cicada claude
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Then for both editors,** run these commands in your codebase to generate keyword lookup and GitHub PR lookup databases:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
# Generate keyword lookup database
|
|
193
|
+
uvx --from git+https://github.com/wende/cicada.git@latest cicada-index .
|
|
194
|
+
|
|
195
|
+
# Generate GitHub PR lookup database
|
|
196
|
+
uvx --from git+https://github.com/wende/cicada.git@latest cicada-index-pr .
|
|
197
|
+
```
|
|
198
|
+
|
|
172
199
|
---
|
|
173
200
|
|
|
174
201
|
## Quick Start
|
|
@@ -221,7 +248,7 @@ your-project/
|
|
|
221
248
|
{
|
|
222
249
|
"mcpServers": {
|
|
223
250
|
"cicada": {
|
|
224
|
-
"command": "cicada-
|
|
251
|
+
"command": "cicada-mcp",
|
|
225
252
|
"env": {
|
|
226
253
|
"CICADA_REPO_PATH": "/path/to/project",
|
|
227
254
|
"CICADA_CONFIG_DIR": "/home/user/.cicada/projects/<hash>"
|
|
@@ -10,7 +10,6 @@ cicada/formatter.py
|
|
|
10
10
|
cicada/git_helper.py
|
|
11
11
|
cicada/indexer.py
|
|
12
12
|
cicada/install.py
|
|
13
|
-
cicada/keyword_extractor.py
|
|
14
13
|
cicada/keyword_search.py
|
|
15
14
|
cicada/lightweight_keyword_extractor.py
|
|
16
15
|
cicada/mcp_server.py
|
|
@@ -71,6 +70,7 @@ tests/test_install_summary.py
|
|
|
71
70
|
tests/test_intelligent_mcp_config.py
|
|
72
71
|
tests/test_keyword_search.py
|
|
73
72
|
tests/test_line_mapper.py
|
|
73
|
+
tests/test_mcp_e2e.py
|
|
74
74
|
tests/test_mcp_git_integration.py
|
|
75
75
|
tests/test_mcp_logging_integration.py
|
|
76
76
|
tests/test_mcp_pr_tools.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "cicada-mcp"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.5"
|
|
8
8
|
description = "An Elixir module search MCP server"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -59,7 +59,8 @@ Changelog = "https://github.com/wende/cicada/blob/main/CHANGELOG.md"
|
|
|
59
59
|
Documentation = "https://github.com/wende/cicada#readme"
|
|
60
60
|
|
|
61
61
|
[project.scripts]
|
|
62
|
-
cicada-
|
|
62
|
+
cicada-mcp = "cicada.mcp_server:main"
|
|
63
|
+
cicada-server = "cicada.mcp_server:main" # Backwards compatibility
|
|
63
64
|
cicada = "cicada.setup:main"
|
|
64
65
|
cicada-install = "cicada.install:main"
|
|
65
66
|
cicada-clean = "cicada.clean:main"
|
|
@@ -84,6 +85,7 @@ asyncio_mode = "auto"
|
|
|
84
85
|
asyncio_default_fixture_loop_scope = "function"
|
|
85
86
|
filterwarnings = [
|
|
86
87
|
"ignore:Importing 'parser.split_arg_string' is deprecated.*:DeprecationWarning",
|
|
88
|
+
"ignore:coroutine 'async_main' was never awaited:RuntimeWarning",
|
|
87
89
|
]
|
|
88
90
|
|
|
89
91
|
[tool.coverage.run]
|
|
@@ -387,20 +387,34 @@ class TestDetectInstallationMethod:
|
|
|
387
387
|
|
|
388
388
|
def test_detect_uv_tools_permanent(self):
|
|
389
389
|
"""Test detection of uv tool install."""
|
|
390
|
-
with
|
|
391
|
-
|
|
390
|
+
with (
|
|
391
|
+
patch(
|
|
392
|
+
"sys.argv",
|
|
393
|
+
["/Users/user/.local/share/uv/tools/cicada/bin/cicada-setup"],
|
|
394
|
+
),
|
|
395
|
+
patch(
|
|
396
|
+
"shutil.which",
|
|
397
|
+
side_effect=lambda tool: (
|
|
398
|
+
"/usr/local/bin/" + tool if tool == "cicada-mcp" else None
|
|
399
|
+
),
|
|
400
|
+
),
|
|
392
401
|
):
|
|
393
402
|
command, args, cwd, _description = detect_installation_method()
|
|
394
403
|
|
|
395
|
-
assert command == "cicada-
|
|
404
|
+
assert command == "cicada-mcp"
|
|
396
405
|
assert args == []
|
|
397
406
|
assert cwd is None
|
|
398
407
|
|
|
399
408
|
def test_detect_cicada_server_in_path(self):
|
|
400
|
-
"""Test when cicada-server is in PATH."""
|
|
409
|
+
"""Test when only cicada-server is in PATH (backwards compatibility)."""
|
|
401
410
|
with (
|
|
402
411
|
patch("sys.argv", ["/some/path/script.py"]),
|
|
403
|
-
patch(
|
|
412
|
+
patch(
|
|
413
|
+
"shutil.which",
|
|
414
|
+
side_effect=lambda tool: (
|
|
415
|
+
"/usr/local/bin/cicada-server" if tool == "cicada-server" else None
|
|
416
|
+
),
|
|
417
|
+
),
|
|
404
418
|
):
|
|
405
419
|
|
|
406
420
|
command, args, cwd, description = detect_installation_method()
|
|
@@ -48,13 +48,39 @@ def test_uv_tool_install_detection():
|
|
|
48
48
|
]
|
|
49
49
|
|
|
50
50
|
for uv_path in uv_paths:
|
|
51
|
-
with
|
|
51
|
+
# Test with cicada-mcp available (new default)
|
|
52
|
+
with (
|
|
53
|
+
patch("sys.argv", [uv_path]),
|
|
54
|
+
patch(
|
|
55
|
+
"shutil.which",
|
|
56
|
+
side_effect=lambda tool: (
|
|
57
|
+
"/usr/local/bin/cicada-mcp" if tool == "cicada-mcp" else None
|
|
58
|
+
),
|
|
59
|
+
),
|
|
60
|
+
):
|
|
52
61
|
command, args, cwd, description = detect_installation_method()
|
|
53
62
|
|
|
54
|
-
# Should use cicada-
|
|
63
|
+
# Should use cicada-mcp for new installs
|
|
55
64
|
assert (
|
|
56
|
-
command == "cicada-
|
|
65
|
+
command == "cicada-mcp"
|
|
57
66
|
), f"uv tool install path {uv_path} not detected correctly"
|
|
67
|
+
assert args == [], "Should have no args for cicada-mcp"
|
|
68
|
+
assert cwd is None, "Should have no cwd for cicada-mcp"
|
|
69
|
+
|
|
70
|
+
# Test backwards compatibility with only cicada-server available
|
|
71
|
+
with (
|
|
72
|
+
patch("sys.argv", [uv_path]),
|
|
73
|
+
patch(
|
|
74
|
+
"shutil.which",
|
|
75
|
+
side_effect=lambda tool: (
|
|
76
|
+
"/usr/local/bin/cicada-server" if tool == "cicada-server" else None
|
|
77
|
+
),
|
|
78
|
+
),
|
|
79
|
+
):
|
|
80
|
+
command, args, cwd, description = detect_installation_method()
|
|
81
|
+
|
|
82
|
+
# Should fall back to cicada-server for backwards compat
|
|
83
|
+
assert command == "cicada-server", f"Backwards compat failed for {uv_path}"
|
|
58
84
|
assert args == [], "Should have no args for cicada-server"
|
|
59
85
|
assert cwd is None, "Should have no cwd for cicada-server"
|
|
60
86
|
|
|
@@ -137,7 +137,11 @@ class TestKeywordExtractor:
|
|
|
137
137
|
def test_invalid_model_size(self):
|
|
138
138
|
"""Test that model_size parameter is ignored (for API compatibility)"""
|
|
139
139
|
# Lightweight extractor accepts any model_size for compatibility but ignores it
|
|
140
|
-
|
|
140
|
+
import warnings
|
|
141
|
+
|
|
142
|
+
with warnings.catch_warnings():
|
|
143
|
+
warnings.simplefilter("ignore", DeprecationWarning)
|
|
144
|
+
extractor = KeywordExtractor(verbose=False, model_size="invalid")
|
|
141
145
|
assert extractor.model_size == "invalid" # Stored but not validated
|
|
142
146
|
|
|
143
147
|
def test_split_camel_case(self):
|
|
@@ -378,7 +382,11 @@ class TestKeywordExtractor:
|
|
|
378
382
|
|
|
379
383
|
def test_medium_model_on_elixir_doc(self):
|
|
380
384
|
"""Test medium spaCy model on Elixir documentation"""
|
|
381
|
-
|
|
385
|
+
import warnings
|
|
386
|
+
|
|
387
|
+
with warnings.catch_warnings():
|
|
388
|
+
warnings.simplefilter("ignore", DeprecationWarning)
|
|
389
|
+
extractor = KeywordExtractor(verbose=True, model_size="medium")
|
|
382
390
|
|
|
383
391
|
# Small Elixir documentation text
|
|
384
392
|
text = """
|