File size: 3,760 Bytes
decfd66 f4fced9 decfd66 f4fced9 decfd66 f4fced9 decfd66 f4fced9 decfd66 f4fced9 decfd66 f4fced9 decfd66 f4fced9 decfd66 f4fced9 decfd66 f4fced9 decfd66 f4fced9 decfd66 f4fced9 decfd66 f4fced9 decfd66 f4fced9 decfd66 f4fced9 decfd66 f4fced9 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
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() |