Skip to content

Repository files navigation

English | 中文

peerclaw-server

License: BSL 1.1

AI Agent Identity & Trust Platform — verifiable identity, reputation scoring, endpoint verification, and cross-protocol bridging.

peerclaw-server is the trust infrastructure for AI agents. It provides cryptographically verifiable identities, EWMA-based reputation scoring from real interactions, endpoint verification, and a public agent directory — all built on top of a full protocol gateway with registry, signaling relay, and protocol bridges (A2A, MCP, ACP). This infrastructure serves as the foundation for PeerClaw's Agent Platform, where any Agent can become a discoverable, trustable, invocable service.

Start it with one command. No external dependencies required.

./peerclawd
# → PeerClaw gateway started http=:8080

What It Does

CapabilityWhat it means for you
Web DashboardBuilt-in web UI with Agent Platform, Provider Console, and Admin Dashboard. Embedded in the binary.
Reputation EngineEWMA scoring from real events (registration, heartbeat, bridge, verification). Trust that's earned, not claimed.
Endpoint VerificationChallenge-response proof that an agent controls its URL. Ed25519 signed.
Public DirectoryBrowse agents by reputation, capability, category, verification status. No auth required.
Agent PlatformUser accounts, agent registration wizard, provider console, invocation analytics.
Playground & InvokeProtocol-agnostic invocation endpoint with SSE streaming. Rate-limited anonymous access.
Reviews & CommunityStar ratings, text reviews, Trusted badges, abuse reporting.
Admin DashboardUser management, agent moderation, report review, category management, global analytics, invocation logs.
Agent RegistryAgents register their capabilities. Anyone can discover them. Like DNS for agents.
Protocol BridgingAn MCP agent can call an A2A agent. The gateway translates automatically.
Signaling RelayAgents establish direct P2P connections via WebSocket signaling.
Auth & SecurityEd25519 signature auth, API keys, JWT user auth, constant-time token verification.
ObservabilityOpenTelemetry traces + metrics, structured logging, audit log.
Horizontal ScalingRedis Pub/Sub for multi-node signaling. PostgreSQL for shared storage.

Getting Started

Build from Source

git clone https://github.com/peerclaw/peerclaw-server.git
cd peerclaw-server
make build
./bin/peerclawd

Docker Compose

docker-compose up -d
# → peerclaw (port 8080) + redis (port 6379)

Docker

docker build -t peerclaw-server:latest .
docker run -p 8080:8080 peerclaw-server:latest

Systemd (Linux Server)

make install
# → installs binary, config, systemd unit, creates peerclaw user
sudo nano /etc/peerclaw/peerclaw.env # set JWT_SECRET
sudo systemctl start peerclawd

See deploy/systemd/ for details.

Verify It's Running

curl http://localhost:8080/api/v1/health
# {"status":"ok","components":{"database":"ok","signaling":"ok"}}

Open http://localhost:8080 in your browser to access the web dashboard.

Architecture

 Incoming requests
│
┌──────────▼──────────┐
│ Middleware │
│ CORS → Auth → │
│ RateLimit → Trace │
└──────────┬──────────┘
│
┌────────────────────┼────────────────────┐
▼ ▼ ▼
┌─────────────┐ ┌──────────────┐ ┌──────────────────┐
│ Registry │ │ Signaling │ │ Bridge Manager │
│ │ │ Hub │ │ │
│ POST/GET │ │ WebSocket │ │ ┌────┬────┬────┐ │
│ /api/v1/ │ │ relay for │ │ │A2A │MCP │ACP │ │
│ agents │ │ WebRTC │ │ └────┴────┴────┘ │
└──────┬──────┘ └──────┬──────┘ └────────┬─────────┘
│ │ │
┌──────▼──────┐ ┌──────▼──────┐ ┌───────▼─────────┐
│ SQLite or │ │ Redis or │ │ Route Engine │
│ PostgreSQL │ │ Local │ │ capability + │
│ │ │ Broker │ │ protocol match │
└─────────────┘ └─────────────┘ └─────────────────┘

Internal Modules

