AI-Python-Tutor / server.py
ABO4SAMRA's picture
Update server.py
decfd66 verified
raw
history blame
3.76 kB
import os
import sys
import subprocess
from mcp.server.fastmcp import FastMCP
# 1. Initialize with System Instructions
# These instructions tell the LLM *how* to use this server when it connects.
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.
"""
)
# --- 2. New Tool: Context Awareness ---
@mcp.tool()
def list_directory() -> str:
"""Lists all files in the current directory to understand the project structure."""
try:
files = os.listdir(".")
# Filter out hidden files/dirs to keep context clean
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)}"
# --- 3. Existing Tools (Enhanced) ---
@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:
# Check if file exists first to avoid confusing subprocess errors
if not os.path.exists(filename):
return f"❌ Cannot run '{filename}' because it does not exist. Write it first."
# Run with timeout to prevent infinite loops (common with students)
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)}"
# --- 4. New Resource: Static Knowledge ---
# The agent can "read" this resource URL to get its core curriculum
@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()