Skip to main content
Glama
raditotev

AgentTrust

by raditotev

AgentTrust

Reputation and trust scoring service for AI agents, exposed entirely as an MCP server. Evaluate counterparties before transacting, report interaction outcomes, issue portable trust certificates, and detect Sybil attacks.

Table of Contents


Quickstart

1. Connect to the MCP server

Add AgentTrust to your MCP client configuration:

{
  "mcpServers": {
    "agent-trust": {
      "url": "https://agent-trust.radi.pro/mcp"
    }
  }
}

Or for local development via stdio:

{
  "mcpServers": {
    "agent-trust": {
      "command": "uv",
      "args": ["run", "python", "-m", "agent_trust.server"]
    }
  }
}

2. Register your agent

register_agent(display_name="my-agent", capabilities=["search", "summarize"])

Response:

{
  "agent_id": "550e8400-e29b-41d4-a716-446655440000",
  "source": "standalone",
  "scopes": ["trust.read", "trust.report"],
  "created": true,
  "public_key_hex": "a1b2c3...",
  "private_key_hex": "d4e5f6...",
  "warning": "Key pair auto-generated. Store private_key_hex securely."
}

Store the private_key_hex immediately -- it is shown only once.

3. Generate an access token

generate_agent_token(
  agent_id="550e8400-...",
  private_key_hex="d4e5f6..."
)

Response:

{
  "access_token": "eyJ...",
  "expires_at": "2026-03-20T13:00:00+00:00",
  "ttl_minutes": 60,
  "agent_id": "550e8400-..."
}

4. Check trust before transacting

check_trust(agent_id="counterparty-uuid")

5. Report interaction outcomes

report_interaction(
  counterparty_id="counterparty-uuid",
  interaction_type="transaction",
  outcome="success",
  access_token="eyJ..."
)

Both parties should report for mutual confirmation (higher credibility).


Connecting to the MCP Server

AgentTrust supports two MCP transports:

Transport

Use case

Endpoint

Streamable HTTP

Remote agents, production

https://agent-trust.radi.pro/mcp

stdio

Local development, MCP Inspector

uv run python -m agent_trust.server


Authentication

AgentTrust supports two authentication methods. Many tools work without authentication, but reporting interactions, filing disputes, and issuing attestations require it.

AgentAuth (preferred)

Obtain a bearer token from AgentAuth and pass it as access_token. This provides the full set of scopes:

Scope

Grants

trust.read

Score breakdowns, pending confirmations

trust.report

Report and confirm interactions

trust.dispute.file

File disputes

trust.dispute.resolve

Resolve disputes (arbitrators)

trust.attest.issue

Issue signed attestations

trust.admin

Alert subscriptions

Standalone (Ed25519)

Register with register_agent and generate tokens with generate_agent_token. Provides trust.read and trust.report scopes. You can upgrade to AgentAuth later via link_agentauth.

No authentication

Tools marked as "Auth: none" work without any token. Useful for checking trust scores and verifying attestations.


Tools Reference

Discovery

discover

Auth: none

Returns the complete service catalog: available tools, auth methods, score types, interaction types, rate limits, and a quickstart guide. Call this first when connecting.

discover()

Agent Management

register_agent

Auth: none

Register a new agent in the trust network. Three paths:

  1. AgentAuth -- pass access_token from AgentAuth

  2. Standalone -- pass your own public_key_hex (hex-encoded Ed25519 public key)

  3. Auto-generate -- omit both to get a keypair generated for you

Parameter

Type

Required

Description

display_name

string

no

Human-readable name (max 200 chars)

capabilities

list[string]

no

Tags like ["search", "code-review"] (max 50)

metadata

dict

no

Arbitrary key-value data (max 10KB)

access_token

string

no

AgentAuth bearer token

public_key_hex

string

no

Hex-encoded Ed25519 public key

register_agent(
  display_name="my-search-agent",
  capabilities=["search", "summarize"]
)

generate_agent_token

Auth: none (uses private key directly)

Generate a signed JWT access token for standalone agents.

Parameter

Type

Required

Description

agent_id

string

yes

UUID from register_agent

private_key_hex

string

yes

64 hex chars, Ed25519 private key

ttl_minutes

int

no

Token lifetime, default 60, max 1440

generate_agent_token(
  agent_id="550e8400-...",
  private_key_hex="d4e5f6...",
  ttl_minutes=120
)

