const vibeMcp = {
init: function() {
this.refreshServers();
},
refreshServers: async function() {
try {
const listContainer = document.getElementById('mcpServerList');
if (listContainer) {
listContainer.innerHTML = '
Loading servers...
';
}
const response = await fetch('/api/ui/sources/mcp');
if (!response.ok) throw new Error('Failed to fetch MCP servers');
const data = await response.json();
// Expected data structure: { servers: [...] }
this.renderServers(data.servers || []);
} catch (err) {
console.error(err);
const listContainer = document.getElementById('mcpServerList');
if (listContainer) {
listContainer.innerHTML = `Error loading servers: ${err.message}
`;
}
}
},
toggleServer: async function(name, enable) {
try {
// Assume an endpoint to toggle enable/disable
const response = await fetch(`/api/ui/sources/mcp/${name}/enable`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ enable: enable })
});
if (response.ok) {
this.refreshServers();
} else {
alert('Failed to toggle server');
}
} catch (e) {
alert('Error toggling server');
}
},
renderServers: function(servers) {
const listContainer = document.getElementById('mcpServerList');
if (!listContainer) return;
if (servers.length === 0) {
listContainer.innerHTML = 'No MCP servers connected.
';
return;
}
let html = '';
servers.forEach(server => {
const isActive = server.enabled || server.active;
const statusClass = isActive ? 'status-active' : 'status-inactive';
html += `
${this.renderTools(server.tools || [])}
`;
});
listContainer.innerHTML = html;
},
renderTools: function(tools) {
if (!tools || tools.length === 0) return 'No tools available
';
// Show up to 3 tools
const displayTools = tools.slice(0, 3);
let toolsHtml = displayTools.map(t => `${t.name}
`).join('');
if (tools.length > 3) {
toolsHtml += `+${tools.length - 3} more
`;
}
return toolsHtml;
}
};
// Initialize when the script loads
document.addEventListener('DOMContentLoaded', () => {
vibeMcp.init();
});
// Since HTMX loads this dynamically, also invoke init right away if DOM is already ready
if (document.readyState === 'complete' || document.readyState === 'interactive') {
vibeMcp.init();
}