The missing trust and supply chain layer for autonomous agents.
MCP connects agents to tools. A2A connects agents to agents. ASPL verifies that what they find is safe, compatible, and trustworthy — then delivers it with cryptographic proof.
[Application] LangChain, CrewAI, AutoGen, your agents
[Trust & Supply] >>> ASPL <<< (find + verify + trust + deliver)
[Communication] A2A (agent-to-agent)
[Tool Layer] MCP (agent-to-tool)
[Infrastructure] Cloud, APIs, databases
ASPL is a layer above MCP and A2A: it ingests both (and LangChain tools) into one trust-scored, signed, discoverable namespace. The capabilities below are defined in ASPL's spec and are not part of the MCP or A2A spec. (They're individually buildable by others — ASPL's value here is being the layer that combines them, not an unbreakable moat.)
| Capability | MCP spec | A2A spec | ASPL |
|---|---|---|---|
| Cryptographic node identity | No | No (cards now JWS-signable) | Ed25519 |
| Quantitative trust scoring (usage outcomes) | No | No | Bayesian + activity + decay |
| Sybil resistance | No | No | PoW register + distinct-confirmer trust |
| Environment verification (probe) | No | No | Compatibility + opt-in smoke probe |
| Content security scanning | No | No | At publish (homoglyph/base64/AST) |
| Capability delivery receipts | No | No | Double-signed + content hash, client-verified |
| Intent-based discovery | No | Tag/schema only | Semantic matching, trust-ranked |
| Capability revocation | No | No | SSE push + signed status-list + enforced at delivery |
| Audit transparency | No | No | Hash-chained log |
| Verifiable transparency log | No | No | Merkle (RFC 6962): inclusion + consistency proofs + signed tree heads |
| Cross-node federation | No | No | Mirror a peer's signed catalog + revocations with provenance |
| Cross-protocol ingestion | n/a | n/a | MCP + A2A + LangChain → one namespace |
Pick one — all three give you a running node:
# 1. One-click script (creates a venv, installs, writes .env) ./install.sh # add --dev for tests, --run to start immediately # 2. Docker (one command) docker compose up # 3. pip pip install -e . # then: aspl-server
Configuration is via flags or ASPL_* env vars (see .env.example):
aspl-server --host 0.0.0.0 --port 5010.
Drive a node from the terminal with the aspl CLI:
aspl register --name my-agent # solves PoW, saves creds under ~/.aspl aspl need --intent "summarize legal contracts" aspl acquire --intent "summarize legal contracts" # need→accept→deliver (sig-verified)
...or from Python:
from sdk.aspl_client import ASPLClient client = ASPLClient("http://localhost:5010") agent = client.register("my-agent") # PoW solved automatically results = client.need("I need to send WhatsApp messages") # intent, not tags capability = client.get("SEO article writing") # need + accept + deliver (verified) client.publish( type="tool", intent="Convert PDF to structured markdown", description="Extract text, tables, and images from PDF documents", content={"code": "..."}, )
A zero-dependency JavaScript/TypeScript SDK is in sdk-js/ and
verifies node Ed25519 delivery signatures in JS (cross-language interop).
ASPL ingests MCP tool definitions and wraps them as trust-scored capabilities. Your MCP tools keep working — they just gain trust scoring, security scanning, and intent-based discovery.
# Ingest your MCP tools in one call client.ingest_mcp("https://my-mcp-server.com", [ { "name": "search_web", "description": "Search the web", "inputSchema": {"type": "object", "properties": {"query": {"type": "string"}}}, }, ]) # Tools now have trust scores, security scans, and are discoverable by intent
MCP tools start at trust 0.5. Trust increases with successful usage, decreases with failures. See examples/migrate_from_mcp.py.
ASPL converts A2A Agent Cards to signed passports with trust history. Your A2A agents keep communicating via A2A — ASPL adds the verification layer on top.
# Ingest an A2A Agent Card client.ingest_a2a({ "name": "code-reviewer", "url": "https://agents.example.com/code-reviewer", "skills": [ {"id": "review", "name": "Code Review", "description": "Review code for bugs"} ], }) # Agent now has a signed passport, trust score (starts at 0.3), and its skills are ASPL capabilities
A2A agents start at trust 0.3 (lower than MCP — Agent Cards are less verifiable). See examples/migrate_from_a2a.py.
ASPL imports LangChain tools as trust-scored, discoverable capabilities, and can wrap an ASPL capability back into a LangChain tool — both directions.
# Import LangChain tool descriptors (live tool objects work too) client.ingest_langchain([ {"name": "web_search", "description": "Search the web and return result snippets", "args_schema": {"query": {"type": "string"}}}, ]) # ...or pull a discovered ASPL capability into a LangChain agent at run time from aspl.adapters.langchain import tools_for_intent tools = tools_for_intent(client, "summarize legal contracts")
LangChain tools start at trust 0.4. The adapter is duck-typed: it works whether or
not langchain is installed.
Agent ASPL Node
| |
|──── GET /v1/pow/challenge ────>| 1. Get proof-of-work challenge
|<─── challenge + difficulty ────|
| |
|──── POST /v1/register ��───────>| 2. Register with PoW solution
|<─── passport + API key ───────| Ed25519 keypair generated
| |
|──── POST /v1/need ────────────>| 3. "I need to send emails"
|<─── ranked matches ───────────| Intent match + trust + env check
| |
|──── POST /v1/accept ────────���─>| 4. Accept a capability
|<─── transaction_id ───────────|
| |
|──── GET /v1/deliver/{txn} ��───>| 5. Receive capability content
|<─── signed content + hash ────| Shop-signed delivery
| |
|──── POST /v1/confirm ────────��>| 6. "It worked" / "It failed"
|<─── trust scores updated ─────| Both agent and capability trust update
aspl/
├── server.py # FastAPI protocol server (register, need, deliver, confirm, revoke)
├── models.py # Pydantic message types
├── crypto.py # Ed25519 signing + shop identity
├── trust.py # Bayesian trust scoring
├── intent.py # TF-IDF + fuzzy intent matching
├── scanner.py # Content security scanner (injection, exfil, abuse)
├── pow.py # Proof-of-work anti-sybil
├── audit.py # Hash-chained transparency log
├── auth.py # API key auth + rate limiting
├── ratelimit.py # Token bucket rate limiter
├── database.py # SQLite schema
└── adapters/
├── mcp.py # MCP tool -> ASPL capability converter
└── a2a.py # A2A Agent Card -> ASPL passport converter
sdk/
└── aspl_client.py # Python client with auto PoW solving
examples/
├── quickstart.py
├── migrate_from_mcp.py
└── migrate_from_a2a.py
tests/
├── test_trust.py
├── test_scanner.py
├── test_intent.py
└── test_adapters.py
Six layers, all built and working:
- Proof-of-Work — configurable difficulty (
ASPL_POW_DIFFICULTY). Default 18 bits is a ~0.5s speed bump in pure Python; raise it (22≈8s, 24≈30s) for adversarial deployments. Native/GPU solvers are faster, so size the cost to your threat model — PoW alone is not a strong sybil barrier. - Ed25519 Signing — Every agent gets a keypair. Every capability is double-signed (publisher + node).
- Content Scanning — 30+ patterns for prompt injection, data exfiltration, and resource abuse.
- Hash-Chained Audit — Every action logged with hash chain. Tamper = chain break = detected.
- Rate Limiting — Per-agent, per-endpoint token buckets.
- Revocation — Publishers revoke instantly: removed from discovery/delivery, pushed live to subscribers over SSE (
GET /v1/revocations/stream, signed events), and recorded in a node-signed pull status-list (GET /v1/revocations) for agents reconciling after downtime. Cross-node fan-out (gossip/bus) is still future work.
# Agent trust: Bayesian success rate * activity * decay trust = ((successes + 2.5) / (total + 5)) # Bayesian average * min(1, log(1 + total) / log(101)) # Activity factor * exp(-0.023 * days_inactive) # 30-day half-life # Capability trust: 70% quality + 30% publisher reputation # quality is over DISTINCT non-publisher confirmers (volume from one identity # can't pump it; the publisher's own confirmations are excluded) cap_trust = 0.7 * (success_rate * usage_factor) + 0.3 * publisher_trust # Read-time freshness decay: stale capabilities rank lower (30-day half-life) effective = cap_trust * exp(-0.023 * days_since_last_use) # Imported capabilities get initial trust based on source # MCP imports: 0.5 (has schema, no trust history) # LangChain imports: 0.4 (typed args schema, local/unsigned) # A2A imports: 0.3 (cards less verifiable) # Federated mirror: 0.5x the origin node's reported trust
Anti-gaming: distinct-confirmer counting, self-dealing (publisher confirming its own
capability) excluded, freshness decay. Measured: a single-agent self-confirm pump that
drove trust 0.10→0.36 is neutralized to 0.00 (tests/test_adversarial.py).
pip install -e ".[dev]"
pytest tests/ -vWorking now: Core protocol, trust scoring, intent matching, MCP/A2A adapters, Python SDK, audit log, proof-of-work.
-
Hardened content scanning — beyond the regex denylist: unicode/homoglyph normalization, base64/hex decode-and-rescan, and AST analysis of code capabilities (catches obfuscated
eval/exec/getattr/os.system/subprocess(shell=True)/destructive-fs that plaintext regex misses). Seetests/test_scanner_hardened.pyfor payloads regex provably misses. -
Environment verification probes —
POST /v1/probe/{cap}checks a capability'srequiresagainst the agent's declared environment (runtime/os/permissions/deps/memory);/v1/needannotates matches withenv_compatible. Optional opt-in resource-limited smoke probe runs a capability'sprobe/codeunder CPU/memory/wall-clock limits (NOT a security sandbox — seeaspl/probe.py). -
Client-side delivery verification — the SDK recomputes the content hash and verifies the node's Ed25519 signature on every
deliver()(raises on tamper/forgery). Signing is only worth something if clients check it. -
Agent-framework adapter —
aspl/adapters/agent.pyexposes the capability lifecycle as OpenAI/Hermes tool schemas so any function-calling agent (Hermes, OpenGenie, OpenHands, ...) can discover→acquire→use capabilities over ASPL. Demo:examples/hermes_agent_demo.py(scripted, or--modelfor a live LLM). -
Revocation broadcast — live SSE push (
/v1/revocations/stream, signed events) + node-signed pull status-list (/v1/revocations). Demonstrated end-to-end (subscriber notified the instant a capability is revoked). -
Live MCP-server ingestion — point the node at a running MCP server URL (
POST /v1/ingest/mcp/url); it fetchestools/listover JSON-RPC and imports them as trust-scored, discoverable capabilities. Demonstrated against a live MCP server. -
Verifiable transparency log (Merkle / CT-style) — a Merkle tree (RFC 6962) over the audit log gives external, O(log n) verifiability: inclusion proofs (an event is in the log), consistency proofs (the log only ever appended — rewrites are detectable), and signed tree heads you can pin and audit against.
GET /v1/log/{sth,proof/inclusion,proof/consistency,leaves}. Seetests/test_translog.py(exhaustive proof math) andtests/test_log_endpoints.py(live signature/proof verification). -
Cross-node federation —
POST /v1/federation/mirrormirrors a peer node: it verifies the peer's signed tree head and signed revocation list (same key for both), then mirrors non-revoked capabilities asaspl-federateddiscovery records at ×ばつ trust with origin-node provenance, honoring the peer's revocations. Acquisition proxy (POST /v1/federation/acquire/{cap}) then lets a local agent actually acquire a mirrored capability — the node fetches it from the origin, verifies the origin's Ed25519 signature, and returns the real content;get()routes federated matches through it transparently. Proven across two real nodes intests/test_federation.py. -
Crash-test red-team agent —
aspl-redteam <url>is an autonomous security scanner you point at any live ASPL node: it registers agents and launches real attacks (auth/PoW bypass, prompt injection, delivery tamper/forge, replay, cross-agent IDOR, revocation bypass, trust pumping, malformed/fuzz input) and reports findings with severities, exiting non-zero on CRITICAL/HIGH. The reference node passes its own scan (tests/test_redteam.py). -
LangChain adapter —
POST /v1/ingest/langchainimports LangChain tool descriptors as capabilities;aspl/adapters/langchain.pyalso wraps an ASPL capability back into a LangChain tool (both directions, works with or withoutlangchaininstalled). -
Sybil-resistant trust — distinct-confirmer counting + self-dealing exclusion + freshness decay (see Trust Scoring above).
-
Adversarial test suite —
tests/test_adversarial.pyattacks a live node (forged sigs, tampered content, replay, revocation bypass, trust pumping). One real revocation-bypass was found and fixed via this suite. -
CLI —
aspldrives the whole protocol from a terminal (register/publish/need/acquire/confirm/revoke/ingest/probe/catalog/stats/audit), with per-node credentials saved under~/.aspl. -
Formal spec + conformance suite —
SPEC.mddefines the wire protocol;python -m conformance.aspl_conformance <url>verifies any implementation against it (the reference node passes 21/21). This is what makes ASPL a protocol, not one codebase. -
JS/TS SDK — zero-dependency Node client (
sdk-js/) that drives the full flow against the Python node and verifies the node's Ed25519 delivery signature in JavaScript (canonical content-hash matches byte-for-byte across languages). Second independent-language implementation.
Coming next: acquisition-proxying for federated capabilities (mirror today is discovery-only), true container/seccomp isolation for the smoke probe, more native framework adapters (CrewAI, AutoGen).
Apache 2.0 — free to use, modify, and distribute. The protocol is open.
Tilelli LAB — hello@tilelli.tech