ModulePathPurpose
HTTP Serverinternal/server/Routes, middleware chain, request handling
Authinternal/server/auth.goBearer token + Ed25519 signature authentication
Validationinternal/server/validation.goInput validation for registration and heartbeat
Registryinternal/registry/Agent CRUD, capability indexing (SQLite/PostgreSQL)
Signalinginternal/signaling/WebSocket hub, connection auth, rate limiting, contacts whitelist
Contactsinternal/contacts/Mutual contact management, whitelist enforcement for signaling
Bridgeinternal/bridge/Protocol adapters (A2A, MCP, ACP) + negotiator
Routerinternal/router/Capability-based message routing
Federationinternal/federation/Multi-server signal relay, DNS SRV discovery
Reputationinternal/reputation/EWMA reputation engine, event recording, score computation
Verificationinternal/verification/Challenge-response endpoint verification (SSRF-safe)
User Authinternal/userauth/User registration, JWT sessions, API key management
Invocationinternal/invocation/Invoke recording, analytics, time-series stats
Reviewinternal/review/Reviews, ratings, categories, abuse reports
Securityinternal/security/URL validation (SSRF protection), safe HTTP client
Configinternal/config/YAML config with ${ENV_VAR} secret substitution
Observabilityinternal/observability/OpenTelemetry provider setup
Auditinternal/audit/Security event logging
Identityinternal/identity/Verifier for API keys, Ed25519 signatures, user context
Contact Requestsinternal/contacts/Contact request send/approve/reject with status tracking
Claim Tokensinternal/claimtoken/Token-based agent pairing for one-prompt registration
Notificationsinternal/notification/Real-time WebSocket + email notification system
Access Controlinternal/useracl/User access request workflow for private agents
Version Checkinternal/versioncheck/SDK upgrade notification service

Configuration

All settings via YAML. Every field has a sensible default — you can start with zero config.

server:
http_addr: ":8080"cors_origins: [] # e.g. ["https://dashboard.example.com"]auth:
required: false # Set true in productiondatabase:
driver: "sqlite"# "sqlite" or "postgres"dsn: "peerclaw.db"redis:
addr: "localhost:6379"password: "${REDIS_PASSWORD}"# Env var substitution supporteddb: 0signaling:
enabled: trueturn:
urls: ["turn:turn.example.com:3478"]username: "user"credential: "${TURN_CREDENTIAL}"bridge:
a2a:
enabled: truemcp:
enabled: trueacp:
enabled: truefederation:
enabled: falsenode_name: "node-1"auth_token: "${FEDERATION_TOKEN}"# Required when federation is enabledpeers:
- name: "node-2"address: "https://node2.example.com"token: "${FEDERATION_PEER_TOKEN}"rate_limit:
enabled: truerequests_per_sec: 100burst_size: 200max_connections: 1000observability:
enabled: falseotlp_endpoint: "localhost:4317"service_name: "peerclaw-gateway"traces_sampling: 0.1audit_log:
enabled: trueoutput: "stdout"# or "file:/var/log/peerclaw-audit.log"user_auth:
enabled: truejwt_secret: "${JWT_SECRET}"# Required in productionaccess_ttl: "15m"refresh_ttl: "168h"bcrypt_cost: 12logging:
level: "info"format: "text"# "text" or "json"

Environment Variable Substitution

Sensitive fields support ${ENV_VAR} syntax:

redis:
password: "${REDIS_PASSWORD}"# Reads from REDIS_PASSWORD env var

Applies to: redis.password, database.dsn, signaling.turn.credential, federation.auth_token, user_auth.jwt_secret, and federation peer tokens.

REST API

Agent Management

MethodPathDescription
POST/api/v1/agentsRegister an agent
GET/api/v1/agentsList agents (filter: protocol, capability, status)
GET/api/v1/agents/{id}Get agent details
DELETE/api/v1/agents/{id}Deregister an agent (owner only)
POST/api/v1/agents/{id}/heartbeatReport heartbeat (owner only)
POST/api/v1/agents/{id}/verifyInitiate endpoint verification (owner only)

Public Directory (no auth required)

MethodPathDescription
GET/api/v1/directoryBrowse agent directory (filter: capability, protocol, status, verified, min_score, search, category; sort: reputation, name, registered_at)
GET/api/v1/directory/{id}Public agent profile (with Trusted badge, review summary)
GET/api/v1/directory/{id}/reputationReputation event history
GET/api/v1/directory/{id}/reviewsList reviews for an agent
GET/api/v1/directory/{id}/reviews/summaryReview summary (average rating, distribution)
GET/api/v1/categoriesList all categories

User Authentication

MethodPathAuthDescription
POST/api/v1/auth/registerPublicRegister a new user account
POST/api/v1/auth/loginPublicLogin, returns JWT token pair
POST/api/v1/auth/refreshPublicRefresh access token
POST/api/v1/auth/logoutPublicInvalidate refresh token
GET/api/v1/auth/meJWTGet current user profile
PUT/api/v1/auth/meJWTUpdate user profile
POST/api/v1/auth/api-keysJWTGenerate API key
GET/api/v1/auth/api-keysJWTList API keys
DELETE/api/v1/auth/api-keys/{key_id}JWTRevoke API key

Claim Tokens

MethodPathAuthDescription
POST/api/v1/claim-tokensJWTGenerate a new claim token
GET/api/v1/claim-tokensJWTList generated claim tokens
POST/api/v1/agents/claimPublicClaim an agent with a token

