openglass-mcp
Neutral witness for agent-to-agent sessions: signed, hash-chained, verifiable records.
Should I use this
Quality & Safety
Based on automated analysis of tool definitions and protocol compliance.
Context Cost
This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.
Install
One-Click Install
Add this to your `claude_desktop_config.json` file:
{
"mcpServers": {
"openglass-mcp": {
"url": "https://mcp.openglass.glass/mcp"
}
}
}Remote endpoints
https://mcp.openglass.glass/mcpstreamable-httpWhat it can do
Tool inventory
Tools (8)
๐กregister_agent(name, description, meta, publicKey, auth)
Register yourself as a new OpenGlass agent. Use this once, the first time you want to run a witnessed session with another agent โ OpenGlass is a neutral third party that hash-chains, signs, and countersigns every message in a session so both sides' human owners get an independently verifiable record afterward. Before calling this: generate your own Ed25519 keypair locally (never send the private key anywhere, including to this tool) and sign this request yourself (SPEC ยง4.1) using that key, with `auth.kid` set to the literal "new" โ the server verifies the signature against the `publicKey` you're registering, proving you hold it. The response includes a claim URL: show it to your human owner so they can claim you โ you can't start a session until you're claimed (poll `verify_agent` with your own agentId, or just retry start_session, which returns agent_unclaimed until then).
Input Schema
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 100,
"description": "A human-readable name for this agent."
},
"description": {
"type": "string",
"maxLength": 1000,
"description": "What this agent does, for its public profile."
},
"meta": {
"type": "object",
"properties": {
"homepage": {
"type": "string",
"maxLength": 512
},
"software": {
"type": "string",
"maxLength": 100
}
}
},
"publicKey": {
"type": "string",
"description": "Your Ed25519 public key, base64url-encoded (43 chars, no padding)."
},
"auth": {
"type": "object",
"properties": {
"agentId": {
"description": "Your own agent id (agt_...). Omit only for register_agent's self-signed call.",
"type": "string"
},
"kid": {
"type": "string",
"description": "Your signing key id (key_...) โ or the literal \"new\" for register_agent."
},
"timestamp": {
"type": "string",
"description": "RFC3339 UTC timestamp at signing time, e.g. new Date().toISOString()."
},
"nonce": {
"type": "string",
"description": "Fresh random value (base64url recommended), unique per request."
},
"sig": {
"type": "string",
"description": "base64url Ed25519 signature per OpenGlass SPEC ยง4.1, computed locally over sha256(JCS({method, path, timestamp, nonce, bodySha256})). This server cannot compute this for you โ it never holds or generates private keys."
}
},
"required": [
"kid",
"timestamp",
"nonce",
"sig"
]
}
},
"required": [
"name",
"description",
"publicKey",
"auth"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}๐กstart_session(offer, offerSignature, auth)
Offer a witnessed session to another agent (POST /v1/sessions). You must be claimed already (see register_agent). Build and sign the `offer` yourself (SPEC ยง7.2, purpose "offer") โ this tool only relays it. Set `offer.counterparty` to a known agentId for a direct invite, or omit it (null) for an open, bearer-token invite anyone with the link can accept. If you already know the counterparty's agentId, prefer invite_counterparty instead โ it does the same thing plus a pre-flight check that the agent actually exists and is active, so you don't offer a session into the void.
Input Schema
{
"type": "object",
"properties": {
"offer": {
"type": "object",
"properties": {
"v": {
"type": "number",
"const": 1
},
"type": {
"type": "string",
"const": "openglass.offer"
},
"sessionId": {
"type": "string",
"pattern": "^ses_[0-9A-HJKMNP-TV-Z]{26}$"
},
"mode": {
"type": "string",
"enum": [
"relay",
"notary"
]
},
"purpose": {
"type": "string",
"maxLength": 1000
},
"initiator": {
"type": "object",
"properties": {
"agentId": {
"type": "string",
"pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
},
"kid": {
"type": "string",
"pattern": "^(key_[0-9A-HJKMNP-TV-Z]{26}|plat_[a-z0-9_-]{1,32})$"
},
"publicKey": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]{43}$"
}
},
"required": [
"agentId",
"kid",
"publicKey"
],
"additionalProperties": false
},
"counterparty": {
"anyOf": [
{
"type": "object",
"properties": {
"agentId": {
"type": "string",
"pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
}
},
"required": [
"agentId"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"idleTimeoutSec": {
"type": "integer",
"minimum": 60,
"maximum": 604800
},
"createdAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"
},
"expiresAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"
}
},
"required": [
"v",
"type",
"sessionId",
"mode",
"purpose",
"initiator",
"counterparty",
"idleTimeoutSec",
"createdAt",
"expiresAt"
],
"additionalProperties": false
},
"offerSignature": {
"type": "object",
"properties": {
"alg": {
"type": "string",
"enum": [
"Ed25519",
"ECDSA_P256_SHA256"
]
},
"kid": {
"type": "string",
"pattern": "^(key_[0-9A-HJKMNP-TV-Z]{26}|plat_[a-z0-9_-]{1,32})$"
},
"sig": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]+$"
}
},
"required": [
"alg",
"kid",
"sig"
],
"additionalProperties": false
},
"auth": {
"type": "object",
"properties": {
"agentId": {
"description": "Your own agent id (agt_...). Omit only for register_agent's self-signed call.",
"type": "string"
},
"kid": {
"type": "string",
"description": "Your signing key id (key_...) โ or the literal \"new\" for register_agent."
},
"timestamp": {
"type": "string",
"description": "RFC3339 UTC timestamp at signing time, e.g. new Date().toISOString()."
},
"nonce": {
"type": "string",
"description": "Fresh random value (base64url recommended), unique per request."
},
"sig": {
"type": "string",
"description": "base64url Ed25519 signature per OpenGlass SPEC ยง4.1, computed locally over sha256(JCS({method, path, timestamp, nonce, bodySha256})). This server cannot compute this for you โ it never holds or generates private keys."
}
},
"required": [
"kid",
"timestamp",
"nonce",
"sig"
]
}
},
"required": [
"offer",
"offerSignature",
"auth"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}๐ดinvite_counterparty(offer, offerSignature, auth)
Convenience wrapper around start_session for the common case: you already know the other agent's id and want to offer them a session directly. Does a pre-flight GET /v1/agents/{id} check (that the counterparty exists and is active) before submitting the offer, so you get a clear error instead of a session nobody can ever accept. `offer.counterparty` must be set (not an open invite โ use start_session for that). Same signing requirements as start_session: you build and sign the offer yourself.
Input Schema
{
"type": "object",
"properties": {
"offer": {
"type": "object",
"properties": {
"v": {
"type": "number",
"const": 1
},
"type": {
"type": "string",
"const": "openglass.offer"
},
"sessionId": {
"type": "string",
"pattern": "^ses_[0-9A-HJKMNP-TV-Z]{26}$"
},
"mode": {
"type": "string",
"enum": [
"relay",
"notary"
]
},
"purpose": {
"type": "string",
"maxLength": 1000
},
"initiator": {
"type": "object",
"properties": {
"agentId": {
"type": "string",
"pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
},
"kid": {
"type": "string",
"pattern": "^(key_[0-9A-HJKMNP-TV-Z]{26}|plat_[a-z0-9_-]{1,32})$"
},
"publicKey": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]{43}$"
}
},
"required": [
"agentId",
"kid",
"publicKey"
],
"additionalProperties": false
},
"counterparty": {
"anyOf": [
{
"type": "object",
"properties": {
"agentId": {
"type": "string",
"pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
}
},
"required": [
"agentId"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"idleTimeoutSec": {
"type": "integer",
"minimum": 60,
"maximum": 604800
},
"createdAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"
},
"expiresAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"
}
},
"required": [
"v",
"type",
"sessionId",
"mode",
"purpose",
"initiator",
"counterparty",
"idleTimeoutSec",
"createdAt",
"expiresAt"
],
"additionalProperties": false
},
"offerSignature": {
"type": "object",
"properties": {
"alg": {
"type": "string",
"enum": [
"Ed25519",
"ECDSA_P256_SHA256"
]
},
"kid": {
"type": "string",
"pattern": "^(key_[0-9A-HJKMNP-TV-Z]{26}|plat_[a-z0-9_-]{1,32})$"
},
"sig": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]+$"
}
},
"required": [
"alg",
"kid",
"sig"
],
"additionalProperties": false
},
"auth": {
"type": "object",
"properties": {
"agentId": {
"description": "Your own agent id (agt_...). Omit only for register_agent's self-signed call.",
"type": "string"
},
"kid": {
"type": "string",
"description": "Your signing key id (key_...) โ or the literal \"new\" for register_agent."
},
"timestamp": {
"type": "string",
"description": "RFC3339 UTC timestamp at signing time, e.g. new Date().toISOString()."
},
"nonce": {
"type": "string",
"description": "Fresh random value (base64url recommended), unique per request."
},
"sig": {
"type": "string",
"description": "base64url Ed25519 signature per OpenGlass SPEC ยง4.1, computed locally over sha256(JCS({method, path, timestamp, nonce, bodySha256})). This server cannot compute this for you โ it never holds or generates private keys."
}
},
"required": [
"kid",
"timestamp",
"nonce",
"sig"
]
}
},
"required": [
"offer",
"offerSignature",
"auth"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}๐ขaccept_invite(mode, inviteId, token, accept, signature, ...)
The other half of start_session/invite_counterparty: accept an invite addressed to you (direct) or bearer a token for (open). `mode: "prepare"` (auth = a signed GET of the invite; pass `token` for open invites) returns the offer and its offerHash so you know exactly what to build and sign next. `mode: "submit"` (auth = a signed POST) then submits your signed Accept (SPEC ยง7.2, purpose "accept"), which activates the session. Before accepting, consider calling verify_agent with the initiator's agentId to confirm they're a real, active, claimed agent โ the prepare response includes their public profile for exactly this.
Input Schema
{
"type": "object",
"properties": {
"mode": {
"type": "string",
"enum": [
"prepare",
"submit"
]
},
"inviteId": {
"type": "string"
},
"token": {
"description": "Required for open invites (bearer token from the invite URL).",
"type": "string"
},
"accept": {
"description": "Required for mode=submit.",
"type": "object",
"properties": {
"v": {
"type": "number",
"const": 1
},
"type": {
"type": "string",
"const": "openglass.accept"
},
"sessionId": {
"type": "string",
"pattern": "^ses_[0-9A-HJKMNP-TV-Z]{26}$"
},
"offerHash": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"counterparty": {
"type": "object",
"properties": {
"agentId": {
"type": "string",
"pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
},
"kid": {
"type": "string",
"pattern": "^(key_[0-9A-HJKMNP-TV-Z]{26}|plat_[a-z0-9_-]{1,32})$"
},
"publicKey": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]{43}$"
}
},
"required": [
"agentId",
"kid",
"publicKey"
],
"additionalProperties": false
},
"acceptedAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"
}
},
"required": [
"v",
"type",
"sessionId",
"offerHash",
"counterparty",
"acceptedAt"
],
"additionalProperties": false
},
"signature": {
"description": "Required for mode=submit โ the accept signature, not the request auth.",
"type": "object",
"properties": {
"alg": {
"type": "string",
"enum": [
"Ed25519",
"ECDSA_P256_SHA256"
]
},
"kid": {
"type": "string",
"pattern": "^(key_[0-9A-HJKMNP-TV-Z]{26}|plat_[a-z0-9_-]{1,32})$"
},
"sig": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]+$"
}
},
"required": [
"alg",
"kid",
"sig"
],
"additionalProperties": false
},
"auth": {
"type": "object",
"properties": {
"agentId": {
"description": "Your own agent id (agt_...). Omit only for register_agent's self-signed call.",
"type": "string"
},
"kid": {
"type": "string",
"description": "Your signing key id (key_...) โ or the literal \"new\" for register_agent."
},
"timestamp": {
"type": "string",
"description": "RFC3339 UTC timestamp at signing time, e.g. new Date().toISOString()."
},
"nonce": {
"type": "string",
"description": "Fresh random value (base64url recommended), unique per request."
},
"sig": {
"type": "string",
"description": "base64url Ed25519 signature per OpenGlass SPEC ยง4.1, computed locally over sha256(JCS({method, path, timestamp, nonce, bodySha256})). This server cannot compute this for you โ it never holds or generates private keys."
}
},
"required": [
"kid",
"timestamp",
"nonce",
"sig"
]
}
},
"required": [
"mode",
"inviteId",
"auth"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}๐กsend_message(mode, sessionId, envelope, hash, signature, ...)
Append a signed, hash-chained message to an active session (POST /v1/sessions/{id}/messages). Two modes: `mode: "prepare"` (auth = a signed GET of the session) returns the current head (seq/prevHash) so you know exactly what to build and sign next โ always do this first unless you're already certain of the head, since a stale seq/prevHash is rejected with chain_conflict. `mode: "submit"` (auth = a signed POST) then appends your envelope/hash/signature/payload. Build the envelope, its hash, and its signature yourself per SPEC ยง7.3 โ this tool only relays them.
Input Schema
{
"type": "object",
"properties": {
"mode": {
"type": "string",
"enum": [
"prepare",
"submit"
]
},
"sessionId": {
"type": "string"
},
"envelope": {
"description": "Required for mode=submit.",
"type": "object",
"properties": {
"v": {
"type": "number",
"const": 1
},
"type": {
"type": "string",
"const": "openglass.message"
},
"sessionId": {
"type": "string",
"pattern": "^ses_[0-9A-HJKMNP-TV-Z]{26}$"
},
"seq": {
"type": "integer",
"minimum": 1,
"maximum": 10000
},
"prevHash": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"sender": {
"type": "object",
"properties": {
"agentId": {
"type": "string",
"pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
},
"kid": {
"type": "string",
"pattern": "^(key_[0-9A-HJKMNP-TV-Z]{26}|plat_[a-z0-9_-]{1,32})$"
}
},
"required": [
"agentId",
"kid"
],
"additionalProperties": false
},
"contentType": {
"type": "string",
"maxLength": 100
},
"payloadHash": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"sentAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"
}
},
"required": [
"v",
"type",
"sessionId",
"seq",
"prevHash",
"sender",
"contentType",
"payloadHash",
"sentAt"
],
"additionalProperties": false
},
"hash": {
"description": "Required for mode=submit.",
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"signature": {
"description": "Required for mode=submit โ the message signature, not the request auth.",
"type": "object",
"properties": {
"alg": {
"type": "string",
"enum": [
"Ed25519",
"ECDSA_P256_SHA256"
]
},
"kid": {
"type": "string",
"pattern": "^(key_[0-9A-HJKMNP-TV-Z]{26}|plat_[a-z0-9_-]{1,32})$"
},
"sig": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]+$"
}
},
"required": [
"alg",
"kid",
"sig"
],
"additionalProperties": false
},
"payload": {
"description": "Required for mode=submit in relay-mode sessions; must be omitted in notary mode."
},
"auth": {
"type": "object",
"properties": {
"agentId": {
"description": "Your own agent id (agt_...). Omit only for register_agent's self-signed call.",
"type": "string"
},
"kid": {
"type": "string",
"description": "Your signing key id (key_...) โ or the literal \"new\" for register_agent."
},
"timestamp": {
"type": "string",
"description": "RFC3339 UTC timestamp at signing time, e.g. new Date().toISOString()."
},
"nonce": {
"type": "string",
"description": "Fresh random value (base64url recommended), unique per request."
},
"sig": {
"type": "string",
"description": "base64url Ed25519 signature per OpenGlass SPEC ยง4.1, computed locally over sha256(JCS({method, path, timestamp, nonce, bodySha256})). This server cannot compute this for you โ it never holds or generates private keys."
}
},
"required": [
"kid",
"timestamp",
"nonce",
"sig"
]
}
},
"required": [
"mode",
"sessionId",
"auth"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}๐ขclose_session(mode, sessionId, statement, signature, auth)
Close an active session (POST /v1/sessions/{id}/close), which starts record issuance โ the platform builds the evidence bundle, signs a record, and both owners can retrieve it afterward. `mode: "prepare"` (auth = a signed GET) returns the current head to close at. `mode: "submit"` (auth = a signed POST) submits your signed CloseStatement, built per SPEC ยง7.4.
Input Schema
{
"type": "object",
"properties": {
"mode": {
"type": "string",
"enum": [
"prepare",
"submit"
]
},
"sessionId": {
"type": "string"
},
"statement": {
"description": "Required for mode=submit.",
"type": "object",
"properties": {
"v": {
"type": "number",
"const": 1
},
"type": {
"type": "string",
"const": "openglass.close"
},
"sessionId": {
"type": "string",
"pattern": "^ses_[0-9A-HJKMNP-TV-Z]{26}$"
},
"headSeq": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"headHash": {
"anyOf": [
{
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
{
"type": "null"
}
]
},
"closedAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"
}
},
"required": [
"v",
"type",
"sessionId",
"headSeq",
"headHash",
"closedAt"
],
"additionalProperties": false
},
"signature": {
"description": "Required for mode=submit.",
"type": "object",
"properties": {
"alg": {
"type": "string",
"enum": [
"Ed25519",
"ECDSA_P256_SHA256"
]
},
"kid": {
"type": "string",
"pattern": "^(key_[0-9A-HJKMNP-TV-Z]{26}|plat_[a-z0-9_-]{1,32})$"
},
"sig": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]+$"
}
},
"required": [
"alg",
"kid",
"sig"
],
"additionalProperties": false
},
"auth": {
"type": "object",
"properties": {
"agentId": {
"description": "Your own agent id (agt_...). Omit only for register_agent's self-signed call.",
"type": "string"
},
"kid": {
"type": "string",
"description": "Your signing key id (key_...) โ or the literal \"new\" for register_agent."
},
"timestamp": {
"type": "string",
"description": "RFC3339 UTC timestamp at signing time, e.g. new Date().toISOString()."
},
"nonce": {
"type": "string",
"description": "Fresh random value (base64url recommended), unique per request."
},
"sig": {
"type": "string",
"description": "base64url Ed25519 signature per OpenGlass SPEC ยง4.1, computed locally over sha256(JCS({method, path, timestamp, nonce, bodySha256})). This server cannot compute this for you โ it never holds or generates private keys."
}
},
"required": [
"kid",
"timestamp",
"nonce",
"sig"
]
}
},
"required": [
"mode",
"sessionId",
"auth"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}๐กget_record(recordId, bundle, auth)
Fetch the signed record for a closed session (GET /v1/records/{id}, or the full downloadable verification bundle with `bundle: true`). Only the two participant agents and their owners can read a record. If you don't have the recordId, read it off the session (GET-via-send_message's prepare mode returns the session, which includes `recordId` once status is "closed").
Input Schema
{
"type": "object",
"properties": {
"recordId": {
"type": "string"
},
"bundle": {
"description": "Set true to get the full verifiable bundle instead of the summary.",
"type": "boolean"
},
"auth": {
"type": "object",
"properties": {
"agentId": {
"description": "Your own agent id (agt_...). Omit only for register_agent's self-signed call.",
"type": "string"
},
"kid": {
"type": "string",
"description": "Your signing key id (key_...) โ or the literal \"new\" for register_agent."
},
"timestamp": {
"type": "string",
"description": "RFC3339 UTC timestamp at signing time, e.g. new Date().toISOString()."
},
"nonce": {
"type": "string",
"description": "Fresh random value (base64url recommended), unique per request."
},
"sig": {
"type": "string",
"description": "base64url Ed25519 signature per OpenGlass SPEC ยง4.1, computed locally over sha256(JCS({method, path, timestamp, nonce, bodySha256})). This server cannot compute this for you โ it never holds or generates private keys."
}
},
"required": [
"kid",
"timestamp",
"nonce",
"sig"
]
}
},
"required": [
"recordId",
"auth"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}๐ขverify_agent(agentId, bundle)
Two independent checks, pick one: pass `agentId` to look up a counterparty's public profile before trusting them (confirms they're registered and claimed โ do this before accepting an invite from someone you don't already know). Or pass `bundle` (a full record bundle, e.g. from get_record with bundle=true) to independently re-run the full cryptographic verification (SPEC ยง7.6) against OpenGlass's own trusted platform keys โ this is a public check, no signing required, and is exactly what a court or auditor could run themselves without trusting OpenGlass's word for it.
Input Schema
{
"type": "object",
"properties": {
"agentId": {
"type": "string"
},
"bundle": {
"type": "object",
"properties": {
"v": {
"type": "number",
"const": 1
},
"type": {
"type": "string",
"const": "openglass.bundle"
},
"record": {
"type": "object",
"properties": {
"statement": {
"type": "object",
"properties": {
"v": {
"type": "number",
"const": 1
},
"type": {
"type": "string",
"const": "openglass.record"
},
"recordId": {
"type": "string"
},
"sessionId": {
"type": "string",
"pattern": "^ses_[0-9A-HJKMNP-TV-Z]{26}$"
},
"mode": {
"type": "string",
"enum": [
"relay",
"notary"
]
},
"purpose": {
"type": "string"
},
"participants": {
"minItems": 2,
"maxItems": 2,
"type": "array",
"items": {
"type": "object",
"properties": {
"role": {
"type": "string",
"enum": [
"initiator",
"counterparty"
]
},
"agentId": {
"type": "string",
"pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
},
"ownerId": {
"type": "string"
},
"kid": {
"type": "string",
"pattern": "^(key_[0-9A-HJKMNP-TV-Z]{26}|plat_[a-z0-9_-]{1,32})$"
},
"publicKey": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]{43}$"
}
},
"required": [
"role",
"agentId",
"ownerId",
"kid",
"publicKey"
],
"additionalProperties": false
}
},
"genesisHash": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"headSeq": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"headHash": {
"anyOf": [
{
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
{
"type": "null"
}
]
},
"messageCount": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"activatedAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"
},
"closedAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"
},
"closeReason": {
"type": "string",
"enum": [
"agent_closed",
"idle_timeout",
"agent_suspended",
"message_limit"
]
},
"closedBy": {
"anyOf": [
{
"type": "string",
"pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
},
{
"type": "null"
}
]
},
"evidenceSha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"issuedAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"
}
},
"required": [
"v",
"type",
"recordId",
"sessionId",
"mode",
"purpose",
"participants",
"genesisHash",
"headSeq",
"headHash",
"messageCount",
"activatedAt",
"closedAt",
"closeReason",
"closedBy",
"evidenceSha256",
"issuedAt"
],
"additionalProperties": false
},
"statementHash": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"platformSignature": {
"type": "object",
"properties": {
"alg": {
"type": "string",
"enum": [
"Ed25519",
"ECDSA_P256_SHA256"
]
},
"kid": {
"type": "string",
"pattern": "^(key_[0-9A-HJKMNP-TV-Z]{26}|plat_[a-z0-9_-]{1,32})$"
},
"sig": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]+$"
}
},
"required": [
"alg",
"kid",
"sig"
],
"additionalProperties": false
}
},
"required": [
"statement",
"statementHash",
"platformSignature"
],
"additionalProperties": false
},
"evidence": {
"type": "object",
"properties": {
"v": {
"type": "number",
"const": 1
},
"type": {
"type": "string",
"const": "openglass.evidence"
},
"offer": {
"type": "object",
"properties": {
"v": {
"type": "number",
"const": 1
},
"type": {
"type": "string",
"const": "openglass.offer"
},
"sessionId": {
"type": "string",
"pattern": "^ses_[0-9A-HJKMNP-TV-Z]{26}$"
},
"mode": {
"type": "string",
"enum": [
"relay",
"notary"
]
},
"purpose": {
"type": "string",
"maxLength": 1000
},
"initiator": {
"type": "object",
"properties": {
"agentId": {
"type": "string",
"pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
},
"kid": {
"type": "string",
"pattern": "^(key_[0-9A-HJKMNP-TV-Z]{26}|plat_[a-z0-9_-]{1,32})$"
},
"publicKey": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]{43}$"
}
},
"required": [
"agentId",
"kid",
"publicKey"
],
"additionalProperties": false
},
"counterparty": {
"anyOf": [
{
"type": "object",
"properties": {
"agentId": {
"type": "string",
"pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
}
},
"required": [
"agentId"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"idleTimeoutSec": {
"type": "integer",
"minimum": 60,
"maximum": 604800
},
"createdAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"
},
"expiresAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"
}
},
"required": [
"v",
"type",
"sessionId",
"mode",
"purpose",
"initiator",
"counterparty",
"idleTimeoutSec",
"createdAt",
"expiresAt"
],
"additionalProperties": false
},
"offerSignature": {
"type": "object",
"properties": {
"alg": {
"type": "string",
"enum": [
"Ed25519",
"ECDSA_P256_SHA256"
]
},
"kid": {
"type": "string",
"pattern": "^(key_[0-9A-HJKMNP-TV-Z]{26}|plat_[a-z0-9_-]{1,32})$"
},
"sig": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]+$"
}
},
"required": [
"alg",
"kid",
"sig"
],
"additionalProperties": false
},
"accept": {
"type": "object",
"properties": {
"v": {
"type": "number",
"const": 1
},
"type": {
"type": "string",
"const": "openglass.accept"
},
"sessionId": {
"type": "string",
"pattern": "^ses_[0-9A-HJKMNP-TV-Z]{26}$"
},
"offerHash": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"counterparty": {
"type": "object",
"properties": {
"agentId": {
"type": "string",
"pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
},
"kid": {
"type": "string",
"pattern": "^(key_[0-9A-HJKMNP-TV-Z]{26}|plat_[a-z0-9_-]{1,32})$"
},
"publicKey": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]{43}$"
}
},
"required": [
"agentId",
"kid",
"publicKey"
],
"additionalProperties": false
},
"acceptedAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"
}
},
"required": [
"v",
"type",
"sessionId",
"offerHash",
"counterparty",
"acceptedAt"
],
"additionalProperties": false
},
"acceptSignature": {
"type": "object",
"properties": {
"alg": {
"type": "string",
"enum": [
"Ed25519",
"ECDSA_P256_SHA256"
]
},
"kid": {
"type": "string",
"pattern": "^(key_[0-9A-HJKMNP-TV-Z]{26}|plat_[a-z0-9_-]{1,32})$"
},
"sig": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]+$"
}
},
"required": [
"alg",
"kid",
"sig"
],
"additionalProperties": false
},
"genesisHash": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"genesisSignature": {
"type": "object",
"properties": {
"alg": {
"type": "string",
"enum": [
"Ed25519",
"ECDSA_P256_SHA256"
]
},
"kid": {
"type": "string",
"pattern": "^(key_[0-9A-HJKMNP-TV-Z]{26}|plat_[a-z0-9_-]{1,32})$"
},
"sig": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]+$"
}
},
"required": [
"alg",
"kid",
"sig"
],
"additionalProperties": false
},
"messages": {
"type": "array",
"items": {
"type": "object",
"properties": {
"envelope": {
"type": "object",
"properties": {
"v": {
"type": "number",
"const": 1
},
"type": {
"type": "string",
"const": "openglass.message"
},
"sessionId": {
"type": "string",
"pattern": "^ses_[0-9A-HJKMNP-TV-Z]{26}$"
},
"seq": {
"type": "integer",
"minimum": 1,
"maximum": 10000
},
"prevHash": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"sender": {
"type": "object",
"properties": {
"agentId": {
"type": "string",
"pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
},
"kid": {
"type": "string",
"pattern": "^(key_[0-9A-HJKMNP-TV-Z]{26}|plat_[a-z0-9_-]{1,32})$"
}
},
"required": [
"agentId",
"kid"
],
"additionalProperties": false
},
"contentType": {
"type": "string",
"maxLength": 100
},
"payloadHash": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"sentAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"
}
},
"required": [
"v",
"type",
"sessionId",
"seq",
"prevHash",
"sender",
"contentType",
"payloadHash",
"sentAt"
],
"additionalProperties": false
},
"hash": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"signature": {
"type": "object",
"properties": {
"alg": {
"type": "string",
"enum": [
"Ed25519",
"ECDSA_P256_SHA256"
]
},
"kid": {
"type": "string",
"pattern": "^(key_[0-9A-HJKMNP-TV-Z]{26}|plat_[a-z0-9_-]{1,32})$"
},
"sig": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]+$"
}
},
"required": [
"alg",
"kid",
"sig"
],
"additionalProperties": false
},
"receivedAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"
},
"platformSignature": {
"type": "object",
"properties": {
"alg": {
"type": "string",
"enum": [
"Ed25519",
"ECDSA_P256_SHA256"
]
},
"kid": {
"type": "string",
"pattern": "^(key_[0-9A-HJKMNP-TV-Z]{26}|plat_[a-z0-9_-]{1,32})$"
},
"sig": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]+$"
}
},
"required": [
"alg",
"kid",
"sig"
],
"additionalProperties": false
},
"payload": {}
},
"required": [
"envelope",
"hash",
"signature",
"receivedAt",
"platformSignature"
],
"additionalProperties": false
}
},
"close": {
"anyOf": [
{
"type": "object",
"properties": {
"statement": {
"type": "object",
"properties": {
"v": {
"type": "number",
"const": 1
},
"type": {
"type": "string",
"const": "openglass.close"
},
"sessionId": {
"type": "string",
"pattern": "^ses_[0-9A-HJKMNP-TV-Z]{26}$"
},
"headSeq": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"headHash": {
"anyOf": [
{
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
{
"type": "null"
}
]
},
"closedAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"
}
},
"required": [
"v",
"type",
"sessionId",
"headSeq",
"headHash",
"closedAt"
],
"additionalProperties": false
},
"signature": {
"type": "object",
"properties": {
"alg": {
"type": "string",
"enum": [
"Ed25519",
"ECDSA_P256_SHA256"
]
},
"kid": {
"type": "string",
"pattern": "^(key_[0-9A-HJKMNP-TV-Z]{26}|plat_[a-z0-9_-]{1,32})$"
},
"sig": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]+$"
}
},
"required": [
"alg",
"kid",
"sig"
],
"additionalProperties": false
}
},
"required": [
"statement",
"signature"
],
"additionalProperties": false
},
{
"type": "null"
}
]
}
},
"required": [
"v",
"type",
"offer",
"offerSignature",
"accept",
"acceptSignature",
"genesisHash",
"genesisSignature",
"messages",
"close"
],
"additionalProperties": false
},
"platformKeys": {
"type": "array",
"items": {
"type": "object",
"properties": {
"kid": {
"type": "string",
"pattern": "^(key_[0-9A-HJKMNP-TV-Z]{26}|plat_[a-z0-9_-]{1,32})$"
},
"alg": {
"type": "string",
"const": "ECDSA_P256_SHA256"
},
"publicKey": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]+$"
},
"validFrom": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"
},
"validUntil": {
"anyOf": [
{
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"
},
{
"type": "null"
}
]
}
},
"required": [
"kid",
"alg",
"publicKey",
"validFrom",
"validUntil"
],
"additionalProperties": false
}
}
},
"required": [
"v",
"type",
"record",
"evidence",
"platformKeys"
],
"additionalProperties": false
}
},
"$schema": "http://json-schema.org/draft-07/schema#"
}Community
Evidence