<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>MCP Server Demo UI</title>
<style>
:root {
color-scheme: light dark;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
body {
margin: 0;
padding: 2rem;
background: #111;
color: #f7f7f7;
display: flex;
flex-direction: column;
gap: 2rem;
}
h1,
h2 {
margin: 0 0 1rem 0;
}
section {
background: rgba(255, 255, 255, 0.05);
padding: 1.5rem;
border-radius: 12px;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.35);
}
form {
display: flex;
flex-direction: column;
gap: 1rem;
}
textarea,
input,
button {
font: inherit;
}
textarea,
input {
background: rgba(0, 0, 0, 0.25);
border: 1px solid rgba(255, 255, 255, 0.2);
color: inherit;
border-radius: 8px;
padding: 0.75rem;
resize: vertical;
}
button {
align-self: flex-start;
background: linear-gradient(135deg, #3b82f6 0%, #6366f1 100%);
color: white;
border: none;
padding: 0.75rem 1.5rem;
border-radius: 999px;
cursor: pointer;
transition: transform 0.15s ease;
}
button:disabled {
opacity: 0.6;
cursor: not-allowed;
}
button:not(:disabled):hover {
transform: translateY(-1px);
}
pre {
background: rgba(0, 0, 0, 0.4);
padding: 1rem;
border-radius: 8px;
white-space: pre-wrap;
word-break: break-word;
}
.status {
font-size: 0.95rem;
opacity: 0.7;
}
</style>
</head>
<body>
<header>
<h1>MCP Server Interactive Demo</h1>
<p class="status">
Use the panels below to verify the OpenAI integration and the MCP knowledge-search tool without
leaving your browser.
</p>
</header>
<section>
<h2>1. Call OpenAI Chat Completion</h2>
<form id="openai-form">
<label>
Prompt
<textarea id="openai-prompt" rows="4" placeholder="Ask OpenAI anything...">Give me a random fun fact about the Model Context Protocol.</textarea>
</label>
<label>
Model (optional)
<input id="openai-model" type="text" placeholder="gpt-4o-mini" />
</label>
<button type="submit">Send Request</button>
</form>
<div id="openai-result" hidden>
<strong>Response:</strong>
<pre></pre>
</div>
</section>
<section>
<h2>2. Invoke MCP Knowledge Search Tool</h2>
<form id="tool-form">
<label>
Query term
<input id="tool-query" type="text" value="architecture" />
</label>
<button type="submit">Search Knowledge Base</button>
</form>
<div id="tool-result" hidden>
<strong>Result:</strong>
<pre></pre>
</div>
</section>
<script>
const handleResponse = async (response) => {
const data = await response.json().catch(() => ({}));
if (!response.ok) {
const error = data?.error ?? response.statusText;
throw new Error(typeof error === 'string' ? error : JSON.stringify(error));
}
return data;
};
const renderResult = (containerId, payload) => {
const container = document.getElementById(containerId);
const pre = container.querySelector('pre');
pre.textContent = typeof payload === 'string' ? payload : JSON.stringify(payload, null, 2);
container.hidden = false;
};
document.getElementById('openai-form').addEventListener('submit', async (event) => {
event.preventDefault();
const form = event.currentTarget;
const button = form.querySelector('button');
button.disabled = true;
try {
const prompt = document.getElementById('openai-prompt').value.trim();
const model = document.getElementById('openai-model').value.trim();
const response = await fetch('/api/openai', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ prompt, model }),
});
const data = await handleResponse(response);
renderResult('openai-result', data);
} catch (error) {
renderResult('openai-result', { error: error.message });
} finally {
button.disabled = false;
}
});
document.getElementById('tool-form').addEventListener('submit', async (event) => {
event.preventDefault();
const form = event.currentTarget;
const button = form.querySelector('button');
button.disabled = true;
try {
const query = document.getElementById('tool-query').value.trim();
const response = await fetch('/api/tools/knowledge_search', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query }),
});
const data = await handleResponse(response);
renderResult('tool-result', data);
} catch (error) {
renderResult('tool-result', { error: error.message });
} finally {
button.disabled = false;
}
});
</script>
</body>
</html>