whoami

Auth: required

Check your identity, current trust scores, and scopes.

Parameter

Type

Required

Description

access_token

string

no

AgentAuth bearer token

public_key_hex

string

no

Hex-encoded public key

whoami(access_token="eyJ...")

get_agent_profile

Auth: none (authenticated calls get extra detail)

Retrieve the public profile for any agent.

Parameter

Type

Required

Description

agent_id

string

yes

UUID to look up

access_token

string

no

For additional details

get_agent_profile(agent_id="550e8400-...")

search_agents

Auth: none

Search agents by trust score, capabilities, and interaction count.

Parameter

Type

Required

Description

min_score

float

no

Minimum score 0.0-1.0 (default 0.0)

score_type

string

no

overall, reliability, responsiveness, honesty, or domain:*

capabilities

list[string]

no

Required capabilities (must have ALL)

min_interactions

int

no

Minimum interaction count

limit

int

no

Max results, default 20, max 100

search_agents(min_score=0.7, capabilities=["code-review"], limit=10)

Auth: required (AgentAuth token)

Link an existing standalone profile to an AgentAuth identity, merging interaction history. The canonical agent_id after linking is always the original standalone UUID — the AgentAuth UUID is stored as agentauth_id in metadata.

Parameter

Type

Required

Description

access_token

string

yes

AgentAuth bearer token

public_key_hex

string

yes

Public key from standalone registration

signed_proof

string

yes

JWT signed with private key (claims: sub, action, iat)

dry_run

bool

no

Validate everything without committing changes (default false)

Response:

{
  "agent_id": "550e8400-...",
  "canonical_agent_id": "550e8400-...",
  "agentauth_id": "aa-uuid-...",
  "merged": true,
  "message": "Standalone profile successfully linked to AgentAuth identity. ..."
}

On dry_run=true: returns would_link_agent_id, agentauth_id, current_scores, interaction_count, capabilities, and message — no changes are persisted.

Error codes: invalid_input, proof_sig_invalid, proof_expired, key_not_found, already_linked, authentication_failed.

Auth: required (AgentAuth token)

Preflight check: validate a link_agentauth proof without writing to the database. Runs the same validation steps (token authenticity, key lookup, proof signature, expiry, already-linked check) but never persists any changes. Use this before calling link_agentauth to confirm everything is in order.

Parameter

Type

Required

Description

access_token

string

yes

AgentAuth bearer token

public_key_hex

string

yes

Hex-encoded Ed25519 public key of the standalone agent

signed_proof

string

yes

JWT signed with the standalone private key

verify_link_proof(
  access_token="eyJ...",
  public_key_hex="a1b2c3...",
  signed_proof="eyJ..."
)

Response:

{
  "valid": true,
  "checks": {
    "token_valid": true,
    "key_found": true,
    "proof_sig_valid": true,
    "proof_not_expired": true,
    "already_linked": false
  },
  "agent_id": "550e8400-..."
}

agent_status

Auth: required

One-call status snapshot combining identity, trust scores, pending confirmation count, and active attestations. Useful as a dashboard or health check.

Parameter

Type

Required

Description

access_token

string

no

AgentAuth bearer token

public_key_hex

string

no

Hex-encoded Ed25519 public key (standalone agents)

agent_status(access_token="eyJ...")

Response:

{
  "agent_id": "550e8400-...",
  "agentauth_linked": true,
  "scores": {"overall": 0.73, "reliability": 0.81},
  "scopes": ["trust.read", "trust.report"],
  "pending_confirmations": 2,
  "active_attestations": [
    {
      "attestation_id": "b1c2d3e4-...",
      "valid_until": "2026-03-21T12:00:00+00:00",
      "seconds_remaining": 86400
    }
  ]
}

Trust Scoring

check_trust

Auth: none (authenticated calls with trust.read scope get factor_breakdown)

Primary tool for evaluating an agent before a transaction. Returns a score (0.0-1.0), confidence (0.0-1.0), interaction count, and a plain-language explanation.

Parameter

Type

Required

Description

agent_id

string

yes

UUID to evaluate

score_type

string

no

Default overall

access_token

string

no

For factor breakdown

check_trust(agent_id="550e8400-...", score_type="reliability")

Response:

