Dominion Observatory is the behavioral trust layer for MCP servers. Public read endpoints need no key. Availability depends on deployment configuration; a signature establishes capture integrity, not endpoint safety.
Machine-readable specs: Capabilities · /openapi.json · /llms.txt · /llms-full.txt · MCP server card · /api/info
| GET /api/trust | Trust score + reliability metrics for a server (by URL or slug). |
| GET /api/drift | Tool-manifest drift: has the server's tool descriptions/schemas changed since baseline? |
| GET /drift | Human page for the drift check. |
| GET /drift-badge | Shields-style README status badge (SVG). |
| GET /api/servers | Server directory, filter by category. |
| GET /api/baselines | Category behavioral baselines. |
{
"kty": "OKP",
"crv": "Ed25519",
"x": "Z7sNt6bWqAaHkULsSOiRAySXx0RgQBbq5A1ZV50Ys_M",
"kid": "capture-a46fe710c055398f3b6f43a1",
"alg": "EdDSA",
"use": "sig"
}
New captures include signed_capture with the immutable payload, Ed25519 signature and key id. Legacy captures have no signature. Fetch the public key from capture JWKS; pin trusted keys before verification. The timestamp is an observation time, not a freshness or safety guarantee. Keep old public keys when rotating.
// Node 22+: save as verify-capture.mjs. Pass the downloaded signed_capture JSON.
// Usage: node verify-capture.mjs capture.json trusted-capture-jwks.json
// Download keys from /.well-known/capture-jwks.json over trusted HTTPS and pin them.
import {readFileSync} from 'node:fs';
import {createPublicKey,createHash,verify} from 'node:crypto';
const canonical = v => v === null || typeof v !== 'object' ? JSON.stringify(v)
: Array.isArray(v) ? '['+v.map(canonical).join(',')+']'
: '{'+Object.keys(v).sort().map(k=>JSON.stringify(k)+':'+canonical(v[k])).join(',')+'}';
const s=JSON.parse(readFileSync(process.argv[2],'utf8'));
const keys=JSON.parse(readFileSync(process.argv[3],'utf8')).keys;
const key=keys.find(k=>k.kid===s.kid && k.crv==='Ed25519' && k.kty==='OKP');
if (!key || s.alg!=='Ed25519' || s.payload.schema!=='dominion.capture.v1') throw Error('Unknown key/schema');
const hash=createHash('sha256').update(canonical(s.payload.capture.tools)).digest('hex');
if (hash!==s.payload.tools_list_sha256 || !verify(null,Buffer.from(canonical(s.payload)),
createPublicKey({key,format:'jwk'}),Buffer.from(s.signature,'base64url'))) throw Error('Invalid capture');
console.log('Verified capture integrity',s.payload.server_url,s.payload.captured_at);
// Also compare server_url and captured_at with your intended endpoint/freshness policy.
// Signatures do not prove that an endpoint is safe or that a tool behaves as described.
| GET /v1/verify?jws= | Stateless Ed25519 verification of any receipt/attestation we issued. |
| GET /v1/receipt/{id} | Resolve a diligence-receipt id to the full signed claim + live re-verification. |
| GET /api/transparency-log | Public append-only log of every issued receipt (raw JWS, self-verifying). |
| GET /.well-known/jwks.json | Our published Ed25519 public key (kid dominion-observatory-2026). |
| POST /mcp | Hosted MCP server (Streamable HTTP): tools/list, check_trust, preflight_check, and more. |
| GET server-card | Machine-readable MCP server card. |
| GET /api/trust/verascore | verascore-evidence-schema-v0.1 evidence; add &format=signed for an RFC8785-JCS + Ed25519 envelope. |
| GET /api/compliance-report | Compliance-oriented report for a server. |
| GET /api/nsa-checklist | NSA MCP security checklist mapping. |
Pricing for monitoring & the metered API is at /pricing.