import type { KvStateSnapshot } from "./store.js";
export interface RenderOptions {
tokenRequired?: boolean;
}
function escapeHtml(value: string): string {
return value
.replace(/&/g, "&")
.replace(//g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
function renderRows(snapshot: KvStateSnapshot): string {
if (snapshot.entries.length === 0) {
return `
No values yet — call the kv_set tool to add one. |
`;
}
return snapshot.entries
.map(
(entry) => `
| ${escapeHtml(entry.key)} |
${escapeHtml(entry.value)} |
${escapeHtml(entry.updatedAt)} |
`,
)
.join("\n");
}
/**
* Render the values UI. The page server-renders the current snapshot and then
* polls {@code GET /api/state} so the table reflects tool writes without a manual
* refresh.
*/
export function renderStatePage(snapshot: KvStateSnapshot, options: RenderOptions = {}): string {
const tokenRequired = options.tokenRequired === true;
return `
KV Demo MCP Server
KV Demo MCP Server
In-memory values for this process. ${snapshot.count} key(s), revision ${snapshot.revision}. Auto-refreshing every 2s.
| Key | Value | Updated |
${renderRows(snapshot)}
`;
}