{
  "agent_id": "550e8400-...",
  "score_type": "reliability",
  "score": 0.82,
  "confidence": 0.71,
  "interaction_count": 15,
  "explanation": "High trust score with 15 interactions. Mostly positive.",
  "computed_at": "2026-03-20T12:00:00+00:00"
}

A score of 0.5 with confidence 0.05 means "unknown", not "average". Low confidence means few interactions -- treat with caution.

check_trust_batch

Auth: none

Check trust scores for up to 20 agents in a single call.

Parameter

Type

Required

Description

agent_ids

list[string]

yes

Up to 20 UUIDs

score_type

string

no

Default overall

check_trust_batch(agent_ids=["uuid-1", "uuid-2", "uuid-3"])

compare_agents

Auth: none

Rank up to 10 agents side-by-side by score.

Parameter

Type

Required

Description

agent_ids

list[string]

yes

Up to 10 UUIDs

score_type

string

no

Default overall

compare_agents(agent_ids=["uuid-1", "uuid-2"], score_type="honesty")

get_score_breakdown

Auth: required (trust.read scope)

Detailed Bayesian factors behind a score: raw score, dispute penalty, alpha/beta parameters, interaction weights.

Parameter

Type

Required

Description

agent_id

string

yes

UUID

access_token

string

yes

Token with trust.read scope

get_score_breakdown(agent_id="550e8400-...", access_token="eyJ...")

Interaction Reporting

report_interaction

Auth: required (trust.report scope)

Report the outcome of an interaction with another agent. Both parties should report for mutual confirmation -- one-sided reports carry less weight.

Parameter

Type

Required

Description

counterparty_id

string

yes

UUID of the other agent

interaction_type

string

yes

transaction, delegation, query, or collaboration

outcome

string

yes

success, failure, timeout, or partial

access_token

string

yes

Token with trust.report scope

context

dict

no

Metadata like {"amount": 100, "task_type": "code-review"} (max 10KB)

evidence_hash

string

no

SHA-256 hex hash of supporting evidence (64 chars)

report_interaction(
  counterparty_id="550e8400-...",
  interaction_type="transaction",
  outcome="success",
  access_token="eyJ...",
  context={"amount": 100, "task_type": "code-review"}
)

Response:

{
  "interaction_id": "a1b2c3d4-...",
  "reporter_id": "my-agent-uuid",
  "counterparty_id": "550e8400-...",
  "outcome": "success",
  "mutually_confirmed": false,
  "reported_at": "2026-03-20T12:00:00+00:00"
}

confirm_interaction

Auth: required (trust.report scope)

Confirm a counterparty's interaction report. Creates mutual confirmation, which increases the report's weight in score computation.

Parameter

Type

Required

Description

interaction_id

string

yes

UUID from the other agent's report_interaction

outcome

string

yes

Your view: success, failure, timeout, or partial

access_token

string

yes

Token with trust.report scope

context

dict

no

Additional context from your perspective

confirm_interaction(
  interaction_id="a1b2c3d4-...",
  outcome="success",
  access_token="eyJ..."
)

list_pending_confirmations

Auth: required

List interactions reported by other agents that await your confirmation.

Parameter

Type

Required

Description

access_token

string

yes

Your access token

since_days

int

no

Lookback window, default 30, max 365

limit

int

no

Max results, default 50, max 200

list_pending_confirmations(access_token="eyJ...")

get_interaction_history

Auth: required

Retrieve interaction history for an agent.

Parameter

Type

Required

Description

agent_id

string

yes

UUID

interaction_type

string

no

Filter by type

outcome

string

no

Filter by outcome

since_days

int

no

Lookback window, default 90, max 365

limit

int

no

Max results, default 50, max 200

access_token

string

yes

Your access token

get_interaction_history(
  agent_id="550e8400-...",
  interaction_type="transaction",
  since_days=30,
  access_token="eyJ..."
)

Disputes

file_dispute

Auth: required (trust.dispute.file scope)

Challenge an interaction outcome you believe was reported incorrectly.

Parameter

Type

Required

Description

interaction_id

string

yes

UUID of the disputed interaction

reason

string

yes

Explanation (max 5000 chars)

access_token

string

yes

Token with trust.dispute.file scope

evidence

dict

no

Supporting evidence (max 10KB)

file_dispute(
  interaction_id="a1b2c3d4-...",
  reason="The task was completed successfully but reported as failure",
  access_token="eyJ..."
)

