Skip to main content
Glama

JSON Schema Validator MCP Server

by EienWolf
  • Apple
  • Linux
client_example.html45.5 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>JSON Schema Validator SSE Client</title> <style> body { font-family: Arial, sans-serif; max-width: 1200px; margin: 0 auto; padding: 20px; background-color: #f5f5f5; } .container { background: white; padding: 30px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); } .section { margin-bottom: 30px; padding: 20px; border: 1px solid #ddd; border-radius: 5px; } .section h2 { margin-top: 0; color: #333; } textarea { width: 100%; height: 150px; padding: 10px; border: 1px solid #ddd; border-radius: 4px; font-family: monospace; font-size: 14px; resize: vertical; } input[type="text"] { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 4px; margin-bottom: 10px; } button { background-color: #007bff; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; margin-right: 10px; margin-bottom: 10px; } button:hover { background-color: #0056b3; } button:disabled { background-color: #6c757d; cursor: not-allowed; } .progress-bar { width: 100%; height: 20px; background-color: #e9ecef; border-radius: 10px; overflow: hidden; margin: 10px 0; } .progress-fill { height: 100%; background-color: #28a745; width: 0%; transition: width 0.3s ease; } .log { background-color: #f8f9fa; border: 1px solid #dee2e6; border-radius: 4px; padding: 15px; height: 200px; overflow-y: auto; font-family: monospace; font-size: 12px; white-space: pre-wrap; } .status { padding: 10px; border-radius: 4px; margin: 10px 0; } .status.success { background-color: #d4edda; border: 1px solid #c3e6cb; color: #155724; } .status.error { background-color: #f8d7da; border: 1px solid #f5c6cb; color: #721c24; } .status.info { background-color: #d1ecf1; border: 1px solid #bee5eb; color: #0c5460; } .checkbox-container { margin: 10px 0; } .checkbox-container input[type="checkbox"] { margin-right: 8px; } </style> </head> <body> <div class="container"> <h1>JSON Schema Validator SSE Client</h1> <p>Example client to demonstrate Server-Sent Events with real-time JSON Schema validation.</p> <!-- Section 1: Direct Validation --> <div class="section"> <h2>🔍 Direct Validation (Streaming)</h2> <label for="jsonData">JSON Data:</label> <textarea id="jsonData" placeholder='{"name": "John", "age": 30}'>{ "name": "John", "age": 30, "email": "john@email.com" }</textarea> <label for="jsonSchema">JSON Schema:</label> <textarea id="jsonSchema" placeholder='{"type": "object", "properties": {...}}'>{ "type": "object", "properties": { "name": { "type": "string", "minLength": 1 }, "age": { "type": "integer", "minimum": 0, "maximum": 150 }, "email": { "type": "string", "format": "email" } }, "required": ["name", "age"] }</textarea> <div class="checkbox-container"> <input type="checkbox" id="strictValidation" checked> <label for="strictValidation">Strict validation</label> </div> <button onclick="validateDirect()">Validate with SSE</button> <button onclick="validateDirectImmediate()">Validate Immediate</button> <div class="progress-bar"> <div class="progress-fill" id="progress1"></div> </div> <div id="status1" class="status" style="display: none;"></div> </div> <!-- Section 2: Validation from Collection --> <div class="section"> <h2>📚 Validation from Collection</h2> <label for="jsonDataCollection">JSON Data:</label> <textarea id="jsonDataCollection" placeholder='{"user_id": 123, "username": "john_doe"}'>{ "user_id": 123, "username": "john_doe", "email": "john@example.com", "created_at": "2024-01-15T10:30:00Z" }</textarea> <label for="schemaId">Schema ID (must exist in .schemas collection):</label> <input type="text" id="schemaId" placeholder="user/profile.json" value="user.json"> <div class="checkbox-container"> <input type="checkbox" id="strictValidationCollection" checked> <label for="strictValidationCollection">Strict validation</label> </div> <button onclick="validateFromCollection()">Validate from Collection (SSE)</button> <button onclick="validateFromCollectionImmediate()">Validate Immediate</button> <div class="progress-bar"> <div class="progress-fill" id="progress2"></div> </div> <div id="status2" class="status" style="display: none;"></div> </div> <!-- Section 3: Add Schema --> <div class="section"> <h2>➕ Add/Update Schema</h2> <label for="newSchemaId">Schema ID:</label> <input type="text" id="newSchemaId" placeholder="user/profile.json" value="example_user.json"> <label for="newSchemaContent">Schema Content:</label> <textarea id="newSchemaContent" placeholder='{"type": "object", ...}'>{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "title": "User Profile Schema", "description": "Schema for user profile validation", "properties": { "user_id": { "type": "integer", "minimum": 1 }, "username": { "type": "string", "pattern": "^[a-zA-Z0-9_]{3,20}$" }, "email": { "type": "string", "format": "email" }, "created_at": { "type": "string", "format": "date-time" } }, "required": ["user_id", "username", "email"] }</textarea> <div class="checkbox-container"> <input type="checkbox" id="updateIfExists"> <label for="updateIfExists">Update if already exists</label> </div> <button onclick="addSchema()">Add Schema (SSE)</button> <button onclick="addSchemaImmediate()">Add Immediate</button> <div class="progress-bar"> <div class="progress-fill" id="progress3"></div> </div> <div id="status3" class="status" style="display: none;"></div> </div> <!-- Section 4: List Schemas --> <div class="section"> <h2>📋 List Available Schemas</h2> <button onclick="listSchemas()">List Schemas (SSE)</button> <button onclick="listSchemasImmediate()">List Immediate</button> <div class="progress-bar"> <div class="progress-fill" id="progress4"></div> </div> <div id="status4" class="status" style="display: none;"></div> <label for="schemaList">Available Schemas:</label> <textarea id="schemaList" readonly placeholder="The schema list will appear here..."></textarea> </div> <!-- Section 5: Generate Schema from JSON --> <div class="section"> <h2>🎯 Generate Schema from JSON</h2> <label for="generateSchemaId">Schema ID to generate:</label> <input type="text" id="generateSchemaId" placeholder="generated_schema.json" value="generated_user.json"> <label for="generateJsonData">Sample JSON data:</label> <textarea id="generateJsonData" placeholder='{"name": "John Doe", "age": 30, "email": "john@example.com", "active": true}'>{"name": "John Doe", "age": 30, "email": "john@example.com", "active": true, "address": {"street": "123 Main St", "city": "New York", "zip": null}}</textarea> <label for="nullHandling">Null value handling:</label> <select id="nullHandling" style="width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 4px;"> <option value="allow">Allow - Allows null values</option> <option value="ignore">Ignore - Ignores fields with null</option> <option value="strict">Strict - Treats nulls as strings</option> </select> <br><br> <button onclick="generateSchema()">Generate Schema (SSE)</button> <button onclick="generateSchemaImmediate()">Generate Immediate</button> <div class="progress-bar"> <div class="progress-fill" id="progress5"></div> </div> <div id="status5" class="status" style="display: none;"></div> <label for="generatedSchema">Generated Schema:</label> <textarea id="generatedSchema" readonly placeholder="The generated schema will appear here..."></textarea> </div> <!-- Section 6: Get Schema --> <div class="section"> <h2>📖 Get Schema</h2> <label for="getSchemaId">Schema ID to retrieve:</label> <input type="text" id="getSchemaId" placeholder="user/profile.json" value="example_user.json"> <button onclick="getSchema()">Get Schema (SSE)</button> <button onclick="getSchemaImmediate()">Get Immediate</button> <div class="progress-bar"> <div class="progress-fill" id="progress6"></div> </div> <div id="status6" class="status" style="display: none;"></div> <label for="schemaOutput">Schema Content:</label> <textarea id="schemaOutput" readonly placeholder="The schema content will appear here..."></textarea> </div> <!-- Section 7: Delete Schema --> <div class="section"> <h2>🗑️ Delete Schema</h2> <label for="deleteSchemaId">Schema ID to delete:</label> <input type="text" id="deleteSchemaId" placeholder="user/profile.json" value="example_user.json"> <div class="checkbox-container"> <input type="checkbox" id="confirmDeletion"> <label for="confirmDeletion">I confirm that I want to delete this schema (irreversible)</label> </div> <button onclick="deleteSchema()">Delete Schema (SSE)</button> <button onclick="deleteSchemaImmediate()">Delete Immediate</button> <div class="progress-bar"> <div class="progress-fill" id="progress7"></div> </div> <div id="status7" class="status" style="display: none;"></div> </div> <!-- Section 8: Validator Information --> <div class="section"> <h2>ℹ️ Validator Information</h2> <p>Get information about the JSON Schema validation server capabilities.</p> <button onclick="getValidationInfo()">Get Information</button> <div class="progress-bar"> <div class="progress-fill" id="progress8"></div> </div> <div id="status8" class="status" style="display: none;"></div> <label for="validatorInfo">Validator Information:</label> <textarea id="validatorInfo" readonly placeholder="The validator information will appear here..."></textarea> </div> <!-- Event Log --> <div class="section"> <h2>📋 SSE Event Log</h2> <button onclick="clearLog()">Clear Log</button> <div id="eventLog" class="log"></div> </div> </div> <script> const SERVER_URL = 'http://localhost:8000'; let eventSource = null; function log(message, type = 'info') { const logElement = document.getElementById('eventLog'); const timestamp = new Date().toLocaleTimeString(); const logEntry = `[${timestamp}] ${type.toUpperCase()}: ${message}\n`; logElement.textContent += logEntry; logElement.scrollTop = logElement.scrollHeight; } function clearLog() { document.getElementById('eventLog').textContent = ''; } function updateProgress(progressId, percentage) { document.getElementById(progressId).style.width = percentage + '%'; } function showStatus(statusId, message, type) { const statusElement = document.getElementById(statusId); statusElement.textContent = message; statusElement.className = `status ${type}`; statusElement.style.display = 'block'; } function hideStatus(statusId) { document.getElementById(statusId).style.display = 'none'; } function setupSSEConnection(endpoint, data, progressId, statusId, method = 'POST') { // Close previous connection if it exists if (eventSource) { eventSource.close(); } // Reset progress updateProgress(progressId, 0); hideStatus(statusId); // Send data via POST and get streaming response fetch(`${SERVER_URL}${endpoint}`, { method: method, headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(data) }) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const reader = response.body.getReader(); const decoder = new TextDecoder(); function readStream() { reader.read().then(({ done, value }) => { if (done) { log('Stream completed'); return; } const chunk = decoder.decode(value); const lines = chunk.split('\n'); let currentEvent = {}; for (const line of lines) { if (line.startsWith('event:')) { currentEvent.type = line.substring(6).trim(); } else if (line.startsWith('data:')) { try { currentEvent.data = JSON.parse(line.substring(5).trim()); } catch (e) { log(`Error parsing SSE data: ${e.message}`, 'error'); } } else if (line.trim() === '' && currentEvent.type && currentEvent.data) { // Process complete event handleSSEEvent(currentEvent, progressId, statusId); currentEvent = {}; } } readStream(); }); } readStream(); }) .catch(error => { log(`SSE connection error: ${error.message}`, 'error'); showStatus(statusId, `Error: ${error.message}`, 'error'); }); } function handleSSEEvent(event, progressId, statusId) { const { type, data } = event; log(`Evento ${type}: ${data.message} (${data.progress}%)`, type); updateProgress(progressId, data.progress); switch (type) { case 'start': showStatus(statusId, data.message, 'info'); break; case 'progress': showStatus(statusId, data.message, 'info'); break; case 'complete': if (data.valid !== undefined) { const status = data.valid ? 'success' : 'error'; const message = data.valid ? `✅ Validation successful` : `❌ Validation failed: ${data.error_count} errors`; showStatus(statusId, message, status); if (!data.valid) { log(`Errors found: ${JSON.stringify(data.errors, null, 2)}`, 'error'); } } else if (data.deleted_from_database !== undefined || data.deleted_from_file !== undefined) { // Special handling for schema deletion showStatus(statusId, '✅ Schema deleted successfully', 'success'); log(`Schema deleted: ${JSON.stringify(data.schema_info, null, 2)}`, 'info'); // Clear fields after successful deletion if (statusId === 'status7') { document.getElementById('deleteSchemaId').value = ''; document.getElementById('confirmDeletion').checked = false; } } else if (data.schema_content !== undefined && data.schema_json !== undefined) { // Special handling for schema retrieval showStatus(statusId, '✅ Schema retrieved successfully', 'success'); log(`Schema retrieved: ${data.schema_id}`, 'info'); // Show schema content in textarea if status6 (get schema) if (statusId === 'status6') { document.getElementById('schemaOutput').value = data.schema_json; } } else if (data.schema_ids !== undefined && data.count !== undefined) { // Special handling for schema listing showStatus(statusId, `✅ List retrieved: ${data.count} schemas found`, 'success'); log(`Schemas found: ${data.count}`, 'info'); // Show schema list in textarea if status4 (list schemas) if (statusId === 'status4') { let listText = `Source: ${data.source}\nTotal schemas: ${data.count}\n\n`; if (data.count === 0) { listText += data.message || "No schemas available"; } else { listText += "Available schemas:\n"; data.schema_ids.forEach((schema_id, index) => { listText += `${index + 1}. ${schema_id}\n`; }); } document.getElementById('schemaList').value = listText; } } else if (data.generated_schema !== undefined && data.schema_info !== undefined) { // Special handling for schema generation showStatus(statusId, '✅ Schema generated and saved successfully', 'success'); log(`Schema generated: ${data.schema_id}`, 'info'); // Show generated schema info if status5 (generate schema) if (statusId === 'status5') { const schemaInfo = data.schema_info || {}; const summary = `🎯 Schema generated successfully: - ID: ${data.schema_id} - Título: ${schemaInfo.title || 'N/A'} - Tipo: ${schemaInfo.type || 'N/A'} - Propiedades: ${schemaInfo.property_count || 0} - Required fields: ${schemaInfo.required_count || 0} - Manejo de nulls: ${data.null_handling} 📋 Use 'Get Schema' with ID '${data.schema_id}' to view the complete schema.`; document.getElementById('generatedSchema').value = summary; // Clear inputs after success document.getElementById('generateSchemaId').value = ''; document.getElementById('generateJsonData').value = ''; } } else { showStatus(statusId, '✅ Operation completed successfully', 'success'); } break; case 'error': showStatus(statusId, `❌ Error: ${data.message}`, 'error'); if (data.error) { log(`Error details: ${JSON.stringify(data, null, 2)}`, 'error'); } break; } } function validateDirect() { try { const jsonData = JSON.parse(document.getElementById('jsonData').value); const schema = JSON.parse(document.getElementById('jsonSchema').value); const strict = document.getElementById('strictValidation').checked; const data = { json_data: jsonData, schema: schema, strict: strict }; log('Starting direct validation with SSE'); setupSSEConnection('/validate/stream', data, 'progress1', 'status1'); } catch (e) { log(`Error parsing JSON: ${e.message}`, 'error'); showStatus('status1', `JSON Error: ${e.message}`, 'error'); } } function validateDirectImmediate() { try { const jsonData = JSON.parse(document.getElementById('jsonData').value); const schema = JSON.parse(document.getElementById('jsonSchema').value); const strict = document.getElementById('strictValidation').checked; const data = { json_data: jsonData, schema: schema, strict: strict }; log('Starting immediate direct validation'); fetch(`${SERVER_URL}/validate`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }) .then(response => response.json()) .then(result => { log(`Immediate result: ${JSON.stringify(result, null, 2)}`); const status = result.valid ? 'success' : 'error'; const message = result.valid ? '✅ Validation successful (immediate)' : `❌ Validation failed: ${result.error_count} errors`; showStatus('status1', message, status); updateProgress('progress1', 100); }) .catch(error => { log(`Error: ${error.message}`, 'error'); showStatus('status1', `Error: ${error.message}`, 'error'); }); } catch (e) { log(`Error parsing JSON: ${e.message}`, 'error'); showStatus('status1', `JSON Error: ${e.message}`, 'error'); } } function validateFromCollection() { try { const jsonData = JSON.parse(document.getElementById('jsonDataCollection').value); const schemaId = document.getElementById('schemaId').value; const strict = document.getElementById('strictValidationCollection').checked; const data = { json_data: jsonData, schema_id: schemaId, strict: strict }; log('Starting validation from collection with SSE'); setupSSEConnection('/validate/collection/stream', data, 'progress2', 'status2'); } catch (e) { log(`Error parsing JSON: ${e.message}`, 'error'); showStatus('status2', `JSON Error: ${e.message}`, 'error'); } } function validateFromCollectionImmediate() { try { const jsonData = JSON.parse(document.getElementById('jsonDataCollection').value); const schemaId = document.getElementById('schemaId').value; const strict = document.getElementById('strictValidationCollection').checked; const data = { json_data: jsonData, schema_id: schemaId, strict: strict }; log('Starting immediate validation from collection'); fetch(`${SERVER_URL}/validate/collection`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }) .then(response => response.json()) .then(result => { log(`Immediate result: ${JSON.stringify(result, null, 2)}`); const status = result.valid ? 'success' : 'error'; const message = result.valid ? '✅ Validation successful (immediate)' : `❌ Validation failed: ${result.error_count} errors`; showStatus('status2', message, status); updateProgress('progress2', 100); }) .catch(error => { log(`Error: ${error.message}`, 'error'); showStatus('status2', `Error: ${error.message}`, 'error'); }); } catch (e) { log(`Error parsing JSON: ${e.message}`, 'error'); showStatus('status2', `JSON Error: ${e.message}`, 'error'); } } function addSchema() { const schemaId = document.getElementById('newSchemaId').value; const schemaContent = document.getElementById('newSchemaContent').value; const updateIfExists = document.getElementById('updateIfExists').checked; if (!schemaId || !schemaContent) { showStatus('status3', 'Error: Schema ID and content are required', 'error'); return; } const data = { schema_id: schemaId, schema_content: schemaContent, update_if_exists: updateIfExists }; log('Starting schema addition with SSE'); setupSSEConnection('/schema/add/stream', data, 'progress3', 'status3'); } function addSchemaImmediate() { const schemaId = document.getElementById('newSchemaId').value; const schemaContent = document.getElementById('newSchemaContent').value; const updateIfExists = document.getElementById('updateIfExists').checked; if (!schemaId || !schemaContent) { showStatus('status3', 'Error: Schema ID and content are required', 'error'); return; } const data = { schema_id: schemaId, schema_content: schemaContent, update_if_exists: updateIfExists }; fetch(`${SERVER_URL}/schema/add`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }) .then(response => { if (!response.ok) { return response.json().then(err => Promise.reject(err)); } return response.json(); }) .then(result => { log(`Immediate result: ${JSON.stringify(result, null, 2)}`); showStatus('status3', `✅ Schema saved successfully: ${data.schema_id}`, 'success'); updateProgress('progress3', 100); }) .catch(error => { log(`Error: ${error.detail || error.message}`, 'error'); showStatus('status3', `Error: ${error.detail || error.message}`, 'error'); }); } function listSchemas() { log('Starting schema listing with SSE'); setupSSEConnection('/schema/list/stream', {}, 'progress4', 'status4'); } function listSchemasImmediate() { log('Starting immediate schema listing'); fetch(`${SERVER_URL}/schema/list`, { method: 'GET', headers: { 'Content-Type': 'application/json' } }) .then(response => { if (!response.ok) { return response.json().then(err => Promise.reject(err)); } return response.json(); }) .then(result => { log(`Immediate result: ${JSON.stringify(result, null, 2)}`); if (result.success) { showStatus('status4', `✅ List retrieved: ${result.count} schemas found (immediate)`, 'success'); updateProgress('progress4', 100); // Show schema list in textarea let listText = `Source: ${result.source}\nTotal schemas: ${result.count}\n\n`; if (result.count === 0) { listText += result.message || "No schemas available"; } else { listText += "Available schemas:\n"; result.schema_ids.forEach((schema_id, index) => { listText += `${index + 1}. ${schema_id}\n`; }); } document.getElementById('schemaList').value = listText; } else { showStatus('status4', `❌ Error: ${result.error}`, 'error'); document.getElementById('schemaList').value = `Error: ${result.error}`; } }) .catch(error => { log(`Error: ${error.detail || error.message}`, 'error'); showStatus('status4', `Error: ${error.detail || error.message}`, 'error'); document.getElementById('schemaList').value = ''; }); } function getSchema() { const schemaId = document.getElementById('getSchemaId').value; if (!schemaId) { showStatus('status5', 'Error: Schema ID es requerido', 'error'); return; } const data = { schema_id: schemaId }; log('Starting schema retrieval with SSE'); setupSSEConnection('/schema/get/stream', data, 'progress5', 'status5'); } function getSchema() { const schemaId = document.getElementById('getSchemaId').value; if (!schemaId) { showStatus('status6', 'Error: Schema ID es requerido', 'error'); return; } const data = { schema_id: schemaId }; log('Starting schema retrieval with SSE'); setupSSEConnection('/schema/get/stream', data, 'progress6', 'status6'); } function getSchemaImmediate() { const schemaId = document.getElementById('getSchemaId').value; if (!schemaId) { showStatus('status6', 'Error: Schema ID es requerido', 'error'); return; } log('Starting immediate schema retrieval'); fetch(`${SERVER_URL}/schema/get?schema_id=${encodeURIComponent(schemaId)}`, { method: 'GET', headers: { 'Content-Type': 'application/json' } }) .then(response => { if (!response.ok) { return response.json().then(err => Promise.reject(err)); } return response.json(); }) .then(result => { log(`Immediate result: ${JSON.stringify(result, null, 2)}`); showStatus('status6', '✅ Schema retrieved successfully (immediate)', 'success'); updateProgress('progress6', 100); // Show schema content in textarea document.getElementById('schemaOutput').value = result.schema_content; // Clear input after success document.getElementById('getSchemaId').value = ''; }) .catch(error => { log(`Error: ${error.detail || error.message}`, 'error'); showStatus('status6', `Error: ${error.detail || error.message}`, 'error'); }); } function deleteSchema() { const schemaId = document.getElementById('deleteSchemaId').value; const confirmDeletion = document.getElementById('confirmDeletion').checked; if (!schemaId) { showStatus('status7', 'Error: Schema ID es requerido', 'error'); return; } if (!confirmDeletion) { showStatus('status7', 'Error: You must confirm deletion by checking the checkbox', 'error'); return; } const data = { schema_id: schemaId, confirm_deletion: confirmDeletion }; log('Starting schema deletion with SSE'); setupSSEConnection('/schema/delete/stream', data, 'progress7', 'status7', 'DELETE'); } function deleteSchemaImmediate() { const schemaId = document.getElementById('deleteSchemaId').value; const confirmDeletion = document.getElementById('confirmDeletion').checked; if (!schemaId) { showStatus('status7', 'Error: Schema ID es requerido', 'error'); return; } if (!confirmDeletion) { showStatus('status7', 'Error: You must confirm deletion by checking the checkbox', 'error'); return; } const data = { schema_id: schemaId, confirm_deletion: confirmDeletion }; log('Starting immediate schema deletion'); fetch(`${SERVER_URL}/schema/delete`, { method: 'DELETE', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }) .then(response => { if (!response.ok) { return response.json().then(err => Promise.reject(err)); } return response.json(); }) .then(result => { log(`Immediate result: ${JSON.stringify(result, null, 2)}`); showStatus('status7', '✅ Schema deleted successfully (immediate)', 'success'); updateProgress('progress7', 100); // Clear input after successful deletion document.getElementById('deleteSchemaId').value = ''; document.getElementById('confirmDeletion').checked = false; }) .catch(error => { log(`Error: ${error.detail || error.message}`, 'error'); showStatus('status7', `Error: ${error.detail || error.message}`, 'error'); }); } function generateSchema() { const schemaId = document.getElementById('generateSchemaId').value; const jsonDataText = document.getElementById('generateJsonData').value; const nullHandling = document.getElementById('nullHandling').value; if (!schemaId) { showStatus('status5', 'Error: Schema ID es requerido', 'error'); return; } if (!jsonDataText) { showStatus('status5', 'Error: JSON data is required', 'error'); return; } let jsonData; try { jsonData = JSON.parse(jsonDataText); } catch (e) { showStatus('status5', 'Error: Invalid JSON data', 'error'); return; } const data = { schema_id: schemaId, json_data: jsonData, null_handling: nullHandling }; log('Starting schema generation with SSE'); setupSSEConnection('/schema/generate/stream', data, 'progress5', 'status5'); } function generateSchemaImmediate() { const schemaId = document.getElementById('generateSchemaId').value; const jsonDataText = document.getElementById('generateJsonData').value; const nullHandling = document.getElementById('nullHandling').value; if (!schemaId) { showStatus('status5', 'Error: Schema ID es requerido', 'error'); return; } if (!jsonDataText) { showStatus('status5', 'Error: JSON data is required', 'error'); return; } let jsonData; try { jsonData = JSON.parse(jsonDataText); } catch (e) { showStatus('status5', 'Error: Invalid JSON data', 'error'); return; } const data = { schema_id: schemaId, json_data: jsonData, null_handling: nullHandling }; log('Starting immediate schema generation'); fetch(`${SERVER_URL}/schema/generate`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }) .then(response => { if (!response.ok) { return response.json().then(err => Promise.reject(err)); } return response.json(); }) .then(result => { log(`Immediate result: ${JSON.stringify(result, null, 2)}`); showStatus('status5', '✅ Schema generated and saved successfully (immediate)', 'success'); updateProgress('progress5', 100); // Show generated schema in textarea const schemaInfo = result.schema_info || {}; const summary = `🎯 Schema generated successfully: - ID: ${result.schema_id} - Título: ${schemaInfo.title || 'N/A'} - Tipo: ${schemaInfo.type || 'N/A'} - Propiedades: ${schemaInfo.property_count || 0} - Required fields: ${schemaInfo.required_count || 0} - Manejo de nulls: ${result.null_handling} 📋 Use 'Get Schema' with ID '${result.schema_id}' to view the complete schema.`; document.getElementById('generatedSchema').value = summary; // Clear inputs after success document.getElementById('generateSchemaId').value = ''; document.getElementById('generateJsonData').value = ''; }) .catch(error => { log(`Error: ${error.detail || error.message}`, 'error'); showStatus('status5', `Error: ${error.detail || error.message}`, 'error'); }); } function getValidationInfo() { log('Getting validator information'); updateProgress('progress8', 20); fetch(`${SERVER_URL}/validation/info`, { method: 'GET', headers: { 'Content-Type': 'application/json' } }) .then(response => { updateProgress('progress8', 60); if (!response.ok) { return response.json().then(err => Promise.reject(err)); } return response.json(); }) .then(result => { updateProgress('progress8', 100); log(`Validator information obtained: ${JSON.stringify(result, null, 2)}`); showStatus('status8', '✅ Validator information retrieved successfully', 'success'); // Format and display the validation info const info = result.validation_info; const formattedInfo = `🔍 ${info.validator_name} v${info.version} 📋 JSON Schema Draft: ${info.draft_version} ✨ Features: ${info.features.map((feature, index) => `${index + 1}. ${feature}`).join('\n')} 📝 Supported formats: ${info.supported_formats.map((format, index) => `${index + 1}. ${format}`).join('\n')} 🗂️ Collections support: - Schema storage: ${info.collections_support.schema_storage ? '✅' : '❌'} - CRUD operations: ${info.collections_support.schema_crud ? '✅' : '❌'} - Schema listing: ${info.collections_support.schema_listing ? '✅' : '❌'} - Schema generation: ${info.collections_support.schema_generation ? '✅' : '❌'} 🔗 Available endpoints: 📍 Validation: ${info.endpoints.validation.map((endpoint, index) => `${index + 1}. ${endpoint}`).join('\n')} 📍 Schema management: ${info.endpoints.schema_management.map((endpoint, index) => `${index + 1}. ${endpoint}`).join('\n')} 📍 Information: ${info.endpoints.info.map((endpoint, index) => `${index + 1}. ${endpoint}`).join('\n')} 🕒 Timestamp: ${new Date(info.timestamp * 1000).toLocaleString()}`; document.getElementById('validatorInfo').value = formattedInfo; }) .catch(error => { updateProgress('progress8', 0); log(`Error: ${error.detail || error.message}`, 'error'); showStatus('status8', `Error: ${error.detail || error.message}`, 'error'); document.getElementById('validatorInfo').value = ''; }); } // Initialization log('SSE Client started. Server at: ' + SERVER_URL); // Check server status fetch(`${SERVER_URL}/health`) .then(response => response.json()) .then(data => { log(`Server connected: ${data.status}`); }) .catch(error => { log(`Error connecting to server: ${error.message}`, 'error'); }); </script> </body> </html>

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/EienWolf/jsonshema_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server