Commit restored mcp.verae.ai site pages (app, register, macos, windows, explorer), hasher/download artifacts, index/sample/hasher updates, ledger and global_client improvements, NATS stamp helper, and TestFlight enroll service. Ignore debug-trace/ and editor backups. Standard Readme for download and enroll docs.
188 lines
8.2 KiB
HTML
188 lines
8.2 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Verae timestamping MCP sample</title>
|
|
<meta name="description" content="Call Verae MCP stamp/verify/hash_report from the browser. No AI required.">
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,600&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
<link rel="icon" href="assets/VeraeFullLogo.png">
|
|
<style>
|
|
:root {
|
|
--ink: oklch(0.21 0.020 310);
|
|
--ink-soft: oklch(0.42 0.018 310);
|
|
--ink-mute: oklch(0.60 0.014 310);
|
|
--paper: oklch(0.992 0.004 90);
|
|
--soft: oklch(0.972 0.008 85);
|
|
--hair: oklch(0.90 0.010 80);
|
|
--purple: oklch(0.32 0.110 310);
|
|
--purple-mid: oklch(0.42 0.130 312);
|
|
--purple-wash: oklch(0.96 0.020 312);
|
|
--gold: oklch(0.80 0.090 85);
|
|
--dark: oklch(0.19 0.022 312);
|
|
}
|
|
* { box-sizing: border-box; }
|
|
body {
|
|
margin: 0;
|
|
font-family: Inter, -apple-system, BlinkMacSystemFont, sans-serif;
|
|
color: var(--ink);
|
|
background: var(--paper);
|
|
line-height: 1.55;
|
|
}
|
|
a { color: var(--purple); }
|
|
header {
|
|
display: flex; align-items: center; justify-content: space-between;
|
|
max-width: 1100px; margin: 0 auto; padding: 28px 28px 0; flex-wrap: wrap; gap: 12px;
|
|
}
|
|
.brand img { height: 46px; width: auto; display: block; }
|
|
nav { display: flex; gap: 22px; font-size: 14px; font-weight: 600; flex-wrap: wrap; }
|
|
nav a { color: var(--ink-soft); text-decoration: none; }
|
|
nav a:hover, nav a.active { color: var(--purple); }
|
|
.wrap { max-width: 760px; margin: 0 auto; padding: 36px 28px 80px; }
|
|
.eyebrow {
|
|
font-size: 13px; font-weight: 700; letter-spacing: 0.14em;
|
|
text-transform: uppercase; color: var(--purple-mid); margin: 0 0 8px;
|
|
}
|
|
h1 {
|
|
font-family: Fraunces, Georgia, serif; font-weight: 560;
|
|
font-size: clamp(28px, 4vw, 40px); line-height: 1.1;
|
|
letter-spacing: -0.03em; margin: 0 0 12px;
|
|
}
|
|
.lede { color: var(--ink-soft); margin: 0 0 18px; font-size: 16px; }
|
|
label { display: block; margin-top: 0.8rem; font-size: 13px; font-weight: 600; color: var(--ink-soft); }
|
|
input, select, button, textarea {
|
|
font: inherit; width: 100%; box-sizing: border-box; margin-top: 6px;
|
|
border: 1px solid var(--hair); border-radius: 10px; padding: 10px 12px; background: var(--soft); color: var(--ink);
|
|
}
|
|
button {
|
|
width: auto; margin-top: 1rem; background: var(--purple); color: white; border: 0;
|
|
border-radius: 999px; padding: 11px 18px; font-weight: 700; cursor: pointer;
|
|
}
|
|
pre {
|
|
white-space: pre-wrap; background: var(--dark); color: oklch(0.95 0.01 90);
|
|
padding: 0.9rem 1rem; border-radius: 14px; overflow: auto;
|
|
font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px;
|
|
}
|
|
code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.92em; }
|
|
footer {
|
|
max-width: 1100px; margin: 0 auto; padding: 0 28px 48px;
|
|
display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap;
|
|
font-size: 13px; color: var(--ink-mute);
|
|
}
|
|
@media (max-width: 800px) { nav { gap: 14px; } }
|
|
|
|
h2 { font-size: 20px; margin: 28px 0 8px; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<header>
|
|
<a class="brand" href="https://www.verae.com/"><img src="assets/VeraeFullLogo.png" alt="Verae"></a>
|
|
<nav>
|
|
<a href="index.html">Install</a>
|
|
<a href="ways.html">Ways to use</a>
|
|
<a href="explorer.html">Explorer</a>
|
|
<a href="macos.html">macOS</a>
|
|
<a href="windows.html">Windows</a>
|
|
<a href="app.html">Browser app</a>
|
|
<a href="register.html">Register docs</a>
|
|
<a href="sample.html" class="active">Sample</a>
|
|
<a href="hasher.html">Hasher</a>
|
|
</nav>
|
|
</header>
|
|
<main class="wrap">
|
|
<p class="eyebrow">MCP sample · no AI required</p>
|
|
<h1>Verae timestamping MCP sample</h1>
|
|
<p class="lede">This page calls a <strong>Model Context Protocol</strong> (MCP) server. It stamps a SHA-256 digest. It does not upload a file. See all clients on <a href="ways.html">Ways to use</a>.</p>
|
|
<p class="lede">Multi-document registration: <a href="register.html">register.html</a>. Full Register + Verify client: <a href="app.html">app.html</a>.</p>
|
|
<p class="lede">Defaults to the public MCP on this host. You can also point it at a local <code>uvx</code> server on <code>127.0.0.1</code>.</p>
|
|
<pre>VERAE_MCP_CORS=1 VERAE_MCP_TRANSPORT=streamable-http uv run verae-mcp-timestamping-server</pre>
|
|
<form id="stamp-form">
|
|
<label>Server URL <input id="url" value="https://mcp.verae.ai/mcp" data-default-remote="1"></label>
|
|
<label>SHA-256 <input id="sha" value="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" spellcheck="false"></label>
|
|
<label>Scope
|
|
<select id="scope">
|
|
<option value="global" selected>global</option>
|
|
<option value="shared">shared</option>
|
|
<option value="local">local</option>
|
|
</select>
|
|
</label>
|
|
<label>Tool
|
|
<select id="tool">
|
|
<option value="stamp">stamp</option>
|
|
<option value="verify">verify</option>
|
|
<option value="hash_report">hash_report</option>
|
|
</select>
|
|
</label>
|
|
<label>Receipt id (verify) <input id="receipt" placeholder="from a previous stamp"></label>
|
|
<button type="submit">Call tool</button>
|
|
</form>
|
|
<h2>Result</h2>
|
|
<pre id="out">Waiting.</pre>
|
|
<p>Docs in this repo: <a href="../docs/html/index.html">HTML</a> · <a href="../docs/pdf/standards.pdf">standards PDF</a></p>
|
|
<p>Same files on the public host: <a href="/docs/html/index.html">HTML</a> · <a href="/docs/pdf/standards.pdf">standards PDF</a></p>
|
|
</main>
|
|
<script>
|
|
const out = document.getElementById("out");
|
|
function rpc(id, method, params) {
|
|
return { jsonrpc: "2.0", id, method, params };
|
|
}
|
|
async function post(url, body, session) {
|
|
const headers = {
|
|
"Content-Type": "application/json",
|
|
"Accept": "application/json, text/event-stream"
|
|
};
|
|
if (session) headers["Mcp-Session-Id"] = session;
|
|
const res = await fetch(url, { method: "POST", headers, body: JSON.stringify(body) });
|
|
const text = await res.text();
|
|
const sessionId = res.headers.get("mcp-session-id") || session;
|
|
let parsed = text;
|
|
try { parsed = JSON.parse(text); } catch (e) { /* SSE or plain text */ }
|
|
if (!res.ok) throw new Error(res.status + " " + text);
|
|
return { parsed, sessionId };
|
|
}
|
|
document.getElementById("stamp-form").addEventListener("submit", async (ev) => {
|
|
ev.preventDefault();
|
|
const url = document.getElementById("url").value.trim();
|
|
const tool = document.getElementById("tool").value;
|
|
const sha = document.getElementById("sha").value.trim();
|
|
const scope = document.getElementById("scope").value;
|
|
const receipt = document.getElementById("receipt").value.trim();
|
|
out.textContent = "Calling " + url + " …";
|
|
try {
|
|
const init = await post(url, rpc(1, "initialize", {
|
|
protocolVersion: "2025-03-26",
|
|
capabilities: {},
|
|
clientInfo: { name: "verae-mcp-sample-page", version: "0.1.0" }
|
|
}));
|
|
await post(url, { jsonrpc: "2.0", method: "notifications/initialized" }, init.sessionId);
|
|
let args;
|
|
if (tool === "verify") args = { receipt_id: receipt, want_scope: scope };
|
|
else if (tool === "hash_report") args = { sha256: sha, want_scope: scope };
|
|
else args = { sha256: sha, scope };
|
|
const call = await post(url, rpc(2, "tools/call", { name: tool, arguments: args }), init.sessionId);
|
|
out.textContent = JSON.stringify({ initialize: init.parsed, call: call.parsed }, null, 2);
|
|
} catch (err) {
|
|
out.textContent = String(err) + "\n\nIf this page is not on the same machine as the server, the browser will block the call.";
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<script>
|
|
(function(){
|
|
var el = document.getElementById("url");
|
|
if (!el) return;
|
|
var host = location.hostname || "mcp.georgelambert.org";
|
|
if (host && host !== "localhost" && host !== "127.0.0.1") {
|
|
el.value = "https://" + host + "/mcp";
|
|
}
|
|
})();
|
|
</script>
|
|
<footer>
|
|
<span>Verae timestamping · <a href="https://www.verae.com/">verae.com</a></span>
|
|
<span><a href="ways.html">Ways to use</a> · <a href="ways.html#testflight">TestFlight</a> · <a href="app.html">Browser app</a> · <a href="windows.html">Windows</a></span>
|
|
</footer>
|
|
|
|
</body>
|
|
</html>
|