Skip to content

Commit cefaafb

Browse files
committed
fix: remove codebase reset call, and fix async bug
1 parent 61964af commit cefaafb

File tree

1 file changed

+30
-15
lines changed
  • codegen-examples/examples/codegen-mcp-server

1 file changed

+30
-15
lines changed

codegen-examples/examples/codegen-mcp-server/server.py

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import asyncio
22
from dataclasses import dataclass, field
3-
from typing import Annotated, Optional, Dict, Any, List
3+
import json
4+
from types import coroutine
5+
from typing import Annotated, Coroutine, Optional, Dict, Any, List
46
from mcp.server.fastmcp import FastMCP
57
from codegen import Codebase
68

@@ -11,14 +13,12 @@ class CodebaseState:
1113

1214
parse_task: Optional[asyncio.Future] = None
1315
parsed_codebase: Optional[Codebase] = None
14-
codebase_path: Optional[str] = None
1516
log_buffer: List[str] = field(default_factory=list)
1617

17-
async def parse(self, path: str) -> Codebase:
18+
def parse(self, path: str) -> Codebase:
1819
"""Parse the codebase at the given path."""
1920
codebase = Codebase(path)
2021
self.parsed_codebase = codebase
21-
self.codebase_path = path
2222
return codebase
2323

2424
def reset(self) -> None:
@@ -44,13 +44,27 @@ def capture_output(*args, **kwargs) -> None:
4444
for arg in args:
4545
state.log_buffer.append(str(arg))
4646

47+
def update_codebase(future: asyncio.Future):
48+
try:
49+
result = future.result()
50+
if result is not None:
51+
state.parsed_codebase = result
52+
else:
53+
state.parsed_codebase = None
54+
except Exception as e:
55+
pass
56+
57+
4758

4859
@mcp.tool(name="parse_codebase", description="Initiate codebase parsing")
4960
async def parse_codebase(codebase_path: Annotated[str, "path to the codebase to be parsed"]) -> Dict[str, str]:
5061
if not state.parse_task or state.parse_task.done():
5162
state.parse_task = asyncio.get_event_loop().run_in_executor(None, lambda: state.parse(codebase_path))
52-
return {"message": "Codebase parsing initiated, this may take some time depending on the size of the codebase. Use the `check_parsing_status` tool to check if the parse has completed."}
53-
return {"message": "Codebase is already being parsed."}
63+
state.parse_task.add_done_callback(update_codebase)
64+
return {
65+
"message": "Codebase parsing initiated, this may take some time depending on the size of the codebase. Use the `check_parsing_status` tool to check if the parse has completed."
66+
}
67+
return {"message": "Codebase is already being parsed.", "status": "error"}
5468

5569

5670
@mcp.tool(name="check_parse_status", description="Check if codebase parsing has completed")
@@ -69,17 +83,18 @@ async def execute_codemod(codemod: Annotated[str, "The python codemod code to ex
6983

7084
try:
7185
await state.parse_task
72-
# TODO: Implement proper sandboxing for code execution
73-
context = {
74-
"codebase": state.parsed_codebase,
75-
"print": capture_output,
76-
}
77-
exec(codemod, context)
86+
if (state.parsed_codebase is None):
87+
return {"error": "Codebase path is not set."}
88+
else:
89+
# TODO: Implement proper sandboxing for code execution
90+
context = {
91+
"codebase": state.parsed_codebase,
92+
"print": capture_output,
93+
}
94+
exec(codemod, context)
7895

7996
logs = "\n".join(state.log_buffer)
80-
81-
state.reset()
82-
return {"message": "Codemod executed and codebase reset.", "logs": logs}
97+
return {"message": "Codemod executed, view the logs for any output and your source code for any resulting updates.", "logs": logs}
8398
except Exception as e:
8499
return {"error": f"Error executing codemod: {str(e)}", "details": {"type": type(e).__name__, "message": str(e)}}
85100

0 commit comments

Comments
 (0)