Skip to content

Commit 3e217a1

Browse files
Merge pull request #1 from VishwasSomasekhariah/feature-add-ast-grep-tool
Feature add ast grep tool
2 parents afbf441 + 3520b89 commit 3e217a1

File tree

17 files changed

+1236
-2
lines changed

17 files changed

+1236
-2
lines changed

Dockerfile

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Use Python 3.12.8-slim as the base image
2+
FROM python:3.12.8-slim
3+
4+
# Set environment variables
5+
ENV PYTHONDONTWRITEBYTECODE=1 \
6+
PYTHONUNBUFFERED=1 \
7+
PIP_NO_CACHE_DIR=off \
8+
PIP_DISABLE_PIP_VERSION_CHECK=on \
9+
PROJECT_PATH="/project"
10+
11+
# Install system dependencies
12+
RUN apt-get update && apt-get install -y --no-install-recommends \
13+
curl \
14+
git \
15+
build-essential \
16+
&& curl -LO https://github.com/ast-grep/ast-grep/releases/latest/download/ast-grep-linux-x64.tar.gz \
17+
&& tar -xzf ast-grep-linux-x64.tar.gz \
18+
&& mv sg /usr/local/bin/ast-grep \
19+
&& chmod +x /usr/local/bin/ast-grep \
20+
&& rm ast-grep-linux-x64.tar.gz \
21+
&& apt-get clean \
22+
&& rm -rf /var/lib/apt/lists/*
23+
24+
# Create a directory for the project mount
25+
RUN mkdir -p /project
26+
27+
# Set working directory
28+
WORKDIR /app
29+
30+
# Clone the repository (replace with your actual repository URL)
31+
RUN git clone https://github.com/yourusername/code-analysis-mcp-server.git . \
32+
&& pip install --no-cache-dir -e .
33+
34+
# Expose the port for the MCP server
35+
EXPOSE 8000
36+
37+
# Create a volume for the project
38+
VOLUME ["/project"]
39+
40+
# Command to run the server
41+
ENTRYPOINT ["code-analysis-server"]

README.md

Lines changed: 192 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,192 @@
1-
# code-analysis-mcp-server
2-
MCP server for code analysis tools like ast-grep integration. Provides a standardized interface for AI assistants to perform structural code queries and transformations.
1+
# Code Analysis MCP Server
2+
A modular Model Context Protocol (MCP) server for code analysis tools, with a primary focus on ast-grep integration. This server provides a standardized interface for AI assistants and other clients to perform structural code queries and transformations.
3+
4+
## Features
5+
- **Structural Code Analysis**: Find patterns in code using ast-grep's powerful pattern matching capabilities
6+
7+
- **Code Transformations**: Replace patterns in code with new implementations
8+
9+
- **YAML Rule Support**: Apply custom lint and transformation rules defined in YAML
10+
11+
- **Project-Wide Scanning**: Scan entire projects for patterns or rule violations
12+
13+
- **Containerized Deployment**: Easy deployment with Docker
14+
15+
- **Modular Architecture**: Designed for easy extension with additional code analysis tools
16+
17+
## Requirements
18+
- Python 3.12.8
19+
20+
- ast-grep CLI tool
21+
22+
- Docker (for containerized deployment)
23+
24+
## Installation
25+
**Using pip**
26+
27+
```bash
28+
pip install code-analysis-mcp-server
29+
```
30+
31+
**From source**
32+
```bash
33+
git clone https://github.com/yourusername/code-analysis-mcp-server.git
34+
cd code-analysis-mcp-server
35+
pip install -e .
36+
```
37+
38+
**Using Docker**
39+
```bash
40+
docker pull yourusername/code-analysis-mcp-server
41+
# or build locally
42+
docker build -t code-analysis-mcp-server .
43+
```
44+
45+
## Usage
46+
### Starting the server
47+
```bash
48+
# Direct execution
49+
code-analysis-server
50+
51+
# With Docker
52+
docker run -p 8000:8000 -v /path/to/your/project:/project code-analysis-mcp-server
53+
```
54+
55+
### Using with Docker Compose
56+
**Create a docker-compose.yml file:**
57+
```text
58+
version: '3'
59+
60+
services:
61+
code-analysis-mcp:
62+
image: yourusername/code-analysis-mcp-server
63+
ports:
64+
- "8000:8000"
65+
volumes:
66+
- ${PROJECT_DIR:-./sample_project}:/project
67+
environment:
68+
- PROJECT_PATH=/project
69+
restart: unless-stopped
70+
```
71+
**Then run:**
72+
```bash
73+
PROJECT_DIR=/path/to/your/project docker-compose up -d
74+
```
75+
76+
**Client Example**
77+
```python
78+
import asyncio
79+
import json
80+
from fastmcp import Client
81+
from fastmcp.client.transports import SSETransport
82+
83+
async def main():
84+
async with Client(transport=SSETransport("http://localhost:8000/sse")) as client:
85+
# Set project path
86+
project_result = await client.call_tool(
87+
"ast_grep_set_project_path",
88+
{
89+
"project_path": "/project"
90+
}
91+
)
92+
93+
# Process the result correctly
94+
content_item = project_result[0]
95+
result_data = json.loads(content_item.text)
96+
print("Project path result:", result_data)
97+
98+
# Find patterns in a file
99+
find_result = await client.call_tool(
100+
"ast_grep_find_pattern",
101+
{
102+
"file_path": "src/example.cs",
103+
"pattern": "public class $NAME"
104+
}
105+
)
106+
107+
# Process results
108+
content_item = find_result[0]
109+
result_data = json.loads(content_item.text)
110+
print(f"Found {result_data.get('count', 0)} matches")
111+
112+
if __name__ == "__main__":
113+
asyncio.run(main())
114+
```
115+
116+
## Available Tools
117+
The server provides the following tools:
118+
### ast-grep
119+
- **ast_grep_set_project_path:** Set the project path for subsequent operations
120+
- **ast_grep_parse_code:** Parse code into an AST
121+
- **ast_grep_find_pattern:** Find patterns in code files
122+
- **ast_grep_replace_pattern:** Replace patterns in code files
123+
- **ast_grep_run_yaml_rule:** Run custom YAML rules on code files
124+
- **ast_grep_scan_project:** Scan entire projects for patterns or rule violations
125+
- **ast_grep_initialize_project:** Initialize a new ast-grep project
126+
- **ast_grep_test_rule:** Test ast-grep rules
127+
128+
## Supported Languages
129+
- Python
130+
- JavaScript
131+
- TypeScript
132+
- Rust
133+
- Go
134+
- Java
135+
- C
136+
- C++
137+
- C#
138+
139+
## Project Structure
140+
```text
141+
code-analysis-mcp-server/
142+
├── src/
143+
│ ├── __init__.py
144+
│ ├── server.py # Main MCP server setup
145+
│ ├── tools/
146+
│ │ ├── __init__.py # Tool registration
147+
│ │ ├── ast_grep/
148+
│ │ │ ├── __init__.py
149+
│ │ │ ├── tools.py # ast-grep tool implementations
150+
│ │ └── common/
151+
│ │ ├── __init__.py
152+
│ │ └── utils.py # Shared utilities
153+
│ └── resources/
154+
│ ├── __init__.py
155+
│ └── status.py # System status resource
156+
├── tests/
157+
├── pyproject.toml
158+
├── setup.py
159+
├── requirements.txt
160+
├── Dockerfile
161+
└── README.md
162+
```
163+
164+
## Contributing
165+
Contributions are welcome! Please feel free to submit a Pull Request.
166+
167+
## License
168+
This project is licensed under the MIT License - see the LICENSE file for details.
169+
170+
```text
171+
MIT License
172+
173+
Copyright (c) 2025 Your Name
174+
175+
Permission is hereby granted, free of charge, to any person obtaining a copy
176+
of this software and associated documentation files (the "Software"), to deal
177+
in the Software without restriction, including without limitation the rights
178+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
179+
copies of the Software, and to permit persons to whom the Software is
180+
furnished to do so, subject to the following conditions:
181+
182+
The above copyright notice and this permission notice shall be included in all
183+
copies or substantial portions of the Software.
184+
185+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
186+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
187+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
188+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
189+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
190+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
191+
SOFTWARE.
192+
```

docker-compose.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
version: '3'
2+
3+
services:
4+
code-analysis-mcp:
5+
build:
6+
context: .
7+
dockerfile: Dockerfile
8+
ports:
9+
- "8000:8000"
10+
volumes:
11+
- ${PROJECT_DIR:-./sample_project}:/project
12+
environment:
13+
- PROJECT_PATH=/project
14+
restart: unless-stopped

pyproject.toml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
[build-system]
2+
requires = ["setuptools>=61.0"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "code-analysis-mcp-server"
7+
version = "0.1.0"
8+
description = "MCP Server for Code Analysis Tools"
9+
readme = "README.md"
10+
requires-python = ">=3.12.8,<3.13"
11+
license = {text = "MIT"}
12+
authors = [
13+
{name = "Your Name", email = "[email protected]"}
14+
]
15+
dependencies = [
16+
"pip==25.0.1",
17+
"uvicorn==0.34.1",
18+
"starlette==0.46.2",
19+
"PyYAML==6.0.2",
20+
"ast-grep-py==0.37.0",
21+
"fastmcp==2.1.2",
22+
]
23+
24+
[project.scripts]
25+
code-analysis-server = "src.server:main"
26+
27+
[tool.setuptools.packages.find]
28+
where = ["."]
29+
include = ["src*"]

requirements.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
fastmcp==2.1.2
2+
PyYAML==6.0.2
3+
uvicorn==0.34.1
4+
starlette==0.46.2
5+
pytest==7.4.0
6+
pytest-asyncio==0.21.1

setup.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from setuptools import setup
2+
3+
setup()

src/__init__.py

Whitespace-only changes.

src/resources/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
"""Resource implementations for the MCP server."""
2+
3+
# This file makes the resources directory a proper Python package.
4+
# It can be used to export specific resources if needed.

src/resources/status.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
"""System status resource for the MCP server."""
2+
3+
from typing import Dict, Any
4+
5+
def register_status_resource(mcp):
6+
"""Register the system status resource with the MCP server."""
7+
8+
@mcp.resource("system://status")
9+
async def get_system_status() -> Dict[str, Any]:
10+
"""
11+
Provide system status information about the Code Analysis MCP server.
12+
13+
Returns:
14+
Status information including version details
15+
"""
16+
try:
17+
import ast_grep_py
18+
import fastmcp
19+
20+
# Get version information
21+
ast_grep_version = getattr(ast_grep_py, "__version__", "unknown")
22+
fastmcp_version = getattr(fastmcp, "__version__", "unknown")
23+
24+
# Get available tools
25+
available_tools = {
26+
"ast_grep": [
27+
"ast_grep_parse_code",
28+
"ast_grep_find_pattern",
29+
"ast_grep_replace_pattern",
30+
"ast_grep_run_yaml_rule"
31+
]
32+
# Future tools will be added here
33+
}
34+
35+
return {
36+
"status": "operational",
37+
"ast_grep_py_version": ast_grep_version,
38+
"fastmcp_version": fastmcp_version,
39+
"supported_languages": [
40+
"python", "javascript", "typescript", "rust",
41+
"go", "java", "c", "cpp", "csharp"
42+
],
43+
"available_tools": available_tools
44+
}
45+
except Exception as exc:
46+
return {
47+
"status": "degraded",
48+
"error": str(exc)
49+
}

src/server.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/usr/bin/env python3
2+
"""
3+
MCP Server for Code Analysis Tools using Anthropic's fastmcp Framework
4+
"""
5+
6+
import importlib
7+
import os
8+
from fastmcp import FastMCP
9+
from starlette.applications import Starlette
10+
from starlette.routing import Mount
11+
import uvicorn
12+
13+
# Create the MCP server instance
14+
mcp = FastMCP("Code Analysis Tools")
15+
16+
# Import and register resources
17+
from src.resources.status import register_status_resource
18+
register_status_resource(mcp)
19+
20+
# Import and register tools
21+
from src.tools import register_all_tools
22+
register_all_tools(mcp)
23+
24+
# Create a Starlette application with the SSE endpoint
25+
app = Starlette(routes=[
26+
# Mount the SSE app at the root
27+
Mount("/", app=mcp.sse_app()),
28+
])
29+
30+
def main():
31+
"""Run the MCP server."""
32+
print("Starting Code Analysis MCP server...")
33+
uvicorn.run(app, host="0.0.0.0", port=8000)
34+
35+
if __name__ == "__main__":
36+
main()

0 commit comments

Comments
 (0)