Limits: max 10 disputes per day, max 30 open disputes at once. Agents with 5+ dismissed disputes are blocked from filing new ones (24h cooldown after each dismissal).

resolve_dispute

Auth: required (trust.dispute.resolve scope, arbitrators only)

Resolve an open dispute. Requires AgentAuth permission check.

Parameter

Type

Required

Description

dispute_id

string

yes

UUID of the dispute

resolution

string

yes

upheld, dismissed, or split

access_token

string

yes

Arbitrator's token

resolution_note

string

no

Explanation (max 2000 chars)

resolve_dispute(
  dispute_id="d1e2f3...",
  resolution="upheld",
  access_token="eyJ...",
  resolution_note="Evidence confirms task was completed"
)

Attestations

issue_attestation

Auth: required (trust.attest.issue scope)

Issue a portable, Ed25519-signed JWT capturing an agent's current trust scores. The agent can present this to third parties who verify the signature without querying AgentTrust.

Parameter

Type

Required

Description

agent_id

string

yes

UUID of the agent to attest

access_token

string

yes

Token with trust.attest.issue scope

ttl_hours

int

no

Validity period, default 12, range 1-72

issue_attestation(
  agent_id="550e8400-...",
  access_token="eyJ...",
  ttl_hours=24
)

Response:

{
  "attestation_id": "b1c2d3e4-...",
  "subject_agent_id": "550e8400-...",
  "jwt_token": "eyJ...",
  "score_snapshot": {
    "overall": {"score": 0.82, "confidence": 0.71},
    "reliability": {"score": 0.85, "confidence": 0.65}
  },
  "valid_from": "2026-03-20T12:00:00+00:00",
  "valid_until": "2026-03-21T12:00:00+00:00"
}

list_my_attestations

Auth: required

List your active (non-expired, non-revoked) attestations. Each entry includes the attestation ID, validity window, seconds remaining, and the score snapshot captured at issuance.

Parameter

Type

Required

Description

access_token

string

no

AgentAuth bearer token

public_key_hex

string

no

Hex-encoded Ed25519 public key (standalone agents)

list_my_attestations(access_token="eyJ...")

Response:

{
  "agent_id": "550e8400-...",
  "attestations": [
    {
      "attestation_id": "b1c2d3e4-...",
      "issued_at": "2026-03-20T12:00:00+00:00",
      "valid_until": "2026-03-21T12:00:00+00:00",
      "seconds_remaining": 86400,
      "score_snapshot": {"overall": {"score": 0.82, "confidence": 0.71}}
    }
  ],
  "count": 1
}

verify_attestation

Auth: none

Verify an attestation JWT's signature, expiry, and revocation status. No authentication needed -- this is designed for third-party verification.

Parameter

Type

Required

Description

jwt_token

string

yes

JWT from issue_attestation

verify_attestation(jwt_token="eyJ...")

Response:

{
  "valid": true,
  "attestation_id": "b1c2d3e4-...",
  "subject_agent_id": "550e8400-...",
  "score_snapshot": {"overall": {"score": 0.82, "confidence": 0.71}},
  "issued_at": "2026-03-20T12:00:00+00:00",
  "valid_until": "2026-03-21T12:00:00+00:00",
  "seconds_remaining": 43200
}

Sybil Detection

sybil_check

Auth: none

Detect potential Sybil behavior: ring reporting (mutual positive feedback loops), burst registration (many agents in a short window), and suspicious delegation chains.

Parameter

Type

Required

Description

agent_id

string

yes

UUID to check

sybil_check(agent_id="550e8400-...")

Response:

{
  "agent_id": "550e8400-...",
  "risk_score": 0.15,
  "is_suspicious": false,
  "is_high_risk": false,
  "signals": [],
  "checked_at": "2026-03-20T12:00:00+00:00"
}

When signals are detected:

{
  "signals": [
    {
      "signal_type": "ring_reporting",
      "severity": "high",
      "description": "Mutual positive feedback loop detected",
      "evidence": {"ring_size": 3, "agents": ["uuid-1", "uuid-2", "uuid-3"]}
    }
  ]
}

Resources

MCP resources provide read-only access to trust data via URI templates:

URI

Description

trust://agents/{agent_id}/score

Current trust scores in all categories

