Skip to content

Commit a1a2fad

Browse files
committed
refactor cpg generation and query execution
1 parent 8dde347 commit a1a2fad

18 files changed

+1007
-1305
lines changed

Dockerfile

Lines changed: 13 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,16 @@
1-
# Dockerfile for CodeBadger Toolkit Server
2-
# Container with Joern, Python MCP server, and Redis
1+
# Dockerfile for Joern Server Container
2+
# Contains Joern CLI and Redis for CPG generation and caching
33

44
FROM eclipse-temurin:21-jdk-jammy
55

6-
# Install system dependencies including Python 3.12 and Redis
6+
# Install system dependencies
77
RUN apt-get update && apt-get install -y \
88
curl \
9-
git \
109
wget \
1110
unzip \
12-
build-essential \
13-
software-properties-common \
1411
redis-server \
15-
libffi-dev \
16-
libssl-dev \
17-
&& add-apt-repository ppa:deadsnakes/ppa \
18-
&& apt-get update \
19-
&& apt-get install -y \
20-
python3.12 \
21-
python3.12-venv \
22-
python3.12-dev \
23-
python3-pip \
2412
&& rm -rf /var/lib/apt/lists/*
2513

26-
# Set Python 3.12 as default
27-
RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.12 1 \
28-
&& update-alternatives --install /usr/bin/python python /usr/bin/python3.12 1
29-
3014
# Set Joern version
3115
ENV JOERN_VERSION=4.0.429
3216
ENV JOERN_HOME=/opt/joern
@@ -43,22 +27,10 @@ RUN mkdir -p ${JOERN_HOME} && \
4327
# Add Joern CLI tools to PATH
4428
ENV PATH="${JOERN_HOME}/joern-cli:${JOERN_HOME}/joern-cli/bin:${PATH}"
4529

46-
# Create workspace and playground directories
47-
RUN mkdir -p /workspace /playground /app
48-
49-
# Copy MCP server code
50-
COPY . /app
51-
WORKDIR /app
30+
# Create playground directory for CPG storage
31+
RUN mkdir -p /playground
5232

53-
# Install Python dependencies
54-
# Ensure pip/setuptools are available for python3 (pointing to 3.12)
55-
RUN python3 -m ensurepip --upgrade || true && \
56-
python3 -m pip install --upgrade pip setuptools wheel && \
57-
python3 -m pip install --no-cache-dir -r requirements.txt && \
58-
python3 -m pip uninstall -y cryptography && \
59-
python3 -m pip install --no-cache-dir cffi cryptography
60-
61-
# Configure Redis to run in background
33+
# Configure Redis to run in background and listen on all interfaces
6234
RUN mkdir -p /var/lib/redis && \
6335
chown redis:redis /var/lib/redis && \
6436
sed -i 's/^daemonize no/daemonize yes/' /etc/redis/redis.conf && \
@@ -67,23 +39,19 @@ RUN mkdir -p /var/lib/redis && \
6739
# Verify Joern installation
6840
RUN joern --help
6941

70-
# Expose MCP server port only
71-
EXPOSE 4242
42+
# Expose Redis port
43+
EXPOSE 6379
7244

73-
# Create entrypoint script
45+
# Create entrypoint script that starts Redis
7446
RUN echo '#!/bin/bash\n\
7547
set -e\n\
7648
\n\
7749
# Start Redis in background\n\
7850
redis-server /etc/redis/redis.conf\n\
7951
\n\
80-
# Wait for Redis to be ready\n\
81-
sleep 2\n\
82-
\n\
83-
# Start MCP server\n\
84-
cd /app\n\
85-
exec python3 main.py\n\
86-
' > /app/entrypoint.sh && chmod +x /app/entrypoint.sh
52+
# Keep container running\n\
53+
tail -f /dev/null\n\
54+
' > /entrypoint.sh && chmod +x /entrypoint.sh
8755

8856
# Run entrypoint script
89-
CMD ["/app/entrypoint.sh"]
57+
CMD ["/entrypoint.sh"]

README.md

Lines changed: 158 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,86 @@
22

33
A containerized Model Context Protocol (MCP) server providing static code analysis using Joern's Code Property Graph (CPG) technology with support for Java, C/C++, JavaScript, Python, Go, Kotlin, C#, Ghidra, Jimple, PHP, Ruby, and Swift.
44

5+
## Prerequisites
6+
7+
Before you begin, make sure you have:
8+
9+
- **Docker** and **Docker Compose** installed
10+
- **Python 3.10+** (Python 3.13 recommended)
11+
- **pip** (Python package manager)
12+
13+
To verify your setup:
14+
15+
```bash
16+
docker --version
17+
docker-compose --version
18+
python --version
19+
```
20+
521
## Quick Start
622

7-
### Build and Run the Container
23+
### 1. Install Python Dependencies
24+
25+
```bash
26+
# Create a virtual environment (optional but recommended)
27+
python -m venv venv
28+
source venv/bin/activate # On Windows: venv\Scripts\activate
29+
30+
# Install dependencies
31+
pip install -r requirements.txt
32+
```
33+
34+
### 2. Start the Docker Services (Joern + Redis)
835

936
```bash
10-
docker compose up --build
37+
docker compose up -d
38+
```
39+
40+
This starts:
41+
- **Joern Server**: Static code analysis engine (runs CPG generation and queries)
42+
- **Redis**: Metadata storage (tracks codebases, ports, and CPG information)
43+
44+
Verify services are running:
45+
46+
```bash
47+
docker compose ps
48+
```
49+
50+
### 3. Start the MCP Server
51+
52+
```bash
53+
# Set the correct Redis port (maps to container's 6379)
54+
REDIS_PORT=6380 python main.py
1155
```
1256

1357
The MCP server will be available at `http://localhost:4242`.
1458

15-
### Stop the Service
59+
### 4. Stop All Services
1660

1761
```bash
18-
docker compose down
62+
# Stop MCP server (Ctrl+C in terminal)
63+
64+
# Stop Docker services
65+
docker-compose down
66+
67+
# Optional: Clean up everything
68+
bash cleanup.sh
1969
```
2070

71+
## Cleanup Script
72+
73+
Use the provided cleanup script to reset your environment:
74+
75+
```bash
76+
bash cleanup.sh
77+
```
78+
79+
This will:
80+
- Stop and remove Docker containers
81+
- Kill orphaned Joern/MCP processes
82+
- Clear Python cache (`__pycache__`, `.pytest_cache`)
83+
- Optionally clear the playground directory (CPGs and cached codebases)
84+
2185
## Integrations
2286

2387
### GitHub Copilot Integration
@@ -100,49 +164,121 @@ Add the following:
100164

101165
Thanks for contributing! Here's a quick guide to get started with running tests and contributing code.
102166

103-
Prerequisites
167+
### Prerequisites
168+
104169
- Python 3.10+ (3.13 is used in CI)
105170
- Docker and Docker Compose (for integration tests)
106171

107-
Local development
172+
### Local Development Setup
173+
108174
1. Create a virtual environment and install dependencies
109175

110176
```bash
111177
python -m venv venv
112-
source venv/bin/activate
113178
pip install -r requirements.txt
114179
```
115180

116-
2. Run unit tests
181+
2. Start Docker services (for integration tests)
182+
183+
```bash
184+
docker-compose up -d
185+
```
186+
187+
3. Run unit tests
188+
189+
```bash
190+
pytest tests/ -q
191+
```
192+
193+
4. Run integration tests (requires Docker Compose running)
117194

118195
```bash
119-
pytest -q
196+
# Start MCP server in background
197+
REDIS_PORT=6380 python main.py &
198+
199+
# Run integration tests
200+
pytest tests/integration -q
201+
202+
# Stop MCP server
203+
pkill -f "python main.py"
120204
```
121205

122-
3. Run integration tests (requires Docker Compose)
206+
5. Run all tests
123207

124208
```bash
125-
docker compose up --build -d
126-
pytest -q tests/integration
127-
docker compose down
209+
pytest tests/ -q
128210
```
129211

130-
4. Run all tests
212+
6. Cleanup after testing
131213

132214
```bash
133-
pytest -q
215+
bash cleanup.sh
216+
docker-compose down
134217
```
135218

136-
Please follow the repository conventions and open a PR with a clear changelog and tests for changes that affect behavior.
219+
### Code Contributions
220+
221+
Please follow these guidelines when contributing:
222+
223+
1. Follow repository conventions
224+
2. Write tests for behavioral changes
225+
3. Ensure all tests pass before submitting PR
226+
4. Include a clear changelog in your PR description
227+
5. Update documentation if needed
137228

138229
## Configuration
139230

140-
Optional configuration via `config.yaml` (copy from `config.example.yaml`).
231+
The MCP server can be configured via environment variables or `config.yaml`.
232+
233+
### Environment Variables
234+
235+
Key settings (optional - defaults shown):
141236

142-
Key settings:
143-
- Server host/port
144-
- Redis settings
145-
- Session timeouts
146-
- CPG generation settings
237+
```bash
238+
# Server
239+
MCP_HOST=0.0.0.0
240+
MCP_PORT=4242
241+
242+
# Redis (running inside Docker container)
243+
REDIS_HOST=localhost
244+
REDIS_PORT=6380 # ⚠️ IMPORTANT: Port 6380 on host maps to 6379 in container
245+
246+
# Joern
247+
JOERN_BINARY_PATH=joern
248+
JOERN_JAVA_OPTS="-Xmx4G -Xms2G -XX:+UseG1GC -Dfile.encoding=UTF-8"
249+
250+
# CPG Generation
251+
CPG_GENERATION_TIMEOUT=600
252+
MAX_REPO_SIZE_MB=500
253+
254+
# Query
255+
QUERY_TIMEOUT=30
256+
QUERY_CACHE_ENABLED=true
257+
QUERY_CACHE_TTL=300
258+
```
259+
260+
### Config File
261+
262+
Create a `config.yaml` from `config.example.yaml`:
263+
264+
```bash
265+
cp config.example.yaml config.yaml
266+
```
267+
268+
Then customize as needed.
269+
270+
### Important: Redis Port Configuration
271+
272+
Since Redis runs inside the Docker container:
273+
274+
- **Inside container**: Redis listens on `6379`
275+
- **Host mapping**: Docker maps `6380:6379`
276+
- **MCP server should use**: `REDIS_PORT=6380`
277+
278+
Always start the MCP server with:
279+
280+
```bash
281+
REDIS_PORT=6380 python main.py
282+
```
147283

148284

config.example.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
server:
2-
host: ${MCP_HOST:0.0.0.0}
2+
host: ${MCP_HOST:127.0.0.1}
33
port: ${MCP_PORT:4242}
44
log_level: ${MCP_LOG_LEVEL:INFO}
55

66
redis:
77
host: ${REDIS_HOST:localhost}
8-
port: ${REDIS_PORT:6379}
8+
port: ${REDIS_PORT:6380}
99
password: ${REDIS_PASSWORD:}
1010
db: ${REDIS_DB:0}
1111

@@ -478,3 +478,4 @@ query:
478478
storage:
479479
workspace_root: ${WORKSPACE_ROOT:/tmp/codebadger-toolkit}
480480
cleanup_on_shutdown: ${CLEANUP_ON_SHUTDOWN:true}
481+

docker-compose.yml

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,25 @@
11
version: '3.8'
22

33
services:
4-
codebadger-toolkit:
4+
# Joern server with Redis (container)
5+
codebadger-joern-server:
56
build:
67
context: .
78
dockerfile: Dockerfile
8-
image: codebadger-toolkit:latest
9-
container_name: codebadger-toolkit-server
9+
image: codebadger-joern-server:latest
10+
container_name: codebadger-joern-server
1011
ports:
11-
- "4242:4242"
12-
environment:
13-
- MCP_HOST=0.0.0.0
14-
- MCP_PORT=4242
15-
- REDIS_HOST=localhost
16-
- REDIS_PORT=6379
17-
- PYTHONUNBUFFERED=1
12+
- "6380:6379"
13+
# Expose ports 2000-2999 for Joern servers
14+
- "2000-2999:2000-2999"
1815
volumes:
19-
# Mount playground for persistent CPG storage
20-
- ./playground:/app/playground
16+
# Mount playground for CPG storage (shared with host)
17+
- ./playground:/playground
2118
restart: unless-stopped
2219
healthcheck:
23-
test: ["CMD", "curl", "-f", "http://localhost:4242/mcp"]
20+
test: ["CMD", "redis-cli", "ping"]
2421
interval: 10s
2522
timeout: 5s
2623
retries: 3
27-
start_period: 30s
24+
start_period: 10s
25+

0 commit comments

Comments
 (0)