Skip to main content
Glama

mcp-perplexity

MIT License
62
  • Linux
  • Apple
chat.html6.88 kB
{% extends "base.html" %} {% block title %}{{ chat['title'] or 'Untitled Chat' }} - MCP Perplexity{% endblock %} {% block content %} <div class="dark:bg-tokyo-bg-secondary shadow sm:rounded-lg"> <div class="px-4 py-3 sm:px-6"> <div class="flex items-center justify-between"> <div> <h2 class="text-md leading-6 font-medium dark:text-tokyo-accent-blue"> {{ chat['title'] or 'Untitled Chat' }} </h2> <p class="mt-0.5 max-w-2xl text-sm dark:text-tokyo-text"> Created {{ chat['created_at'].strftime('%Y-%m-%d %H:%M:%S') }} </p> </div> <div class="flex items-center"> <span class="inline-flex items-center rounded-full dark:bg-tokyo-bg-accent px-2.5 py-0.5 text-xs font-medium dark:text-tokyo-text"> ID: {{ chat['id'] }} </span> <button class="copy-chat-id ml-1 dark:text-tokyo-text-secondary hover:text-tokyo-accent-blue focus:outline-none focus:ring-1 focus:ring-tokyo-accent-blue rounded-md transition-colors duration-150" data-chat-id="{{ chat['id'] }}"> <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none" /> <path d="M9 5h-2a2 2 0 0 0 -2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-12a2 2 0 0 0 -2 -2h-2" /> <path d="M9 3m0 2a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v0a2 2 0 0 1 -2 2h-2a2 2 0 0 1 -2 -2z" /> </svg> </button> <span class="copied-text ml-2 text-tokyo-accent-green text-xs hidden">Copied!</span> <a href="/" class="ml-4 inline-flex items-center px-4 py-2 border dark:border-tokyo-bg-accent shadow-sm text-sm font-medium rounded-md dark:text-tokyo-text dark:bg-tokyo-bg-accent hover:bg-tokyo-bg-message transition-colors duration-150"> Back to Chats </a> </div> </div> </div> <div class="border-t dark:border-tokyo-bg-accent"> <!-- Container for messages - No longer has direct HTMX update attributes --> <div class="chat-container px-4 py-3 sm:px-6"> {% include '_message_list.html' %} </div> </div> </div> <!-- Hidden div that acts as a data fetcher and updates messages only if there are changes --> <div id="message-updater" hx-get="/api/chat/{{ chat['id'] }}/messages" hx-trigger="every 5s" hx-target="#message-updater" hx-swap="innerHTML" class="hidden"> </div> <script> let lastMessageCount = document.querySelectorAll('.message').length; let messageData = null; // Scroll to bottom only on initial load document.addEventListener('DOMContentLoaded', () => { const container = document.querySelector('.chat-container'); container.scrollTop = container.scrollHeight; // Initialize the message data on load messageData = Array.from(document.querySelectorAll('.message')).map(el => el.id); }); // On HTMX content update to the hidden updater document.body.addEventListener('htmx:afterSwap', (event) => { if (event.detail.target.id !== 'message-updater') return; // Parse the new data and compare with current state const updatedMessages = Array.from(event.detail.target.querySelectorAll('.message')); const updatedMessageIds = updatedMessages.map(el => el.id); // Only update if there are actual changes in the messages if (JSON.stringify(updatedMessageIds) !== JSON.stringify(messageData)) { // Save scroll position and details state const container = document.querySelector('.chat-container'); const scrollPosition = container.scrollTop; const isNearBottom = container.scrollHeight - container.scrollTop - container.clientHeight < 100; // Save states of any open details elements const openDetailsState = {}; document.querySelectorAll('.chat-container details').forEach(detail => { openDetailsState[detail.querySelector('summary').textContent.trim()] = detail.open; }); // Update the messages container with new content document.querySelector('.chat-container').innerHTML = event.detail.target.innerHTML; // Restore open state of details elements document.querySelectorAll('.chat-container details').forEach(detail => { const summary = detail.querySelector('summary').textContent.trim(); if (openDetailsState[summary]) { detail.open = true; } }); // Update our tracked message data messageData = updatedMessageIds; // Restore scroll position or scroll to bottom for new messages if (isNearBottom) { container.scrollTop = container.scrollHeight; } else { container.scrollTop = scrollPosition; } } }); // Copy chat ID functionality document.addEventListener('DOMContentLoaded', function() { document.querySelectorAll('.copy-chat-id').forEach(button => { button.addEventListener('click', function(e) { e.preventDefault(); e.stopPropagation(); const chatId = this.getAttribute('data-chat-id'); navigator.clipboard.writeText(chatId).then(() => { // Visual feedback: Show "Copied!" text let sibling = this.nextElementSibling; while (sibling && !sibling.classList.contains('copied-text')) { sibling = sibling.nextElementSibling; } if (sibling) { sibling.classList.remove('hidden'); setTimeout(() => { sibling.classList.add('hidden'); }, 1500); } // Visual feedback - temporarily change the icon color const svg = this.querySelector('svg'); svg.className.baseVal = 'h-4 w-4 text-tokyo-accent-green'; setTimeout(() => { svg.className.baseVal = 'h-4 w-4'; }, 1000); }).catch(err => { console.error('Failed to copy:', err); }); }); }); }); </script> {% endblock %}

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/daniel-lxs/mcp-perplexity'

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