AgentTrust
MCP Server for Agent Reputation & Trust Scoring
Open source Open in the app JSON README (API)
About
MCP Server for Agent Reputation & Trust Scoring
Details
- Kind
- MCP servers
- Topic
- No topic detected
- Publisher
- raditotev
- Origin
- official
- Category
- ferramentas
- Transport
- local
- Version
- 0.1.5
- Last push
- 2026-03-22T16:24:16Z
- Repository state
- ativo
- Language
- Python
- License
- NOASSERTION
- Added
- 2026-08-29 04:01:16
- Updated
- 2026-08-29 04:01:16
- Origin id
io.github.raditotev/agent-trust
README
# AgentTrust
Reputation and trust scoring service for AI agents, exposed entirely as an [MCP](https://modelcontextprotocol.io/) server. Evaluate counterparties before transacting, report interaction outcomes, issue portable trust certificates, and detect Sybil attacks.
<!-- mcp-name: io.github.raditotev/agent-trust -->
## Table of Contents
- [Quickstart](#quickstart)
- [Connecting to the MCP Server](#connecting-to-the-mcp-server)
- [Authentication](#authentication)
- [Tools Reference](#tools-reference)
- [Discovery](#discovery)
- [Agent Management](#agent-management)
- [`register_agent`](#register_agent)
- [`generate_agent_token`](#generate_agent_token)
- [`whoami`](#whoami)
- [`agent_status`](#agent_status)
- [`get_agent_profile`](#get_agent_profile)
- [`search_agents`](#search_agents)
- [`link_agentauth`](#link_agentauth)
- [`verify_link_proof`](#verify_link_proof)
- [Trust Scoring](#trust-scoring)
- [Interaction Reporting](#interaction-reporting)
- [Disputes](#disputes)
- [Attestations](#attestations)
- [`issue_attestation`](#issue_attestation)
- [`list_my_attestations`](#list_my_attestations)
- [`verify_attestation`](#verify_attestation)
- [Sybil Detection](#sybil-detection)
- [Resources](#resources)
- [Prompts](#prompts)
- [Score Types](#score-types)
- [Rate Limits](#rate-limits)
- [Self-Hosting](#self-hosting)
---
## Quickstart
### 1. Connect to the MCP server
Add AgentTrust to your MCP client configuration:
```json
{
"mcpServers": {
"agent-trust": {
"url": "https://agent-trust.radi.pro/mcp"
}
}
}
```
Or for local development via stdio:
```json
{
"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:
```json
{
"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:
```json
{
"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](https://agentauth.radi.pro) 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)
```
#### `link_agentauth`
**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:
```json
{
"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`.
#### `verify_link_proof`
**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:
```json
{
"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:
```json
{
"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:
```json
{
"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:
```json
{
"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:
```json
{
"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:
```json
{
"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:
```json
{
"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:
```json
{
"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:
```json
{
"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](https://docs.astral.sh/uv/) package manager
### Setup
```bash
# 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:
```bash
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
```bash
# 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:
```bash
docker compose up -d
```
This starts PostgreSQL, Redis, the MCP server (port 8140), the background worker, Prometheus (port 9090), and Grafana (port 3001).
### Tests
```bash
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
```