Skip to content

Commit 0367ab7

Browse files
authored
feat: [CG-10632] mcp server (#358)
# Motivation <!-- Why is this change necessary? --> [CG-10632 ](https://linear.app/codegen-sh/issue/CG-10632/cursor-mcp-codegen-integration)Provide a simple MCP server for AI Agents to start leveraging, to assist in generating and iterating on codemods. # Content This PR adds a simple MCP server as a starting point for users to add helpful codegen specific tools and resources to their AI Agents <!-- Please include a summary of the change --> # Testing <!-- How was the change tested? --> # Please check the following before marking your PR as ready for review - [ ] I have added tests for my changes - [ ] I have updated the documentation or added new documentation as needed --------- Co-authored-by: rushilpatel0 <[email protected]>
1 parent 5ca9798 commit 0367ab7

File tree

8 files changed

+10117
-1
lines changed

8 files changed

+10117
-1
lines changed

docs/introduction/ide-usage.mdx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,46 @@ Codegen creates a custom Python environment in `.codegen/.venv`. Configure your
5151
</AccordionGroup>
5252

5353

54+
## MCP Server Setup
55+
This is an optional step but highly recommended if your IDE supports MCP support and you use AI Agents.
56+
The MCP server is a local server that allows your AI Agent to interact with the Codegen specific tools,
57+
it will allow an agent to:
58+
- ask an expert to create a codemod
59+
- improve a codemod
60+
- get setup instructions
61+
62+
### Configuration
63+
#### Usage with Cline:
64+
Add this to your cline_mcp_settings.json:
65+
```
66+
{
67+
"mcpServers": {
68+
"codegen-cli": {
69+
"command": "uv",
70+
"args": [
71+
"--directory",
72+
"<path to codegen installation>/codegen-sdk/src/codegen/cli/mcp",
73+
"run",
74+
"server.py"
75+
]
76+
}
77+
}
78+
}
79+
```
80+
81+
82+
#### Usage with Cursor:
83+
Under the `Settings` > `Feature` > `MCP Servers` section, click "Add New MCP Server" and add the following:
84+
85+
```
86+
Name: codegen-mcp
87+
Type: Command
88+
Command: uv --directory <path to codegen installation>/codegen-sdk/src/codegen/cli/mcp run server.py
89+
```
90+
91+
92+
93+
5494
## Create a New Codemod
5595

5696
Generate the boilerplate for a new code manipulation program using [codegen create](/cli/create):

src/codegen/cli/api/client.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
DOCS_ENDPOINT,
1212
EXPERT_ENDPOINT,
1313
IDENTIFY_ENDPOINT,
14+
IMPROVE_ENDPOINT,
1415
LOOKUP_ENDPOINT,
1516
PR_LOOKUP_ENDPOINT,
1617
RUN_ENDPOINT,
@@ -27,6 +28,8 @@
2728
DocsInput,
2829
DocsResponse,
2930
IdentifyResponse,
31+
ImproveCodemodInput,
32+
ImproveCodemodResponse,
3033
LookupInput,
3134
LookupOutput,
3235
PRLookupInput,
@@ -42,6 +45,7 @@
4245
from codegen.cli.env.global_env import global_env
4346
from codegen.cli.errors import InvalidTokenError, ServerError
4447
from codegen.cli.utils.codemods import Codemod
48+
from codegen.cli.utils.constants import ProgrammingLanguage
4549
from codegen.cli.utils.function_finder import DecoratedFunction
4650

4751
InputT = TypeVar("InputT", bound=BaseModel)
@@ -55,7 +59,7 @@ class RestAPI:
5559

5660
auth_token: str | None = None
5761

58-
def __init__(self, auth_token: str):
62+
def __init__(self, auth_token: str | None = None):
5963
self.auth_token = auth_token
6064

6165
def _get_headers(self) -> dict[str, str]:
@@ -248,3 +252,12 @@ def lookup_pr(self, repo_full_name: str, github_pr_number: int) -> PRSchema:
248252
PRLookupInput(input=PRLookupInput.BasePRLookupInput(repo_full_name=repo_full_name, github_pr_number=github_pr_number)),
249253
PRLookupResponse,
250254
)
255+
256+
def improve_codemod(self, codemod: str, task: str, concerns: list[str], context: dict[str, str], language: ProgrammingLanguage) -> ImproveCodemodResponse:
257+
"""Improve a codemod."""
258+
return self._make_request(
259+
"GET",
260+
IMPROVE_ENDPOINT,
261+
ImproveCodemodInput(input=ImproveCodemodInput.BaseImproveCodemodInput(codemod=codemod, task=task, concerns=concerns, context=context, language=language)),
262+
ImproveCodemodResponse,
263+
)

