MCP MySQL Server
by TristanLib
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MCP MySQL SSE 测试</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
#messages {
border: 1px solid #ccc;
padding: 10px;
height: 300px;
overflow-y: auto;
margin-bottom: 20px;
background-color: #f8f8f8;
}
.message {
padding: 5px;
margin-bottom: 5px;
border-bottom: 1px solid #eee;
}
.message.system {
background-color: #e6f7ff;
}
.message.ping {
color: #888;
font-size: 0.8em;
}
.message.connection {
background-color: #f6ffed;
}
.message.database-update {
background-color: #fff7e6;
}
.timestamp {
color: #888;
font-size: 0.8em;
}
</style>
</head>
<body>
<h1>MCP MySQL SSE 测试</h1>
<div>
<button id="connect">连接 SSE</button>
<button id="disconnect" disabled>断开连接</button>
<span id="status">未连接</span>
</div>
<h2>事件消息</h2>
<div id="messages"></div>
<script>
const connectBtn = document.getElementById('connect');
const disconnectBtn = document.getElementById('disconnect');
const statusSpan = document.getElementById('status');
const messagesDiv = document.getElementById('messages');
let eventSource;
function formatTimestamp() {
return new Date().toLocaleTimeString();
}
function addMessage(event, data) {
const msgDiv = document.createElement('div');
msgDiv.className = `message ${event}`;
const timestamp = document.createElement('span');
timestamp.className = 'timestamp';
timestamp.textContent = formatTimestamp() + ' ';
const eventSpan = document.createElement('strong');
eventSpan.textContent = event + ': ';
const dataSpan = document.createElement('span');
dataSpan.textContent = typeof data === 'object' ? JSON.stringify(data) : data;
msgDiv.appendChild(timestamp);
msgDiv.appendChild(eventSpan);
msgDiv.appendChild(dataSpan);
messagesDiv.appendChild(msgDiv);
messagesDiv.scrollTop = messagesDiv.scrollHeight;
}
connectBtn.addEventListener('click', function() {
try {
const apiKey = '123456';
eventSource = new EventSource(`http://localhost:3000/api/sse?apiKey=${apiKey}`);
statusSpan.textContent = '正在连接...';
addMessage('info', '正在连接到SSE服务...');
eventSource.onopen = function() {
statusSpan.textContent = '已连接';
connectBtn.disabled = true;
disconnectBtn.disabled = false;
addMessage('info', 'SSE连接已建立');
};
eventSource.onerror = function(err) {
statusSpan.textContent = '连接错误';
addMessage('error', '连接出错: ' + JSON.stringify(err));
eventSource.close();
connectBtn.disabled = false;
disconnectBtn.disabled = true;
};
// 监听各种事件类型
eventSource.addEventListener('connection', function(e) {
const data = JSON.parse(e.data);
addMessage('connection', data);
});
eventSource.addEventListener('ping', function(e) {
const data = JSON.parse(e.data);
addMessage('ping', data);
});
eventSource.addEventListener('system', function(e) {
const data = JSON.parse(e.data);
addMessage('system', data);
});
eventSource.addEventListener('database-update', function(e) {
const data = JSON.parse(e.data);
addMessage('database-update', data);
});
// 未知事件类型
eventSource.onmessage = function(e) {
const data = JSON.parse(e.data);
addMessage('unknown', data);
};
} catch (error) {
addMessage('error', '创建SSE连接失败: ' + error.message);
}
});
disconnectBtn.addEventListener('click', function() {
if (eventSource) {
eventSource.close();
eventSource = null;
statusSpan.textContent = '已断开连接';
connectBtn.disabled = false;
disconnectBtn.disabled = true;
addMessage('info', 'SSE连接已关闭');
}
});
</script>
</body>
</html>