Skip to main content
Glama
@proof-holdings/mcp-server

@proof-holdings/mcp-server

Official

create_delegation

Issue a signed Proof of Delegation token that authorizes a typed URL or purl artifact under your domain control proof, returning the token and its validity status.

Instructions

Create a delegation (Proof of Delegation): a control-proven domain authorizes a typed url/purl artifact and receives a publishable signed token. The attestation is that the domain's controller authorized this artifact — nothing more; it says nothing about the artifact or the business behind it. Each mint is a billable proof. A requested lifetime longer than the control proof's remainder is rejected, never truncated. The result carries the publishable token AND the DERIVED effective_status/is_valid — the same pair the list and get tools return, so the shape does not depend on which verb produced it.

ACCESS: needs a Proof account. Set PROOF_API_KEY and restart this server, then call this tool again. start_login does NOT open this tool.

Input Schema

NameRequiredDescriptionDefault
delegateYesThe typed artifact being authorized
expires_inNoLifetime in seconds (must not exceed the control proof's remainder)
control_proofYesPublic handle (ph_ctl_<32 hex>) of YOUR active domain control proof

Output Schema

NameRequiredDescriptionDefault
idNoMongoDB ObjectId
scopeNoDeprecated. Delegation schema 2.0 carries no scope; this array stays for the SDKs released before it: the scope a delegation issued before schema 2.0 was stored with, otherwise empty. Removed in the next major version.
tokenNoThe signed delegation JWT — the PUBLISHABLE artifact (publish it in your MCP server card under `_meta` → `holdings.proof/delegation`). Same key, algorithm and JWKS as proof tokens
statusNoThe owner's OWN record — whether they revoked this delegation themselves. Nothing else writes it: neither the control proof dying nor this delegation's own lifetime running out. Liveness is DERIVED and reported separately as `effective_status`. This stored field is also what `?status=` filters on
delegateNoTyped delegate identifier
is_validNoTrue only when `effective_status` is `active`. It is a restatement of that field, not a second opinion: expiry is decided once, inside the derivation above
issued_atNo
principalNoThe proven domain that authorized the delegate — derived from the control proof, never client input
created_atNo
expires_atNoNever later than the control proof's own expiry at issuance (effective expiry is min of the two)
revoked_atNo
environmentNo
control_proofNoThe control proof handle this delegation points down to
delegation_idNoStable public handle (`ph_dlg_<32 hex>`) — also the token's `sub`, and accepted by the proof status endpoint
revoked_reasonNo
effective_statusNoDERIVED liveness, computed at read time from BOTH clocks that govern a delegation: the control proof it stands on (cascade rule a — revoked, suspended or expired flows through) and its own `expires_at` (rule b — effective expiry is the earlier of the two). Either one running out reports `expired` here while the delegation's own `status` stays untouched. This is the field to render — `status` alone would show a live badge on a delegation every verifier already rejects

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed5 schema fields changedv1.7.2
    • removedInput schema / additionalProperties
      Removed value: -false
    • removedInput schema / properties / delegate / additionalProperties
      Removed value: -false
    • removedInput schema / properties / scope
      Removed value: -{
      -  "description": "1-32 capability scopes: lowercase kebab-case tokens, at most 64 characters each (e.g. send-email). NOT API scopes — an API-style resource:action such as payments:read is rejected with invalid_scope.",
      -  "items": {
      -    "maxLength": 64,
      -    "minLength": 1,
      -    "type": "string"
      -  },
      -  "maxItems": 32,
      -  "minItems": 1,
      -  "type": "array"
      -}
    • changedInput schema / required
      Previous value: -[
      -  "control_proof",
      -  "delegate",
      -  "scope"
      -]New value: +[
      +  "control_proof",
      +  "delegate"
      +]
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "http://json-schema.org/draft-07/schema#",
      +  "additionalProperties": {},
      +  "properties": {
      +    "control_proof": {
      +      "description": "The control proof handle this delegation points down to"
      +    },
      +    "created_at": {},
      +    "delegate": {
      +      "description": "Typed delegate identifier"
      +    },
      +    "delegation_id": {
      +      "description": "Stable public handle (`ph_dlg_<32 hex>`) — also the token's `sub`, and accepted by the proof status endpoint"
      +    },
      +    "effective_status": {
      +      "description": "DERIVED liveness, computed at read time from BOTH clocks that govern a delegation: the control proof it stands on (cascade rule a — revoked, suspended or expired flows through) and its own `expires_at` (rule b — effective expiry is the earlier of the two). Either one running out reports `expired` here while the delegation's own `status` stays untouched. This is the field to render — `status` alone would show a live badge on a delegation every verifier already rejects"
      +    },
      +    "environment": {},
      +    "expires_at": {
      +      "description": "Never later than the control proof's own expiry at issuance (effective expiry is min of the two)"
      +    },
      +    "id": {
      +      "description": "MongoDB ObjectId"
      +    },
      +    "is_valid": {
      +      "description": "True only when `effective_status` is `active`. It is a restatement of that field, not a second opinion: expiry is decided once, inside the derivation above"
      +    },
      +    "issued_at": {},
      +    "principal": {
      +      "description": "The proven domain that authorized the delegate — derived from the control proof, never client input"
      +    },
      +    "revoked_at": {},
      +    "revoked_reason": {},
      +    "scope": {
      +      "description": "Deprecated. Delegation schema 2.0 carries no scope; this array stays for the SDKs released before it: the scope a delegation issued before schema 2.0 was stored with, otherwise empty. Removed in the next major version."
      +    },
      +    "status": {
      +      "description": "The owner's OWN record — whether they revoked this delegation themselves. Nothing else writes it: neither the control proof dying nor this delegation's own lifetime running out. Liveness is DERIVED and reported separately as `effective_status`. This stored field is also what `?status=` filters on"
      +    },
      +    "token": {
      +      "description": "The signed delegation JWT — the PUBLISHABLE artifact (publish it in your MCP server card under `_meta` → `holdings.proof/delegation`). Same key, algorithm and JWKS as proof tokens"
      +    }
      +  },
      +  "type": "object"
      +}
  2. First observedv1.1.0

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial behavior beyond the annotations: each mint is billable, an over-long expires_in is rejected rather than silently truncated, and the response carries derived effective_status/is_valid so it matches list/get output. Auth setup is spelled out at the environment level. What is missing is any note on reversibility/idempotency — whether re-minting the same delegate creates a duplicate billable proof — which matters for a non-destructive-but-metered write.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the definition, then constraints, then billing, then access — a sensible order with no filler. It is somewhat dense and the closing clause ('so the shape does not depend on which verb produced it') could be trimmed, but every sentence conveys operational information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a nested-object, three-parameter write with an output schema, the description covers the domain concept, the failure mode, the billing implication, and the credential prerequisite. Since an output schema exists, it is not obligated to explain return values, yet it tells the agent enough about the returned pair to plan downstream calls.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% so the baseline is 3, and the description earns an extra point by adding real semantics: expires_in is bounded by the control proof's remaining lifetime and fails rather than truncates, and control_proof must be the caller's own active domain proof, not any handle. It does not clarify server-side canonicalization effects on the delegate value beyond what the schema already says.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Create a delegation (Proof of Delegation)') and then defines the exact semantics of the artifact: a control-proven domain authorizes a typed url/purl and receives a publishable signed token. It also scopes what the attestation does NOT claim ('nothing more; it says nothing about the artifact or the business behind it'), which separates it cleanly from siblings like create_authorization, verify_delegation, and get_delegation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete preconditions and an explicit exclusion: needs a Proof account, PROOF_API_KEY must be set and the server restarted, and 'start_login does NOT open this tool' — a genuinely useful anti-pattern warning given start_login exists as a sibling. It stops short of naming the alternative verb to call when you only want to read or verify an existing delegation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Deploy Server

Other Tools