Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>MCP EdTech Demo</title> | |
| <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet"> | |
| <style> | |
| body { | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| padding-top: 20px; | |
| background-color: #f8f9fa; | |
| } | |
| .navbar { | |
| background-color: #4a6fa5 ; | |
| box-shadow: 0 2px 4px rgba(0,0,0,0.1); | |
| } | |
| .navbar-brand { | |
| font-weight: bold; | |
| color: white ; | |
| } | |
| .nav-link { | |
| color: rgba(255,255,255,0.85) ; | |
| } | |
| .nav-link:hover { | |
| color: white ; | |
| } | |
| .card { | |
| border-radius: 10px; | |
| box-shadow: 0 4px 6px rgba(0,0,0,0.1); | |
| margin-bottom: 20px; | |
| transition: transform 0.3s; | |
| } | |
| .card:hover { | |
| transform: translateY(-5px); | |
| } | |
| .card-header { | |
| background-color: #4a6fa5; | |
| color: white; | |
| font-weight: bold; | |
| border-radius: 10px 10px 0 0 ; | |
| } | |
| .btn-primary { | |
| background-color: #4a6fa5; | |
| border-color: #4a6fa5; | |
| } | |
| .btn-primary:hover { | |
| background-color: #3a5a8f; | |
| border-color: #3a5a8f; | |
| } | |
| .api-url { | |
| font-family: monospace; | |
| background-color: #f1f1f1; | |
| padding: 5px; | |
| border-radius: 4px; | |
| } | |
| .response-area { | |
| background-color: #f8f9fa; | |
| border: 1px solid #dee2e6; | |
| border-radius: 5px; | |
| padding: 15px; | |
| max-height: 300px; | |
| overflow-y: auto; | |
| font-family: monospace; | |
| } | |
| .footer { | |
| margin-top: 50px; | |
| padding: 20px 0; | |
| background-color: #343a40; | |
| color: white; | |
| } | |
| #loading { | |
| display: none; | |
| } | |
| .spinner-border { | |
| width: 1rem; | |
| height: 1rem; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <nav class="navbar navbar-expand-lg navbar-dark bg-dark mb-4"> | |
| <div class="container"> | |
| <a class="navbar-brand" href="#">MCP EdTech</a> | |
| <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"> | |
| <span class="navbar-toggler-icon"></span> | |
| </button> | |
| <div class="collapse navbar-collapse" id="navbarNav"> | |
| <ul class="navbar-nav"> | |
| <li class="nav-item"> | |
| <a class="nav-link active" href="#home">Home</a> | |
| </li> | |
| <li class="nav-item"> | |
| <a class="nav-link" href="#api-demo">API Demo</a> | |
| </li> | |
| <li class="nav-item"> | |
| <a class="nav-link" href="#documentation">Documentation</a> | |
| </li> | |
| </ul> | |
| </div> | |
| </div> | |
| </nav> | |
| <div class="container" id="home"> | |
| <div class="row mb-4"> | |
| <div class="col-12"> | |
| <div class="card"> | |
| <div class="card-header"> | |
| Model Context Protocol (MCP) for EdTech | |
| </div> | |
| <div class="card-body"> | |
| <h5 class="card-title">Welcome to the MCP EdTech Demo</h5> | |
| <p class="card-text"> | |
| This demo showcases the Model Context Protocol (MCP) implementation for educational technology applications. | |
| MCP provides a standardized way for EdTech applications to interact with various AI models while maintaining | |
| context and state across interactions. | |
| </p> | |
| <p> | |
| Key features of this implementation: | |
| </p> | |
| <ul> | |
| <li>Context management for stateful conversations</li> | |
| <li>Student profile management</li> | |
| <li>Learning progress tracking</li> | |
| <li>Content adaptation based on student profiles</li> | |
| <li>Assessment and feedback systems</li> | |
| </ul> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="row mb-4" id="api-demo"> | |
| <div class="col-12"> | |
| <div class="card"> | |
| <div class="card-header"> | |
| API Demo | |
| </div> | |
| <div class="card-body"> | |
| <h5 class="card-title">Try the MCP API</h5> | |
| <div class="mb-4"> | |
| <h6>1. Create a Context</h6> | |
| <p>First, let's create a new context for our interaction:</p> | |
| <div class="mb-3"> | |
| <button id="createContextBtn" class="btn btn-primary">Create Context</button> | |
| <span id="loading-context" class="ms-2" style="display: none;"> | |
| <span class="spinner-border spinner-border-sm"></span> Processing... | |
| </span> | |
| </div> | |
| <div class="response-area" id="contextResponse"> | |
| <!-- Context response will appear here --> | |
| </div> | |
| </div> | |
| <div class="mb-4"> | |
| <h6>2. Process an Interaction</h6> | |
| <p>Now, let's process an interaction using the context we created:</p> | |
| <div class="mb-3"> | |
| <label for="interactionText" class="form-label">Enter your question or prompt:</label> | |
| <input type="text" class="form-control" id="interactionText" | |
| placeholder="e.g., Explain the concept of photosynthesis"> | |
| </div> | |
| <div class="mb-3"> | |
| <button id="interactBtn" class="btn btn-primary">Process Interaction</button> | |
| <span id="loading-interaction" class="ms-2" style="display: none;"> | |
| <span class="spinner-border spinner-border-sm"></span> Processing... | |
| </span> | |
| </div> | |
| <div class="response-area" id="interactionResponse"> | |
| <!-- Interaction response will appear here --> | |
| </div> | |
| </div> | |
| <div class="mb-4"> | |
| <h6>3. Create a Student Profile</h6> | |
| <p>Let's create a student profile:</p> | |
| <div class="mb-3"> | |
| <label for="studentName" class="form-label">Student Name:</label> | |
| <input type="text" class="form-control" id="studentName" placeholder="John Doe"> | |
| </div> | |
| <div class="mb-3"> | |
| <label for="educationalLevel" class="form-label">Educational Level:</label> | |
| <select class="form-select" id="educationalLevel"> | |
| <option value="elementary">Elementary</option> | |
| <option value="middle_school">Middle School</option> | |
| <option value="high_school">High School</option> | |
| <option value="undergraduate">Undergraduate</option> | |
| <option value="graduate">Graduate</option> | |
| <option value="professional">Professional</option> | |
| </select> | |
| </div> | |
| <div class="mb-3"> | |
| <button id="createStudentBtn" class="btn btn-primary">Create Student Profile</button> | |
| <span id="loading-student" class="ms-2" style="display: none;"> | |
| <span class="spinner-border spinner-border-sm"></span> Processing... | |
| </span> | |
| </div> | |
| <div class="response-area" id="studentResponse"> | |
| <!-- Student profile response will appear here --> | |
| </div> | |
| </div> | |
| <div class="mb-4"> | |
| <h6>4. Adapt Content for Student</h6> | |
| <p>Now, let's adapt some content for the student:</p> | |
| <div class="mb-3"> | |
| <label for="contentText" class="form-label">Content to adapt:</label> | |
| <textarea class="form-control" id="contentText" rows="3" | |
| placeholder="The process of photosynthesis involves the conversion of light energy into chemical energy that can be used by plants and other organisms."></textarea> | |
| </div> | |
| <div class="mb-3"> | |
| <button id="adaptContentBtn" class="btn btn-primary">Adapt Content</button> | |
| <span id="loading-content" class="ms-2" style="display: none;"> | |
| <span class="spinner-border spinner-border-sm"></span> Processing... | |
| </span> | |
| </div> | |
| <div class="response-area" id="contentResponse"> | |
| <!-- Content adaptation response will appear here --> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="row mb-4" id="documentation"> | |
| <div class="col-12"> | |
| <div class="card"> | |
| <div class="card-header"> | |
| API Documentation | |
| </div> | |
| <div class="card-body"> | |
| <h5 class="card-title">Available Endpoints</h5> | |
| <div class="mb-3"> | |
| <h6>Context Management</h6> | |
| <ul> | |
| <li><span class="api-url">POST /api/v1/context/create</span> - Create a new context</li> | |
| <li><span class="api-url">GET /api/v1/context/{context_id}</span> - Get context information</li> | |
| <li><span class="api-url">PUT /api/v1/context/{context_id}</span> - Update context</li> | |
| <li><span class="api-url">DELETE /api/v1/context/{context_id}</span> - Delete context</li> | |
| </ul> | |
| </div> | |
| <div class="mb-3"> | |
| <h6>Interaction</h6> | |
| <ul> | |
| <li><span class="api-url">POST /api/v1/interact</span> - Process an interaction</li> | |
| </ul> | |
| </div> | |
| <div class="mb-3"> | |
| <h6>Student Profiles</h6> | |
| <ul> | |
| <li><span class="api-url">POST /api/v1/students</span> - Create student profile</li> | |
| <li><span class="api-url">GET /api/v1/students/{student_id}</span> - Get student information</li> | |
| <li><span class="api-url">PUT /api/v1/students/{student_id}</span> - Update student information</li> | |
| </ul> | |
| </div> | |
| <div class="mb-3"> | |
| <h6>Progress Tracking</h6> | |
| <ul> | |
| <li><span class="api-url">GET /api/v1/students/{student_id}/progress</span> - Get learning progress</li> | |
| <li><span class="api-url">POST /api/v1/assessments</span> - Create assessment</li> | |
| <li><span class="api-url">GET /api/v1/students/{student_id}/assessments</span> - List student assessments</li> | |
| </ul> | |
| </div> | |
| <div class="mb-3"> | |
| <h6>Content Adaptation</h6> | |
| <ul> | |
| <li><span class="api-url">POST /api/v1/content/adapt</span> - Adapt content for a student</li> | |
| </ul> | |
| </div> | |
| <div class="mb-3"> | |
| <h6>Learning Paths</h6> | |
| <ul> | |
| <li><span class="api-url">GET /api/v1/learning-paths/{student_id}</span> - Get personalized learning path</li> | |
| </ul> | |
| </div> | |
| <div class="mb-3"> | |
| <h6>Models</h6> | |
| <ul> | |
| <li><span class="api-url">GET /api/v1/models</span> - List available models</li> | |
| <li><span class="api-url">GET /api/v1/models/{model_name}/capabilities</span> - Get model capabilities</li> | |
| </ul> | |
| </div> | |
| <p class="mt-4"> | |
| For complete API documentation, visit the <a href="/docs" target="_blank">Swagger UI</a> or | |
| <a href="/redoc" target="_blank">ReDoc</a> pages. | |
| </p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <footer class="footer"> | |
| <div class="container"> | |
| <div class="row"> | |
| <div class="col-md-6"> | |
| <h5>MCP EdTech Project</h5> | |
| <p>An open-source implementation of the Model Context Protocol for educational technology applications.</p> | |
| </div> | |
| <div class="col-md-6 text-md-end"> | |
| <p>© 2025 MCP EdTech Project</p> | |
| <p>Licensed under MIT License</p> | |
| </div> | |
| </div> | |
| </div> | |
| </footer> | |
| <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script> | |
| <script> | |
| // Store context and student IDs | |
| let currentContextId = null; | |
| let currentStudentId = null; | |
| // Function to format JSON responses | |
| function formatJSON(json) { | |
| return JSON.stringify(json, null, 2); | |
| } | |
| // Create Context | |
| document.getElementById('createContextBtn').addEventListener('click', async () => { | |
| const loadingElement = document.getElementById('loading-context'); | |
| loadingElement.style.display = 'inline'; | |
| try { | |
| const response = await fetch('/api/v1/context/create', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json' | |
| }, | |
| body: JSON.stringify({ | |
| metadata: { | |
| source: 'demo-ui', | |
| created_by: 'demo-user' | |
| } | |
| }) | |
| }); | |
| const data = await response.json(); | |
| currentContextId = data.context_id; | |
| document.getElementById('contextResponse').innerText = formatJSON(data); | |
| } catch (error) { | |
| document.getElementById('contextResponse').innerText = `Error: ${error.message}`; | |
| } finally { | |
| loadingElement.style.display = 'none'; | |
| } | |
| }); | |
| // Process Interaction | |
| document.getElementById('interactBtn').addEventListener('click', async () => { | |
| if (!currentContextId) { | |
| alert('Please create a context first!'); | |
| return; | |
| } | |
| const interactionText = document.getElementById('interactionText').value; | |
| if (!interactionText) { | |
| alert('Please enter a question or prompt!'); | |
| return; | |
| } | |
| const loadingElement = document.getElementById('loading-interaction'); | |
| loadingElement.style.display = 'inline'; | |
| try { | |
| const response = await fetch('/api/v1/interact', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json' | |
| }, | |
| body: JSON.stringify({ | |
| context_id: currentContextId, | |
| interaction_type: 'text', | |
| content: { | |
| text: interactionText | |
| }, | |
| format: 'text', | |
| model_name: 'mock' | |
| }) | |
| }); | |
| const data = await response.json(); | |
| document.getElementById('interactionResponse').innerText = formatJSON(data); | |
| } catch (error) { | |
| document.getElementById('interactionResponse').innerText = `Error: ${error.message}`; | |
| } finally { | |
| loadingElement.style.display = 'none'; | |
| } | |
| }); | |
| // Create Student Profile | |
| document.getElementById('createStudentBtn').addEventListener('click', async () => { | |
| const studentName = document.getElementById('studentName').value; | |
| if (!studentName) { | |
| alert('Please enter a student name!'); | |
| return; | |
| } | |
| const educationalLevel = document.getElementById('educationalLevel').value; | |
| const loadingElement = document.getElementById('loading-student'); | |
| loadingElement.style.display = 'inline'; | |
| try { | |
| const response = await fetch('/api/v1/students', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json' | |
| }, | |
| body: JSON.stringify({ | |
| name: studentName, | |
| educational_level: educationalLevel, | |
| learning_style: 'visual', | |
| interests: ['science', 'technology', 'art'], | |
| strengths: ['problem-solving', 'creativity'], | |
| areas_for_improvement: ['time-management'] | |
| }) | |
| }); | |
| const data = await response.json(); | |
| currentStudentId = data.id; | |
| document.getElementById('studentResponse').innerText = formatJSON(data); | |
| } catch (error) { | |
| document.getElementById('studentResponse').innerText = `Error: ${error.message}`; | |
| } finally { | |
| loadingElement.style.display = 'none'; | |
| } | |
| }); | |
| // Adapt Content | |
| document.getElementById('adaptContentBtn').addEventListener('click', async () => { | |
| if (!currentStudentId) { | |
| alert('Please create a student profile first!'); | |
| return; | |
| } | |
| const contentText = document.getElementById('contentText').value; | |
| if (!contentText) { | |
| alert('Please enter content to adapt!'); | |
| return; | |
| } | |
| const loadingElement = document.getElementById('loading-content'); | |
| loadingElement.style.display = 'inline'; | |
| try { | |
| const response = await fetch('/api/v1/content/adapt', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json' | |
| }, | |
| body: JSON.stringify({ | |
| content: { | |
| text: contentText | |
| }, | |
| student_id: currentStudentId, | |
| learning_objectives: ['obj-1', 'obj-2'], | |
| content_format: 'text' | |
| }) | |
| }); | |
| const data = await response.json(); | |
| document.getElementById('contentResponse').innerText = formatJSON(data); | |
| } catch (error) { | |
| document.getElementById('contentResponse').innerText = `Error: ${error.message}`; | |
| } finally { | |
| loadingElement.style.display = 'none'; | |
| } | |
| }); | |
| </script> | |
| </body> | |
| </html> | |