Agent Invocation

MethodPathAuthDescription
POST/api/v1/invoke/{agent_id}OptionalInvoke an agent (anonymous: 10/h rate limit, authenticated: 100/h)
GET/api/v1/invocationsJWTUser's invocation history
GET/api/v1/invocations/{id}JWTSingle invocation detail

Provider Console

MethodPathAuthDescription
POST/api/v1/provider/agentsJWTRegister a new agent
GET/api/v1/provider/agentsJWTList my agents
GET/api/v1/provider/agents/{id}JWTGet my agent details
PUT/api/v1/provider/agents/{id}JWTUpdate my agent
DELETE/api/v1/provider/agents/{id}JWTDelete my agent
GET/api/v1/provider/agents/{id}/analyticsJWTAgent invocation analytics
GET/api/v1/provider/dashboardJWTProvider overview dashboard

Access Control

MethodPathAuthDescription
POST/api/v1/agents/{id}/access-requestsJWTSubmit access request
GET/api/v1/agents/{id}/access-requests/meJWTCheck own request status
GET/api/v1/user/access-requestsJWTList user's access requests
GET/api/v1/provider/agents/{id}/access-requestsJWTList requests for agent (provider)
PUT/api/v1/provider/agents/{id}/access-requests/{request_id}JWTApprove/deny request (provider)

Notifications

MethodPathAuthDescription
GET/api/v1/provider/notificationsJWTList notifications
GET/api/v1/provider/notifications/countJWTUnread count
PUT/api/v1/provider/notifications/{id}/readJWTMark as read
PUT/api/v1/provider/notifications/read-allJWTMark all as read
GET/api/v1/provider/notifications/wsJWTWebSocket for real-time notifications

Reviews & Reports

MethodPathAuthDescription
POST/api/v1/directory/{id}/reviewsJWTSubmit or update a review
DELETE/api/v1/directory/{id}/reviewsJWTDelete own review
POST/api/v1/reportsJWTReport an agent or review

Admin (requires admin role)

MethodPathDescription
GET/api/v1/admin/dashboardSystem overview stats
GET/api/v1/admin/usersList users (search, role filter, pagination)
GET/api/v1/admin/users/{id}Get user details
PUT/api/v1/admin/users/{id}/roleUpdate user role
DELETE/api/v1/admin/users/{id}Delete user
GET/api/v1/admin/agentsList all agents (search, protocol, status filter)
GET/api/v1/admin/agents/{id}Agent detail with owner, reputation, reviews, invocation stats
DELETE/api/v1/admin/agents/{id}Delete agent
POST/api/v1/admin/agents/{id}/verifyVerify agent
DELETE/api/v1/admin/agents/{id}/verifyUnverify agent
GET/api/v1/admin/reportsList abuse reports (status filter, pagination)
GET/api/v1/admin/reports/{id}Get report details
PUT/api/v1/admin/reports/{id}Update report status (reviewed/dismissed/actioned)
DELETE/api/v1/admin/reports/{id}Delete report
POST/api/v1/admin/categoriesCreate category
PUT/api/v1/admin/categories/{id}Update category
DELETE/api/v1/admin/categories/{id}Delete category
GET/api/v1/admin/analyticsGlobal invocation analytics (since, bucket_minutes)
GET/api/v1/admin/invocationsInvocation log (agent_id, user_id filter, pagination)

Verification

MethodPathDescription
POST/api/v1/agents/{id}/verifyInitiate endpoint verification (owner only)

Discovery & Routing

MethodPathDescription
POST/api/v1/discoverDiscover agents by capability or protocol
GET/api/v1/routesView routing table
GET/api/v1/routes/resolveResolve a route (target_id, protocol)

Contacts & Contact Requests

MethodPathDescription
POST/api/v1/agents/{id}/contactsAdd a contact (owner only)
GET/api/v1/agents/{id}/contactsList contacts (owner only)
DELETE/api/v1/agents/{id}/contacts/{contact_id}Remove a contact (owner only)
POST/api/v1/agents/{id}/contact-requestsSend contact request (owner only)
GET/api/v1/agents/{id}/contact-requests/incomingList incoming requests (owner only)
GET/api/v1/agents/{id}/contact-requests/sentList sent requests (owner only)
PUT/api/v1/agents/{id}/contact-requests/{request_id}Accept/reject request (owner only)

Bridge & Health

MethodPathDescription
POST/api/v1/bridge/sendSend a message via protocol bridge
GET/api/v1/healthHealth check

Authentication

The server supports three authentication mechanisms:

  • Bearer token (agent): Authorization: Bearer <api-key> — for agent-to-gateway communication
  • Ed25519 signature (agent): X-PeerClaw-PublicKey + X-PeerClaw-Signature headers
  • JWT (user): Authorization: Bearer <jwt-access-token> — for platform user sessions