src/codegen/cli/api/endpoints.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@
1010
RUN_ON_PR_ENDPOINT = f"https://{MODAL_PREFIX}--cli-run-on-pull-request.modal.run"
1111
PR_LOOKUP_ENDPOINT = f"https://{MODAL_PREFIX}--cli-pr-lookup.modal.run"
1212
CODEGEN_SYSTEM_PROMPT_URL = "https://gist.githubusercontent.com/jayhack/15681a2ceaccd726f19e6fdb3a44738b/raw/17c08054e3931b3b7fdf424458269c9e607541e8/codegen-system-prompt.txt"
13+
IMPROVE_ENDPOINT = f"https://{MODAL_PREFIX}--cli-improve.modal.run"

src/codegen/cli/api/schemas.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,3 +234,24 @@ class RunOnPRResponse(BaseModel):
234234
codemod_id: int = Field(..., description="ID of the codemod")
235235
codemod_run_id: int = Field(..., description="ID of the codemod run")
236236
web_url: str = Field(..., description="URL to view the test results")
237+
238+
239+
###########################################################################
240+
# IMPROVE
241+
###########################################################################
242+
243+
244+
class ImproveCodemodInput(BaseModel):
245+
class BaseImproveCodemodInput(BaseModel):
246+
codemod: str = Field(..., description="Source code of the codemod to improve")
247+
task: str = Field(..., description="Task to which the codemod should implement to solve")
248+
concerns: list[str] = Field(..., description="A list of issues that were discovered with the current codemod that need to be considered in the next iteration")
249+
context: dict[str, str] = Field(..., description="Additional context for the codemod this can be a list of files that are related, additional information about the task, etc.")
250+
language: ProgrammingLanguage = Field(..., description="Language of the codemod")
251+
252+
input: BaseImproveCodemodInput = Field(..., description="Input data for improvement")
253+
254+
255+
class ImproveCodemodResponse(BaseModel):
256+
success: bool = Field(..., description="Whether the improvement was successful")
257+
codemod_source: str = Field(..., description="Source code of the improved codemod")

src/codegen/cli/mcp/README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Codegen MCP server
2+
3+
A MCP server implementation that provides tools and resources for using and working with the Codegen CLI and SDK, enabling AI agents to iterate quickly on writing codemods with the codegen sdk.
4+
5+
### Dependencies
6+
7+
- [fastmcp](https://github.com/codegen-sh/fastmcp)
8+
9+
## Usage
10+
11+
Most AI Agents that support MCP will have some way to configure the server startup.
12+
13+
### Cline
14+
15+
Add this to your `cline_mcp_settings.json` file to get started:
16+
17+
```
18+
{
19+
"mcpServers": {
20+
"codegen-cli": {
21+
"command": "uv",
22+
"args": [
23+
"--directory",
24+
"<path to codegen installation>/codegen-sdk/src/codegen/cli/mcp",
25+
"run",
26+
"server.py"
27+
]
28+
}
29+
}
30+
}
31+
```
32+
33+
Cursor:
34+
Under the `Settings` > `Feature` > `MCP Servers` section, click "Add New MCP Server" and add the following:
35+
36+
```
37+
Name: codegen-mcp
38+
Type: Command
39+
Command: uv --directory <path to codegen installation>/codegen-sdk/src/codegen/cli/mcp run server.py
40+
```

0 commit comments

Comments
 (0)