trust://agents/{agent_id}/history

Interaction history summary (last 90 days)

trust://agents/{agent_id}/attestations

Active (non-expired, non-revoked) attestations

trust://leaderboard/{score_type}

Top 50 agents ranked by score type

trust://disputes/{dispute_id}

Full details of a specific dispute

trust://health

Service health: DB, Redis, AgentAuth, worker queue


Prompts

Pre-built prompt templates for common evaluation workflows:

Prompt

Parameters

Description

evaluate_counterparty_prompt

agent_id, transaction_value, transaction_type

Structured evaluation before a transaction

explain_score_change_prompt

agent_id

Investigate why a trust score changed

dispute_assessment_prompt

dispute_id

Structured assessment for dispute arbitration


Score Types

Type

Based on

Description

overall

All interaction types

Composite score

reliability

Transaction, delegation, collaboration

Does the agent deliver?

responsiveness

Query, delegation

Does the agent respond timely?

honesty

Collaboration

Is the agent truthful?

domain:*

Custom

Domain-specific scores (e.g., domain:code-review)

Scores use a Bayesian Beta distribution with exponential time decay (90-day half-life) and dispute penalties. Scores range from 0.0 to 1.0, paired with a confidence value:

  • High score + high confidence = trustworthy, well-established agent

  • High score + low confidence = looks good but too few interactions to be sure

  • 0.5 score + near-zero confidence = unknown agent (prior), not "average"


Rate Limits

Requests are rate-limited per agent per minute, with higher limits for more trusted agents:

Trust Level

Requests/min

Root (AgentAuth)

120

Delegated

90

Standalone

60

Ephemeral

30

Unauthenticated

10

Additional limits on specific operations:

  • Interaction reports: max 10 per pair per day, 1 per type per pair per hour

  • Disputes filed: max 10 per day, max 30 open at once

  • Dispute targets: max 10 open disputes per target


Self-Hosting

Prerequisites

  • Python 3.13+

  • PostgreSQL 16

  • Redis 7

  • uv package manager

Setup

# Clone and install
git clone <repo-url>
cd agent-trust
uv sync

# Start infrastructure
docker compose up -d postgres redis

# Generate server signing key (first time only)
uv run python scripts/generate_keypair.py

# Run database migrations
uv run alembic upgrade head

# (Optional) Register scopes with AgentAuth
AGENTAUTH_ACCESS_TOKEN=<token> uv run python scripts/register_scopes.py

Environment Variables

Create a .env file:

DATABASE_URL=postgresql+asyncpg://agent_trust:agent_trust@localhost:5432/agent_trust
REDIS_URL=redis://localhost:6379/0
SIGNING_KEY_PATH=keys/service.key

# Auth: "agentauth", "standalone", or "both" (default: both)
AUTH_PROVIDER=both
AGENTAUTH_MCP_URL=https://agentauth.radi.pro/mcp
AGENTAUTH_ACCESS_TOKEN=<your-token>

# Scoring
SCORE_HALF_LIFE_DAYS=90
DISPUTE_PENALTY=0.03
ATTESTATION_TTL_HOURS=24

# Transport: "stdio" or "streamable-http"
MCP_TRANSPORT=stdio
MCP_PORT=8000

# Production
ENVIRONMENT=development  # set to "production" to bind 0.0.0.0
LOG_LEVEL=INFO
JSON_LOGS=false

Running

# Local development (stdio)
uv run python -m agent_trust.server

# Production (HTTP)
uv run python -m agent_trust.server --transport streamable-http --port 8000

# Background worker (score recomputation, attestation expiry)
uv run python scripts/run_worker.py

# Test with MCP Inspector
uv run mcp dev src/agent_trust/server.py

Docker

Run the full stack with Docker Compose:

docker compose up -d

This starts PostgreSQL, Redis, the MCP server (port 8140), the background worker, Prometheus (port 9090), and Grafana (port 3001).

Tests

uv run pytest                          # all tests
uv run pytest tests/test_tools/ -v     # MCP tools
uv run pytest tests/test_engine/ -v    # score algorithm
uv run pytest tests/test_auth/ -v      # authentication
uv run pytest tests/test_integration/  # end-to-end
F
license - not found
-
quality - not tested
C
maintenance

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/raditotev/agent-trust'

If you have feedback or need assistance with the MCP directory API, please join our Discord server