π Executive Summary
Project: evmBench-mcp-server
Review Date: 2026-03-08
Reviewer: Professional Code Review
Overall Rating: ββββββββββ (8/10)
Project Type: Smart Contract Security Auditing Platform with MCP Integration
Tech Stack:
- Backend: Python 3.11+, FastAPI, PostgreSQL, RabbitMQ, Docker/Kubernetes
- Frontend: TypeScript, Next.js 16, React 19, Bun
- Codebase Size: ~180KB Python, ~301KB TypeScript (total ~500KB)
π― Project Overview
evmBench-mcp-server is a production-grade smart contract auditing system that extends OpenAI's evmBench with MCP (Model Context Protocol) capabilities. It allows users to:
- Upload contract source code (ZIP)
- Select an AI model
- Get automated vulnerability reports
- Access via Web UI or MCP API
Key Innovation: MCP integration enables other agents/tools to programmatically trigger audits, making it agent-native.
ποΈ Architecture Analysis (9.5/10)
β
Strengths
1. Microservices Design - Exceptional
Frontend (Next.js) βββΊ Backend API (FastAPI:1337)
βββΊ PostgreSQL (job state)
βββΊ Secrets Service (:8081)
βββΊ Results Service (:8083)
βββΊ OAI Proxy (:8084, optional)
βββΊ RabbitMQ (job queue)
β
Instancer (consumer)
β
ββββββββββββ΄ββββββββββββ
βΌ βΌ
Docker Backend K8s Backend
β β
ββββββββββββ¬ββββββββββββ
βΌ
Worker Container
βββΊ Fetch bundle
βββΊ Run Codex agent
βββΊ Upload results
Why it's excellent:
- Separation of concerns: Each service has single responsibility
- Scal ability: RabbitMQ queue + multiple worker backends
- Security isolation: Worker runs in sandboxed environment
- Flexibility: Supports both Docker and Kubernetes deployments
2. Security-First Design - Outstanding
Trust Boundary Model:
ββββββββββββββββββββββββββββββββββββββββββββββββ
β UNTRUSTED ZONE (Worker) β
β β’ Uploaded code (potentially malicious) β
β β’ Agent execution environment β
β β’ Filesystem, logs, outputs β
ββββββββββββββββββββββββββββββββββββββββββββββββ
β
Secret Bundle (encrypted)
β
ββββββββββββββββββββββββββββββββββββββββββββββββ
β TRUSTED ZONE (Backend Services) β
β β’ PostgreSQL, RabbitMQ β
β β’ Secrets/Results Services β
ββββββββββββββββββββββββββββββββββββββββββββββββ
Credential Handling Modes:
-
Direct BYOK (default): Worker gets plaintext OpenAI key
- Pros: Simple, low latency
- Cons: Key exposed in worker environment
- Use case: Local development, trusted environments
-
Proxy-Token Mode (recommended for production):
# Backend encrypts key
encrypt_token(key, AES-GCM) β opaque_token
# Worker sends token to oai_proxy
Worker β oai_proxy (decrypts) β OpenAI API
- Pros: Zero plaintext keys in worker
- Cons: Added hop, slightly higher latency
- Use case: Internet-exposed deployments
This is industry best-practice for handling secrets in untrusted environments.
3. MCP Integration - Well-Designed
5 MCP Tools Implemented:
| Tool |
Purpose |
Auth |
start_job |
Submit contract zip + model |
MCP-API-Key header |
get_job_status |
Poll job result |
Service user identity |
get_job_history |
List past audits |
Limited to 100 |
set_job_public |
Toggle visibility |
Owner-only |
get_frontend_config |
Get backend config |
Public |
Code Quality Example (api/mcp/tools.py):
async def tool_start_job(
*,
file_base64: str,
file_name: str,
model: str,
openai_key: str | None = None,
app_state: object,
) -> dict:
"""Start a smart-contract audit job."""
token = _mcp_token() # Fixed service identity
# Validation
upload = _decode_upload(file_base64, file_name) # Base64 β UploadFile
openai_token, key_mode = _resolve_openai_token(openai_key) # Handle 3 modes
# Check for existing queued/running job
async with _db.acquire() as session:
existing = await session.scalar(...)
if existing:
raise ValueError('You already have a queued or running job')
# Create job, save bundle, publish to queue
job_id = uuid.uuid4()
secret_ref = os.urandom(32).hex()
bundle = build_secret_bundle(...)
await secret_storage.save_secret(secret_ref, bundle)
job = Job(id=job_id, status=JobStatus.queued, ...)
session.add(job)
await session.commit()
await publisher.publish_job_start(...)
return {'job_id': str(job_id), 'status': job.status.value}
Observations:
- β
Type hints: Full type annotations
- β
Error handling: Proper exception propagation
- β
Async/await: Non-blocking I/O
- β
Resource cleanup: Context managers for DB sessions
- β
Security: Fixed service identity, no user impersonation
π Security Analysis (8.5/10)
β
Excellent Security Practices
- Documented SECURITY.md - Clear trust model and threat analysis
- Secret isolation - Workers never see plaintext keys in proxy mode
- Input validation:
validate_upload_zip(
upload,
max_uncompressed_bytes=settings.BACKEND_MAX_ATTACHMENT_UNCOMPRESSED_BYTES,
max_files=settings.BACKEND_ZIP_MAX_FILES,
max_ratio=settings.BACKEND_ZIP_MAX_COMPRESSION_RATIO,
require_solidity=True,
)
- Rate limiting - Daily job limits enforced
- Authentication - MCP-API-Key header required
- Job ownership - Users can only access their own jobs (unless public)
- AES-GCM encryption - For proxy tokens
β οΈ Security Concerns Found
1. CRITICAL: Weak Development Credentials in .env.example
# .env.example
POSTGRES_PASSWORD='DO_NOT_USE_ME'
RABBITMQ_PASSWORD='DO_NOT_USE_ME'
SECRETS_TOKEN_RO='dev-secret'
BACKEND_MCP_API_KEY=dev-secret
Risk: Developers might copy these to production
Recommendation:
# Replace with:
POSTGRES_PASSWORD='<CHANGE_ME - generate with: openssl rand -hex 32>'
RABBITMQ_PASSWORD='<CHANGE_ME - generate with: openssl rand -hex 32>'
SECRETS_TOKEN_RO='<CHANGE_ME - use: python -c "import secrets; print(secrets.token_urlsafe(32))">'
2. HIGH: TODO Comments Indicate Unfinished Security Work
# instancer/backends/k8s.py
# TODO(trixter-osec): consider in the future hardening and running as non-root?
Risk: Workers running as root in Kubernetes
Recommendation:
- Add
securityContext to K8s pod spec:
securityContext:
runAsNonRoot: true
runAsUser: 65534 # nobody
readOnlyRootFilesystem: true
3. MEDIUM: Missing Rate Limiting Documentation
Code mentions "daily limits" but no documentation on:
- How limits are calculated
- What happens when exceeded
- How to customize per-user
4. LOW: No Audit Logging
No evidence of audit trail for:
- Job submissions
- MCP API access
- Admin actions
Recommendation: Add structured logging:
logger.info(
"mcp_job_started",
extra={
"job_id": str(job_id),
"user_id": token.user_id,
"model": model,
"ip": request.client.host
}
)
π Code Quality Analysis (7.5/10)
β
Strengths
-
Ruff Linter Configured:
[tool.ruff.lint]
select = ["ALL"] # Enable ALL rules
ignore = ["D211", "D212", "D203", ...] # Selective ignores
-
Type Safety - Python 3.11+ with type hints
-
Async/Await - Proper async patterns
-
Dependency Injection - app_state pattern
-
Test Coverage - 4 test files (unit + integration)
β οΈ Issues Found
1. MEDIUM: Code Smells in Schemas
# api/schemas/job.py
# TODO(es3n1n): this is **very** bad
Found: Developer acknowledges bad design but hasn't fixed it
Recommendation: Investigate and refactor job.py schemas
2. MEDIUM: Model Design Needs Revamp
# api/models/job.py
# TODO(es3n1n): revamp
Recommendation: Schedule database schema review
3. LOW: Inconsistent Error Messages
Some functions return:
raise ValueError(msg) # Good: structured
Others:
raise RuntimeError(msg) # Mixed: should use custom exceptions
Recommendation: Define custom exception hierarchy:
class EvmBenchError(Exception): pass
class JobNotFoundError(EvmBenchError): pass
class InvalidUploadError(EvmBenchError): pass
4. LOW: Missing Type Annotations in Some Functions
def _get_rabbitmq(app_state: object) -> RabbitMQPublisher:
# app_state is 'object' - too generic
Recommendation: Define proper type:
from typing import Protocol
class AppState(Protocol):
rabbitmq: RabbitMQPublisher | None
π§ͺ Testing Analysis (7/10)
Current State
Test Files:
test_mcp_tools.py - MCP tool unit tests
test_mcp_integration.py - Integration tests
conftest.py - Pytest fixtures
Test Framework: pytest + pytest-asyncio + pytest-cov
Observations:
- β
Tests exist for critical MCP functions
- β
Async tests properly configured
- β οΈ NO coverage report found
- β οΈ NO frontend tests found
Recommendations
-
Add Coverage Reporting:
pytest --cov=api --cov=instancer --cov=secretsvc --cov-report=html
-
Target: Achieve β₯80% coverage for:
api/mcp/tools.py (critical)
api/util/zip_validate.py (security)
api/util/aes_gcm.py (cryptography)
-
Add Frontend Tests:
# frontend/package.json
"scripts": {
"test": "vitest",
"test:ui": "vitest --ui"
}
-
Add E2E Tests (Playwright recommended):
- Upload contract ZIP β Check result
- MCP API flow β Verify response
π Performance & Scalability (8/10)
β
Strong Points
- Async I/O: FastAPI + async/await throughout
- Message Queue: RabbitMQ decouples API from workers
- Multiple Workers: Horizontal scaling via Docker/K8s
- Connection Pooling: SQLAlchemy async pool
- Efficient JSON:
orjson for fast serialization
β οΈ Potential Bottlenecks
1. PostgreSQL Single Point of Failure
Current: Single Postgres instance
Risk: Database downtime = entire system down
Recommendation:
- Add read replicas for job status queries
- Consider connection pooling proxy (PgBouncer)
- Implement DB health checks + circuit breakers
2. No Caching Layer
Current: Every get_job_status hits database
Risk: Heavy polling can overwhelm DB
Recommendation:
# Add Redis cache
@cache(ttl=10) # 10 second TTL
async def tool_get_job_status(job_id: str) -> dict:
...
3. Missing Metrics/Monitoring
Current: No Prometheus/Grafana integration
Risk: Can't detect performance degradation
Recommendation: Add metrics:
from prometheus_client import Counter, Histogram
job_start_counter = Counter('evmbench_jobs_started', 'Total jobs started')
job_duration_histogram = Histogram('evmbench_job_duration_seconds', 'Job execution time')
π Documentation Analysis (8/10)
β
Strong Documentation
- README.md - Clear architecture diagram, setup steps
- SECURITY.md - Excellent threat model documentation
- backend/README.md - Service-specific docs
- Inline comments - Functions well-documented
β οΈ Missing Documentation
-
API Reference - No OpenAPI/Swagger docs exposed
- Fix: Add
/docs endpoint (FastAPI has built-in support)
-
MCP Tool Schemas - Not documented for external consumers
- Fix: Publish MCP tool definitions
-
Deployment Guide - No production deployment checklist
- Fix: Add
DEPLOYMENT.md with:
- Environment variable reference
- Security hardening steps
- Monitoring setup
- Backup/restore procedures
-
Troubleshooting Guide - No common issues documented
π’ Production Readiness Checklist
| Category |
Status |
Notes |
| Security |
β οΈ 85% |
Fix dev credentials, add audit logs |
| Reliability |
β οΈ 75% |
Add health checks, retries, circuit breakers |
| Scalability |
β
90% |
RabbitMQ + multi-backend ready |
| Monitoring |
β 40% |
No metrics, alerts, or dashboards |
| Documentation |
β
80% |
Good README, needs API ref |
| Testing |
β οΈ 70% |
Unit tests exist, need coverage + E2E |
| Dependencies |
β
95% |
Modern stack, up-to-date versions |
π Priority Action Items
π΄ Critical (Fix Before Production)
- Replace Dev Credentials in
.env.example
- Add Health Check Endpoints:
@app.get("/health")
async def health():
return {"status": "healthy", "version": "0.1.0"}
- Enable K8s Security Context (run as non-root)
- Implement Rate Limiting per user/IP
- Add Audit Logging for MCP access
π‘ High Priority (Next Sprint)
- Fix TODO Items in
api/schemas/job.py and api/models/job.py
- Add Test Coverage Reporting (target β₯80%)
- Implement Caching Layer (Redis) for job status
- Add Prometheus Metrics
- Document MCP Tool Schemas
π’ Medium Priority (Backlog)
- Frontend Tests (Vitest + Playwright)
- Custom Exception Hierarchy
- Database Read Replicas
- OpenAPI Documentation UI (
/docs)
- Deployment Automation (Terraform/Helm charts)
π‘ Architectural Recommendations
1. Add API Gateway
Internet
β
βΌ
[API Gateway - Kong/NGINX]
β
βββΊ Frontend (Next.js)
βββΊ Backend API (FastAPI)
Benefits:
- Centralized rate limiting
- Request logging
- SSL termination
- Load balancing
2. Implement Circuit Breakers
from circuitbreaker import circuit
@circuit(failure_threshold=5, recovery_timeout=60)
async def call_openai_api(...):
...
Prevents: Cascading failures when OpenAI API is down
3. Add Job Expiration
# Auto-delete old jobs after 30 days
@scheduler.scheduled_job('cron', day='*')
async def cleanup_old_jobs():
cutoff = datetime.utcnow() - timedelta(days=30)
await session.execute(
delete(Job).where(Job.created_at < cutoff)
)
π Learning from This Codebase
What to Emulate β¨
- Security-first design - Clear trust boundaries
- Microservices done right - Proper service separation
- Multiple deployment targets - Docker + K8s support
- Async Python patterns - FastAPI best practices
- Structured logging - Using
loguru
What to Avoid β οΈ
- TODO debt - Fix TODOs immediately or create issues
- Generic types -
app_state: object should be typed
- Missing monitoring - Add from day 1, not later
- Weak dev credentials - Use password managers even for dev
π Final Verdict
Overall Score: 8/10 ββββββββββ
Strengths:
- Excellent architecture and security design
- Well-implemented MCP integration
- Clean, type-safe Python code
- Good documentation foundation
- Production-ready infrastructure
Weaknesses:
- Missing monitoring/metrics
- Test coverage unknown (likely <70%)
- Some security TODO items unfixed
- No frontend tests
- Audit logging absent
Recommendation: APPROVE with conditions
This is a high-quality codebase with solid fundamentals. Address the Critical items before production deployment. The architecture is sound and will scale well.
Estimated Effort to Production-Ready: 2-3 sprints (4-6 weeks)
π Comparison: evmBench vs mcp-server-tron
| Aspect |
evmBench-mcp-server |
mcp-server-tron |
| Complexity |
High (microservices) |
Medium (monolithic) |
| Language |
Python + TypeScript |
TypeScript only |
| Architecture |
8/10 (excellent) |
9/10 (excellent) |
| Security |
8.5/10 (strong) |
10/10 (best-in-class) |
| Testing |
7/10 (needs work) |
9.5/10 (comprehensive) |
| Documentation |
8/10 (good) |
9/10 (excellent) |
| MCP Integration |
8/10 (5 tools) |
10/10 (60+ tools) |
| Production Ready |
75% |
95% |
Verdict: Both projects are high quality. mcp-server-tron is more polished and production-ready, while evmBench-mcp-server has more ambitious architecture but needs more work on testing and monitoring.
π References
π Executive Summary
Project: evmBench-mcp-server
Review Date: 2026-03-08
Reviewer: Professional Code Review
Overall Rating: ββββββββββ (8/10)
Project Type: Smart Contract Security Auditing Platform with MCP Integration
Tech Stack:
π― Project Overview
evmBench-mcp-server is a production-grade smart contract auditing system that extends OpenAI's evmBench with MCP (Model Context Protocol) capabilities. It allows users to:
Key Innovation: MCP integration enables other agents/tools to programmatically trigger audits, making it agent-native.
ποΈ Architecture Analysis (9.5/10)
β Strengths
1. Microservices Design - Exceptional
Why it's excellent:
2. Security-First Design - Outstanding
Trust Boundary Model:
Credential Handling Modes:
Direct BYOK (default): Worker gets plaintext OpenAI key
Proxy-Token Mode (recommended for production):
This is industry best-practice for handling secrets in untrusted environments.
3. MCP Integration - Well-Designed
5 MCP Tools Implemented:
start_jobget_job_statusget_job_historyset_job_publicget_frontend_configCode Quality Example (
api/mcp/tools.py):Observations:
π Security Analysis (8.5/10)
β Excellent Security Practices
1. CRITICAL: Weak Development Credentials in .env.example
Risk: Developers might copy these to production
Recommendation:
2. HIGH: TODO Comments Indicate Unfinished Security Work
Risk: Workers running as root in Kubernetes
Recommendation:
securityContextto K8s pod spec:3. MEDIUM: Missing Rate Limiting Documentation
Code mentions "daily limits" but no documentation on:
4. LOW: No Audit Logging
No evidence of audit trail for:
Recommendation: Add structured logging:
π Code Quality Analysis (7.5/10)
β Strengths
Ruff Linter Configured:
Type Safety - Python 3.11+ with type hints
Async/Await - Proper async patterns
Dependency Injection -
app_statepatternTest Coverage - 4 test files (unit + integration)
1. MEDIUM: Code Smells in Schemas
Found: Developer acknowledges bad design but hasn't fixed it
Recommendation: Investigate and refactor
job.pyschemas2. MEDIUM: Model Design Needs Revamp
Recommendation: Schedule database schema review
3. LOW: Inconsistent Error Messages
Some functions return:
Others:
Recommendation: Define custom exception hierarchy:
4. LOW: Missing Type Annotations in Some Functions
Recommendation: Define proper type:
π§ͺ Testing Analysis (7/10)
Current State
Test Files:
test_mcp_tools.py- MCP tool unit teststest_mcp_integration.py- Integration testsconftest.py- Pytest fixturesTest Framework: pytest + pytest-asyncio + pytest-cov
Observations:
Recommendations
Add Coverage Reporting:
Target: Achieve β₯80% coverage for:
api/mcp/tools.py(critical)api/util/zip_validate.py(security)api/util/aes_gcm.py(cryptography)Add Frontend Tests:
Add E2E Tests (Playwright recommended):
π Performance & Scalability (8/10)
β Strong Points
orjsonfor fast serialization1. PostgreSQL Single Point of Failure
Current: Single Postgres instance
Risk: Database downtime = entire system down
Recommendation:
2. No Caching Layer
Current: Every
get_job_statushits databaseRisk: Heavy polling can overwhelm DB
Recommendation:
3. Missing Metrics/Monitoring
Current: No Prometheus/Grafana integration
Risk: Can't detect performance degradation
Recommendation: Add metrics:
π Documentation Analysis (8/10)
β Strong Documentation
API Reference - No OpenAPI/Swagger docs exposed
/docsendpoint (FastAPI has built-in support)MCP Tool Schemas - Not documented for external consumers
Deployment Guide - No production deployment checklist
DEPLOYMENT.mdwith:Troubleshooting Guide - No common issues documented
π’ Production Readiness Checklist
π Priority Action Items
π΄ Critical (Fix Before Production)
.env.exampleπ‘ High Priority (Next Sprint)
api/schemas/job.pyandapi/models/job.pyπ’ Medium Priority (Backlog)
/docs)π‘ Architectural Recommendations
1. Add API Gateway
Benefits:
2. Implement Circuit Breakers
Prevents: Cascading failures when OpenAI API is down
3. Add Job Expiration
π Learning from This Codebase
What to Emulate β¨
loguruWhat to Avoidβ οΈ
app_state: objectshould be typedπ Final Verdict
Overall Score: 8/10 ββββββββββ
Strengths:
Weaknesses:
Recommendation: APPROVE with conditions
This is a high-quality codebase with solid fundamentals. Address the Critical items before production deployment. The architecture is sound and will scale well.
Estimated Effort to Production-Ready: 2-3 sprints (4-6 weeks)
π Comparison: evmBench vs mcp-server-tron
Verdict: Both projects are high quality. mcp-server-tron is more polished and production-ready, while evmBench-mcp-server has more ambitious architecture but needs more work on testing and monitoring.
π References