eth-mcp 0.2.0__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.
- eth_mcp-0.2.0/.github/workflows/bump.yml +81 -0
- eth_mcp-0.2.0/.github/workflows/ci.yml +59 -0
- eth_mcp-0.2.0/.github/workflows/release.yml +72 -0
- eth_mcp-0.2.0/.gitignore +63 -0
- eth_mcp-0.2.0/.mcp.json +8 -0
- eth_mcp-0.2.0/CLAUDE.md +118 -0
- eth_mcp-0.2.0/PKG-INFO +332 -0
- eth_mcp-0.2.0/README.md +286 -0
- eth_mcp-0.2.0/docs/INCREMENTAL_INDEXING.md +326 -0
- eth_mcp-0.2.0/pyproject.toml +112 -0
- eth_mcp-0.2.0/src/ethereum_mcp/__init__.py +3 -0
- eth_mcp-0.2.0/src/ethereum_mcp/cli.py +589 -0
- eth_mcp-0.2.0/src/ethereum_mcp/clients.py +363 -0
- eth_mcp-0.2.0/src/ethereum_mcp/config.py +324 -0
- eth_mcp-0.2.0/src/ethereum_mcp/expert/__init__.py +1 -0
- eth_mcp-0.2.0/src/ethereum_mcp/expert/guidance.py +300 -0
- eth_mcp-0.2.0/src/ethereum_mcp/indexer/__init__.py +8 -0
- eth_mcp-0.2.0/src/ethereum_mcp/indexer/chunker.py +563 -0
- eth_mcp-0.2.0/src/ethereum_mcp/indexer/client_compiler.py +725 -0
- eth_mcp-0.2.0/src/ethereum_mcp/indexer/compiler.py +245 -0
- eth_mcp-0.2.0/src/ethereum_mcp/indexer/downloader.py +521 -0
- eth_mcp-0.2.0/src/ethereum_mcp/indexer/embedder.py +627 -0
- eth_mcp-0.2.0/src/ethereum_mcp/indexer/manifest.py +411 -0
- eth_mcp-0.2.0/src/ethereum_mcp/logging.py +85 -0
- eth_mcp-0.2.0/src/ethereum_mcp/models.py +126 -0
- eth_mcp-0.2.0/src/ethereum_mcp/server.py +555 -0
- eth_mcp-0.2.0/src/ethereum_mcp/tools/__init__.py +1 -0
- eth_mcp-0.2.0/tests/__init__.py +1 -0
- eth_mcp-0.2.0/tests/conftest.py +166 -0
- eth_mcp-0.2.0/tests/test_chunker.py +399 -0
- eth_mcp-0.2.0/tests/test_config.py +238 -0
- eth_mcp-0.2.0/tests/test_guidance.py +125 -0
- eth_mcp-0.2.0/tests/test_incremental.py +413 -0
- eth_mcp-0.2.0/tests/test_manifest.py +443 -0
- eth_mcp-0.2.0/tests/test_models.py +180 -0
- eth_mcp-0.2.0/tests/test_security.py +317 -0
- eth_mcp-0.2.0/tests/test_server.py +47 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
name: Bump Version
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
bump_type:
|
|
7
|
+
description: 'Version bump type'
|
|
8
|
+
required: true
|
|
9
|
+
default: 'patch'
|
|
10
|
+
type: choice
|
|
11
|
+
options:
|
|
12
|
+
- patch
|
|
13
|
+
- minor
|
|
14
|
+
- major
|
|
15
|
+
|
|
16
|
+
permissions:
|
|
17
|
+
contents: write
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
bump:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
with:
|
|
25
|
+
fetch-depth: 0
|
|
26
|
+
|
|
27
|
+
- name: Set up Python
|
|
28
|
+
uses: actions/setup-python@v5
|
|
29
|
+
with:
|
|
30
|
+
python-version: '3.11'
|
|
31
|
+
|
|
32
|
+
- name: Install toml
|
|
33
|
+
run: pip install toml
|
|
34
|
+
|
|
35
|
+
- name: Bump version
|
|
36
|
+
id: bump
|
|
37
|
+
run: |
|
|
38
|
+
python << 'EOF'
|
|
39
|
+
import toml
|
|
40
|
+
import re
|
|
41
|
+
import os
|
|
42
|
+
|
|
43
|
+
# Read current version
|
|
44
|
+
with open('pyproject.toml', 'r') as f:
|
|
45
|
+
data = toml.load(f)
|
|
46
|
+
|
|
47
|
+
current = data['project']['version']
|
|
48
|
+
major, minor, patch = map(int, current.split('.'))
|
|
49
|
+
|
|
50
|
+
bump_type = '${{ inputs.bump_type }}'
|
|
51
|
+
if bump_type == 'major':
|
|
52
|
+
major += 1
|
|
53
|
+
minor = 0
|
|
54
|
+
patch = 0
|
|
55
|
+
elif bump_type == 'minor':
|
|
56
|
+
minor += 1
|
|
57
|
+
patch = 0
|
|
58
|
+
else:
|
|
59
|
+
patch += 1
|
|
60
|
+
|
|
61
|
+
new_version = f'{major}.{minor}.{patch}'
|
|
62
|
+
data['project']['version'] = new_version
|
|
63
|
+
|
|
64
|
+
with open('pyproject.toml', 'w') as f:
|
|
65
|
+
toml.dump(data, f)
|
|
66
|
+
|
|
67
|
+
print(f'Bumped {current} -> {new_version}')
|
|
68
|
+
|
|
69
|
+
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
|
|
70
|
+
f.write(f'version={new_version}\n')
|
|
71
|
+
f.write(f'tag=v{new_version}\n')
|
|
72
|
+
EOF
|
|
73
|
+
|
|
74
|
+
- name: Commit and tag
|
|
75
|
+
run: |
|
|
76
|
+
git config user.name "github-actions[bot]"
|
|
77
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
78
|
+
git add pyproject.toml
|
|
79
|
+
git commit -m "chore: bump version to ${{ steps.bump.outputs.version }}"
|
|
80
|
+
git tag ${{ steps.bump.outputs.tag }}
|
|
81
|
+
git push origin main --tags
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ['3.11', '3.12']
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
20
|
+
uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: ${{ matrix.python-version }}
|
|
23
|
+
|
|
24
|
+
- name: Install dependencies
|
|
25
|
+
run: |
|
|
26
|
+
python -m pip install --upgrade pip
|
|
27
|
+
pip install -e ".[dev]"
|
|
28
|
+
|
|
29
|
+
- name: Run linter
|
|
30
|
+
run: ruff check src/
|
|
31
|
+
|
|
32
|
+
- name: Run tests
|
|
33
|
+
run: pytest tests/ -v --cov=ethereum_mcp --cov-report=xml
|
|
34
|
+
|
|
35
|
+
- name: Upload coverage
|
|
36
|
+
uses: codecov/codecov-action@v4
|
|
37
|
+
if: matrix.python-version == '3.11'
|
|
38
|
+
with:
|
|
39
|
+
files: coverage.xml
|
|
40
|
+
fail_ci_if_error: false
|
|
41
|
+
|
|
42
|
+
build:
|
|
43
|
+
runs-on: ubuntu-latest
|
|
44
|
+
steps:
|
|
45
|
+
- uses: actions/checkout@v4
|
|
46
|
+
|
|
47
|
+
- name: Set up Python
|
|
48
|
+
uses: actions/setup-python@v5
|
|
49
|
+
with:
|
|
50
|
+
python-version: '3.11'
|
|
51
|
+
|
|
52
|
+
- name: Install build dependencies
|
|
53
|
+
run: pip install build twine
|
|
54
|
+
|
|
55
|
+
- name: Build package
|
|
56
|
+
run: python -m build
|
|
57
|
+
|
|
58
|
+
- name: Check package
|
|
59
|
+
run: twine check dist/*
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
name: Release to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
id-token: write # Required for OIDC
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- name: Set up Python
|
|
19
|
+
uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: '3.11'
|
|
22
|
+
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: |
|
|
25
|
+
python -m pip install --upgrade pip
|
|
26
|
+
pip install -e ".[dev]"
|
|
27
|
+
|
|
28
|
+
- name: Run tests
|
|
29
|
+
run: pytest tests/ -v
|
|
30
|
+
|
|
31
|
+
- name: Run linter
|
|
32
|
+
run: ruff check src/
|
|
33
|
+
|
|
34
|
+
build:
|
|
35
|
+
needs: test
|
|
36
|
+
runs-on: ubuntu-latest
|
|
37
|
+
steps:
|
|
38
|
+
- uses: actions/checkout@v4
|
|
39
|
+
|
|
40
|
+
- name: Set up Python
|
|
41
|
+
uses: actions/setup-python@v5
|
|
42
|
+
with:
|
|
43
|
+
python-version: '3.11'
|
|
44
|
+
|
|
45
|
+
- name: Install build dependencies
|
|
46
|
+
run: pip install build
|
|
47
|
+
|
|
48
|
+
- name: Build package
|
|
49
|
+
run: python -m build
|
|
50
|
+
|
|
51
|
+
- name: Upload artifacts
|
|
52
|
+
uses: actions/upload-artifact@v4
|
|
53
|
+
with:
|
|
54
|
+
name: dist
|
|
55
|
+
path: dist/
|
|
56
|
+
|
|
57
|
+
publish:
|
|
58
|
+
needs: build
|
|
59
|
+
runs-on: ubuntu-latest
|
|
60
|
+
environment:
|
|
61
|
+
name: pypi
|
|
62
|
+
url: https://pypi.org/p/eth-mcp
|
|
63
|
+
steps:
|
|
64
|
+
- name: Download artifacts
|
|
65
|
+
uses: actions/download-artifact@v4
|
|
66
|
+
with:
|
|
67
|
+
name: dist
|
|
68
|
+
path: dist/
|
|
69
|
+
|
|
70
|
+
- name: Publish to PyPI
|
|
71
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
72
|
+
# No password needed - uses OIDC trusted publishing
|
eth_mcp-0.2.0/.gitignore
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
*.egg-info/
|
|
20
|
+
.installed.cfg
|
|
21
|
+
*.egg
|
|
22
|
+
|
|
23
|
+
# Virtual environments
|
|
24
|
+
venv/
|
|
25
|
+
ENV/
|
|
26
|
+
env/
|
|
27
|
+
.venv/
|
|
28
|
+
|
|
29
|
+
# IDE
|
|
30
|
+
.idea/
|
|
31
|
+
.vscode/
|
|
32
|
+
*.swp
|
|
33
|
+
*.swo
|
|
34
|
+
|
|
35
|
+
# Testing
|
|
36
|
+
.pytest_cache/
|
|
37
|
+
.coverage
|
|
38
|
+
htmlcov/
|
|
39
|
+
|
|
40
|
+
# Data (downloaded repos and indices - large, user-specific)
|
|
41
|
+
# Users should run `ethereum-mcp build` to generate these
|
|
42
|
+
# Uncomment if you want to track compiled data:
|
|
43
|
+
# !data/compiled/
|
|
44
|
+
|
|
45
|
+
# Misc
|
|
46
|
+
.DS_Store
|
|
47
|
+
*.log
|
|
48
|
+
|
|
49
|
+
# Secrets and sensitive files (defense in depth)
|
|
50
|
+
.env
|
|
51
|
+
.env.*
|
|
52
|
+
*.env
|
|
53
|
+
!.env.example
|
|
54
|
+
.envrc
|
|
55
|
+
*.pem
|
|
56
|
+
*.key
|
|
57
|
+
*.p12
|
|
58
|
+
*.secret
|
|
59
|
+
*.credentials
|
|
60
|
+
credentials.json
|
|
61
|
+
secrets.json
|
|
62
|
+
*_private.*
|
|
63
|
+
*.private.*
|
eth_mcp-0.2.0/.mcp.json
ADDED
eth_mcp-0.2.0/CLAUDE.md
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# ethereum-mcp
|
|
2
|
+
|
|
3
|
+
RAG-powered MCP server for Ethereum consensus specs and EIPs.
|
|
4
|
+
|
|
5
|
+
## Quick Reference
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Full build (download + compile + index)
|
|
9
|
+
ethereum-mcp build
|
|
10
|
+
|
|
11
|
+
# Individual steps
|
|
12
|
+
ethereum-mcp download # Clone consensus-specs and EIPs
|
|
13
|
+
ethereum-mcp compile # Extract constants/functions to JSON
|
|
14
|
+
ethereum-mcp index # Build vector embeddings in LanceDB
|
|
15
|
+
|
|
16
|
+
# Incremental updates (fast)
|
|
17
|
+
ethereum-mcp update # Git pull + incremental re-index
|
|
18
|
+
ethereum-mcp index # Incremental by default
|
|
19
|
+
ethereum-mcp index --full # Force full rebuild
|
|
20
|
+
ethereum-mcp index --dry-run # Preview what would change
|
|
21
|
+
|
|
22
|
+
# Search
|
|
23
|
+
ethereum-mcp search "slashing penalty"
|
|
24
|
+
ethereum-mcp status # Check index status
|
|
25
|
+
ethereum-mcp models # List available embedding models
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## MCP Tools
|
|
29
|
+
|
|
30
|
+
| Tool | Purpose |
|
|
31
|
+
|------|---------|
|
|
32
|
+
| `eth_search` | Unified search across specs + EIPs (default: current fork) |
|
|
33
|
+
| `eth_get_current_fork` | Returns active fork name |
|
|
34
|
+
| `eth_list_forks` | All upgrades with dates/epochs |
|
|
35
|
+
| `eth_search_specs` | Specs-only search (no EIPs) |
|
|
36
|
+
| `eth_grep_constant` | Fast constant lookup |
|
|
37
|
+
| `eth_analyze_function` | Get Python implementation from specs |
|
|
38
|
+
| `eth_get_spec_version` | Index metadata |
|
|
39
|
+
| `eth_expert_guidance` | Curated expert interpretations |
|
|
40
|
+
| `eth_search_eip` | EIP-specific search |
|
|
41
|
+
|
|
42
|
+
## Project Structure
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
src/ethereum_mcp/
|
|
46
|
+
├── server.py # MCP server (FastMCP)
|
|
47
|
+
├── cli.py # CLI commands
|
|
48
|
+
├── config.py # Configuration management
|
|
49
|
+
├── indexer/
|
|
50
|
+
│ ├── downloader.py # Git clone specs/EIPs
|
|
51
|
+
│ ├── compiler.py # Extract to JSON
|
|
52
|
+
│ ├── chunker.py # Markdown chunking + chunk IDs
|
|
53
|
+
│ ├── embedder.py # Embeddings + LanceDB + IncrementalEmbedder
|
|
54
|
+
│ └── manifest.py # File tracking for incremental updates
|
|
55
|
+
└── expert/
|
|
56
|
+
└── guidance.py # Curated interpretations
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Data Location
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
~/.ethereum-mcp/
|
|
63
|
+
├── config.yaml # Configuration (optional)
|
|
64
|
+
├── manifest.json # Index state tracking
|
|
65
|
+
├── consensus-specs/ # Cloned repo
|
|
66
|
+
├── EIPs/ # Cloned repo
|
|
67
|
+
├── builder-specs/ # Cloned repo
|
|
68
|
+
├── compiled/ # JSON extracts per fork
|
|
69
|
+
└── lancedb/ # Vector index
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Configuration
|
|
73
|
+
|
|
74
|
+
Create `~/.ethereum-mcp/config.yaml` to customize:
|
|
75
|
+
|
|
76
|
+
```yaml
|
|
77
|
+
embedding:
|
|
78
|
+
model: "all-MiniLM-L6-v2" # Or codesage/codesage-large
|
|
79
|
+
batch_size: 32
|
|
80
|
+
|
|
81
|
+
chunking:
|
|
82
|
+
chunk_size: 1000
|
|
83
|
+
chunk_overlap: 200
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Available models: `all-MiniLM-L6-v2`, `all-mpnet-base-v2`, `codesage/codesage-large`, `voyage:voyage-code-3`
|
|
87
|
+
|
|
88
|
+
## Development
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
pip install -e ".[dev]"
|
|
92
|
+
pytest
|
|
93
|
+
ruff check src/
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Incremental Indexing
|
|
97
|
+
|
|
98
|
+
See [docs/INCREMENTAL_INDEXING.md](docs/INCREMENTAL_INDEXING.md) for detailed documentation.
|
|
99
|
+
|
|
100
|
+
Key concepts:
|
|
101
|
+
- **Manifest**: Tracks file hashes and chunk IDs
|
|
102
|
+
- **Chunk IDs**: Deterministic IDs based on content hash
|
|
103
|
+
- **Change detection**: Fast mtime check, then hash verification
|
|
104
|
+
- **Delta updates**: Only re-embed changed content
|
|
105
|
+
|
|
106
|
+
## Adding Expert Guidance
|
|
107
|
+
|
|
108
|
+
Edit `src/ethereum_mcp/expert/guidance.py` to add entries:
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
GUIDANCE_DB["topic"] = GuidanceEntry(
|
|
112
|
+
topic="Topic Name",
|
|
113
|
+
summary="Brief summary",
|
|
114
|
+
key_points=["point 1", "point 2"],
|
|
115
|
+
gotchas=["gotcha 1", "gotcha 2"],
|
|
116
|
+
references=["specs/fork/file.md"],
|
|
117
|
+
)
|
|
118
|
+
```
|