|
|
import os |
|
|
import sys |
|
|
import subprocess |
|
|
from mcp.server.fastmcp import FastMCP |
|
|
|
|
|
|
|
|
|
|
|
mcp = FastMCP( |
|
|
"VibeCodingTutor", |
|
|
instructions=""" |
|
|
This server provides file system access and code execution for a Python Tutor. |
|
|
- Always 'list_directory' first to understand the student's current workspace. |
|
|
- Use 'read_file' to diagnose errors in existing code. |
|
|
- Use 'run_python_script' to verify your examples work before showing them. |
|
|
""" |
|
|
) |
|
|
|
|
|
|
|
|
@mcp.tool() |
|
|
def list_directory() -> str: |
|
|
"""Lists all files in the current directory to understand the project structure.""" |
|
|
try: |
|
|
files = os.listdir(".") |
|
|
|
|
|
visible_files = [f for f in files if not f.startswith('.')] |
|
|
if not visible_files: |
|
|
return "The directory is empty." |
|
|
return "Current Project Files:\n- " + "\n- ".join(visible_files) |
|
|
except Exception as e: |
|
|
return f"Error listing directory: {str(e)}" |
|
|
|
|
|
|
|
|
@mcp.tool() |
|
|
def write_file(filename: str, content: str) -> str: |
|
|
"""Writes code or text to a file. Overwrites if exists.""" |
|
|
try: |
|
|
with open(filename, "w") as f: |
|
|
f.write(content) |
|
|
return f"β
Successfully wrote {len(content)} bytes to '{filename}'.\nYou can now run this file." |
|
|
except Exception as e: |
|
|
return f"β Error writing file: {str(e)}" |
|
|
|
|
|
@mcp.tool() |
|
|
def read_file(filename: str) -> str: |
|
|
"""Reads a file's content. Use this to debug code.""" |
|
|
try: |
|
|
if not os.path.exists(filename): |
|
|
return f"β File '{filename}' not found. Did you forget to write it first?" |
|
|
with open(filename, "r") as f: |
|
|
return f.read() |
|
|
except Exception as e: |
|
|
return f"Error reading file: {str(e)}" |
|
|
|
|
|
@mcp.tool() |
|
|
def run_python_script(filename: str) -> str: |
|
|
"""Runs a Python script and captures output/errors.""" |
|
|
try: |
|
|
|
|
|
if not os.path.exists(filename): |
|
|
return f"β Cannot run '{filename}' because it does not exist. Write it first." |
|
|
|
|
|
|
|
|
result = subprocess.run( |
|
|
[sys.executable, filename], |
|
|
capture_output=True, |
|
|
text=True, |
|
|
timeout=10 |
|
|
) |
|
|
|
|
|
output = "" |
|
|
if result.stdout: |
|
|
output += f"[STDOUT]\n{result.stdout}\n" |
|
|
if result.stderr: |
|
|
output += f"[STDERR]\n{result.stderr}\n" |
|
|
|
|
|
if not output: |
|
|
return "[Process finished with no output]" |
|
|
|
|
|
return output |
|
|
except subprocess.TimeoutExpired: |
|
|
return "β Error: Script execution timed out (limit: 10s). Check for infinite loops." |
|
|
except Exception as e: |
|
|
return f"Execution failed: {str(e)}" |
|
|
|
|
|
|
|
|
|
|
|
@mcp.resource("tutor://curriculum") |
|
|
def get_curriculum() -> str: |
|
|
"""Returns the standard teaching curriculum for this session.""" |
|
|
return """ |
|
|
# Python Vibe Coding Curriculum |
|
|
1. Basics: Variables, Loops, functions. |
|
|
2. Data: Lists, Dictionaries, Sets. |
|
|
3. Advanced: Decorators, Generators, Context Managers. |
|
|
4. Data Science: Pandas, Matplotlib. |
|
|
|
|
|
TEACHING STYLE: |
|
|
- Don't just explain. CODING IS DOING. |
|
|
- Always create a file, run it, and show the output. |
|
|
- If the user is wrong, be encouraging but precise. |
|
|
""" |
|
|
|
|
|
if __name__ == "__main__": |
|
|
mcp.run() |