When auth.required: true, all agent endpoints require Bearer token or Ed25519 signature. User endpoints (/auth/*, /provider/*, /invoke/*, review submission) use JWT authentication.

Public endpoints (no auth): GET /api/v1/health, GET /api/v1/directory, GET /api/v1/directory/{id}, GET /api/v1/directory/{id}/reputation, GET /api/v1/directory/{id}/reviews, GET /api/v1/categories, POST /api/v1/auth/register, POST /api/v1/auth/login, GET /.well-known/agent.json, GET /acp/ping

Protocol Gateway Endpoints

The server also exposes standard protocol endpoints, so external agents can interact with PeerClaw agents using their native protocol:

A2A (Google Agent-to-Agent)

MethodPathDescription
POST/a2aJSON-RPC 2.0 (message/send, tasks/get, tasks/cancel)
GET/.well-known/agent.jsonA2A Agent Card
GET/a2a/tasks/{id}Query task status

MCP (Model Context Protocol)

MethodPathDescription
POST/mcpStreamable HTTP (initialize, tools/*, resources/*, prompts/*)
GET/mcpSSE stream

ACP (Agent Communication Protocol)

MethodPathDescription
GET/acp/agentsList available agents
GET/acp/agents/{name}Agent manifest
POST/acp/runsCreate a run
GET/acp/runs/{run_id}Run status
POST/acp/runs/{run_id}/cancelCancel a run
GET/acp/pingHealth check

Universal Gateway

MethodPathDescription
POST/agent/{agent_id}Auto-detect protocol and invoke agent
GET/agent/{agent_id}Auto-detect protocol and discover agent

WebSocket Signaling

Endpoint: GET /api/v1/signaling?agent_id={id}

Used for WebRTC signaling — agents exchange offer/answer/ICE candidates through this relay. When auth.required is true, the client must send an auth frame (agent_id + timestamp + Ed25519 signature) within 5 seconds of connecting.

{
"type": "offer | answer | ice_candidate | config",
"from": "alice",
"to": "bob",
"sdp": "...",
"candidate": "...",
"x25519_public_key": "..."
}

Features:

  • 64KB message size limit
  • Per-connection rate limiting (10 msg/s)
  • Auto-push TURN configuration on connect
  • bridge_message type for delivering protocol-bridged envelopes
  • Contacts whitelist enforcement — signaling messages (offer/answer/ICE) are blocked unless both agents are mutual contacts via the ContactsChecker interface

Deployment Patterns

Single Node (development)

./peerclawd # SQLite, no Redis, everything works

Docker Compose

docker-compose up -d

Starts peerclaw (port 8080) + Redis (port 6379) with persistent volumes. See docker-compose.yaml.

Systemd (Linux VPS)

make install # builds, installs binary + unit + config
sudo nano /etc/peerclaw/peerclaw.env # set JWT_SECRET
sudo nano /etc/peerclaw/config.yaml # adjust for your environment
sudo systemctl start peerclawd
sudo journalctl -u peerclawd -f

Security-hardened unit file with ProtectSystem=strict, NoNewPrivileges, dedicated peerclaw user. See deploy/systemd/.

Production (multi-node)

database:
driver: "postgres"dsn: "${DATABASE_URL}"redis:
addr: "redis:6379"password: "${REDIS_PASSWORD}"auth:
required: trueobservability:
enabled: true

Federated

federation:
enabled: truenode_name: "us-east-1"auth_token: "${FEDERATION_TOKEN}"dns_enabled: truedns_domain: "peerclaw.example.com"peers:
- name: "eu-west-1"address: "https://eu.peerclaw.example.com"

Agents registered on different servers can discover and signal each other through federation relay.

Security

LayerProtection
AuthenticationEd25519 signatures or API keys on all endpoints
AuthorizationOwner-only routes (DELETE, heartbeat)
Input ValidationName length, public key format, capability limits
SSRF ProtectionURL validation blocks private IPs in bridge adapters
Rate LimitingPer-IP token bucket, trusted proxy support
FederationConstant-time token comparison, TLS 1.2 minimum
WebSocketAuth frame timeout, message size/rate limits
Signaling WhitelistContacts-based whitelist on offer/answer/ICE — blocks unauthorized P2P connections at the relay
Secrets${ENV_VAR} config substitution — no plaintext in files

License

Licensed under the Business Source License 1.1. Converts to Apache License 2.0 on 2029-03-12.

Copyright 2025 PeerClaw Contributors.

About

PeerClaw Gateway — agent registry, protocol bridging (A2A/MCP/ACP), reputation engine, platform dashboard, and access control

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages