Skip to content

ghostmk/Agent-Content-Licensing

Repository files navigation

ACL — Agent Content Licensing

Slide deck | Design doc | Quick start

A content marketplace on Base where the entire workflow — listing, discovering, paying, proving license ownership — is six MCP tool calls. No browser. No human in the loop. Any LLM.

A creator's agent lists content with two license tiers — Personal (display/print) and Commercial (full rights) — each with its own price and onchain terms. A buyer's agent searches, scores, picks a tier, and purchases in a single atomic transaction. Creator gets 97.5%. Platform takes 2.5%. Buyer gets an ERC-721 license NFT with the tier recorded. Point Claude Code at the MCP server and it trades content the same way it runs shell commands.

Runtime + MCP Capabilities

flowchart LR
    subgraph world["External World"]
        CC["Claude Code"]
        CD["Claude Desktop"]
        SDK["Agent SDK / Custom"]
    end

    CC & CD & SDK ==>|"MCP protocol"| MCP["ACL MCP Server<br>6 tools"]

    MCP -->|"register_content"| IPFS["IPFS + SHA-256"]
    IPFS -->|"content URI"| CR["ContentRegistry<br>(Base)"]

    MCP -->|"search_content"| CR
    CR -->|"listings + tier prices"| MCP

    MCP -->|"purchase_license(tier)"| CAP{{"spend < cap?"}}
    CAP -->|"✓"| CR
    CR -->|"atomic split"| PAY["97.5% → Creator<br>2.5% → Platform"]
    CR -->|"mint"| NFT["LicenseNFT<br>(ERC-721 + tier)"]

    MCP -->|"verify_license"| NFT
    NFT -->|"true / false"| MCP
Loading

What We Built

Layer What it does
2 Solidity contracts ContentRegistry (marketplace logic, payment splitting, dual license tiers) + LicenseNFT (ERC-721 + ERC-2981 royalties, tier tracking)
License tiers Every listing has a Personal and Commercial tier with independent prices and onchain terms — buyers choose their level of rights
MCP server 6 tool calls that give any LLM native marketplace access — bounded by MCP_MAX_SPEND_ETH so humans stay in control
AI agent personas Built-in /sell, /buy, /browse, /verify slash commands turn Claude Code into a seller or buyer agent — real AI making decisions through MCP, not scripted demos
IPFS integration Decentralized content + metadata storage with SHA-256 integrity verification
Web dashboard + REST API For humans who want to see what's happening onchain
29 Foundry tests Registration, tier selection, purchases, refunds, payment splitting, royalties, admin controls: all green
100% E2E Verified Automated test suite verifies full lifecycle: Register → Purchase (Personal) → Purchase (Commercial) → Price Update → Verify Ownership → Deactivate

Under the Hood

  • ethers.js NonceManager handles high-concurrency agent transactions without nonce collisions
  • Price selection, license terms, payment splitting, and NFT minting settle in a single atomic Ethereum transaction
  • Every agent purchase is bounded by MCP_MAX_SPEND_ETH — agents cannot drain wallets without human oversight
  • Full metadata and license terms live on IPFS with SHA-256 content hashes recorded onchain for verification

MCP Server

The marketplace exposed as native LLM tool calls:

Tool What happens
register_content Hashes file, uploads to IPFS, registers onchain with personal + commercial prices and separate license terms per tier
search_content Queries onchain registry, returns active listings with both tier prices
get_content Full listing details — both tier prices, creator, IPFS links, license terms
purchase_license Takes a tier param (personal / commercial), pays the tier price, mints license NFT with tier recorded. Bounded by MCP_MAX_SPEND_ETH
verify_license Single onchain call: does this wallet own a license for this content?
get_licenses Every license NFT held by a wallet, including tier

Any MCP-compatible client — Claude Code, Claude Desktop, or custom — gets full marketplace access out of the box. The .mcp.json ships in the repo root.

ACL Dashboard Demo


How It Works

Human (Creator)                          Human (Buyer)
     |                                        |
     v                                        v
  AI Session (Seller)                    AI Session (Buyer)
     |                                        |
     |-- hash file (SHA-256)                  |-- query registry
     |-- upload to IPFS                       |-- score listings (tags, price, type)
     |-- build per-tier license terms         |-- rank results
     |-- registerContent(...)                 |-- choose tier (personal/commercial)
     |                                        |-- purchaseLicense(contentId, tier)
     v                                        v
  ContentRegistry (Base)              Atomic Settlement
     |                                   |-- creator gets 97.5%
     |                                   |-- platform gets 2.5%
     |                                   |-- buyer gets License NFT (tier recorded)
     v                                        v
  Any agent: verifyLicense(address, contentId) → true
  1. Human tells their agent to list content — a photo, document, dataset, whatever.
  2. Seller agent hashes the file, uploads to IPFS, creates separate license terms for Personal and Commercial tiers, registers onchain with both prices.
  3. Buyer's agent searches the registry, scores listings against criteria, compares tiers, and purchases the best match at the right tier.
  4. Atomic settlement — payment splits, license NFT mints, tier is recorded onchain. All-or-nothing.
  5. Onchain verification — any agent, anywhere, one call: verifyLicense(address, contentId). No trust required.

Architecture

sequenceDiagram
    participant HC as Human (Creator)
    participant SA as AI Session (Seller)
    participant IPFS
    participant CR as ContentRegistry
    participant NFT as LicenseNFT
    participant BA as AI Session (Buyer)
    participant HB as Human (Buyer)

    HC->>SA: "List my photo (Personal: 0.001, Commercial: 0.01 ETH)"
    SA->>SA: Hash file (SHA-256)
    SA->>IPFS: Upload file + metadata + per-tier license terms
    IPFS-->>SA: CIDs
    SA->>CR: registerContent(hash, metadataURI, personalTerms, commercialTerms, prices)
    CR-->>SA: contentId
    SA-->>HC: Listed as Content #1

    HB->>BA: "Find me landscape photos under 0.005 ETH"
    BA->>CR: getActiveContents()
    CR-->>BA: listings[]
    BA->>BA: Score + rank by tags, price, type
    BA-->>HB: Best match: "Sunset Over Mountains" (Personal 0.001 / Commercial 0.01)

    HB->>BA: "Buy it (personal tier)"
    BA->>CR: purchaseLicense(contentId, Personal) + ETH
    CR->>CR: Split payment (creator 97.5% / platform 2.5%)
    CR->>NFT: mintLicense(buyer, contentId, tier, price, termsURI)
    NFT-->>BA: License NFT #1
    BA->>NFT: verifyLicense(buyer, contentId)
    NFT-->>BA: true
    BA-->>HB: License verified, NFT in your wallet
Loading
Component Technology
Smart contracts Solidity 0.8.24+, OpenZeppelin 5.x, Foundry
Agent interface Model Context Protocol (MCP)
Agent runtime TypeScript, Node.js, Express, ethers.js v6
File storage IPFS via local kubo node
Frontend Vanilla HTML/CSS/JS
Target chain Base (local anvil for dev, Sepolia/Mainnet for prod)

Quick Start

Prerequisites

  • Node.js v18+ and npm
  • Foundry (anvil, forge) — install guide
  • IPFS (kubo) — optional, the demo simulates IPFS if not running
node -v && npm -v && anvil --version && forge --version
cd agent && npm install && cd ..

Option A: Quick Demo (fastest)

Deploys contracts, registers content with dual tiers, purchases a personal license, verifies ownership, checks royalties — all on a local chain in ~5 seconds.

# Terminal 1
anvil

# Terminal 2
cd agent && npm run demo

Option B: Agent Personas in Claude Code (recommended)

Open this project in Claude Code. The MCP server connects automatically. Then use the built-in persona commands:

/sell                    # Become a seller agent — list content with dual tier pricing
/buy                     # Become a buyer agent — search, evaluate, purchase
/browse                  # Browse all marketplace listings
/verify                  # Check license ownership on-chain

What happens: Claude Code assumes the persona, reasons about your request, and uses the 6 MCP tools to interact with the marketplace. This is a real AI agent making real decisions — not a scripted demo.

Examples:

/sell ~/photos/sunset.jpg --name "Beach Sunset" --personal 0.002 --commercial 0.02

/buy --type landscape --budget 0.005 --tags sunset,nature

/verify 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 1

The seller agent walks you through pricing strategy, uploads to IPFS, and registers on-chain. The buyer agent searches, scores, ranks listings, recommends a tier, and only purchases with your explicit approval.

Option C: Full Stack (dashboard + API + blockchain)

# Terminal 1: start IPFS (optional)
ipfs daemon

# Terminal 2: start everything
chmod +x dev.sh && ./dev.sh

Open frontend/index.html — register content with two price tiers, browse listings, pick a tier and buy, view trades, verify ownership.


MCP Integration

Ships with .mcp.json at repo root — Claude Code auto-detects it.

Two wallets required. The contract enforces creators can't buy their own content. Anvil provides pre-funded test accounts.

Spending cap. MCP_MAX_SPEND_ETH (default 0.1 ETH) bounds every purchase_license call. Human stays in control.

For Claude Desktop or custom setups:

{
  "mcpServers": {
    "acl": {
      "command": "npx",
      "args": ["tsx", "src/mcp-server.ts"],
      "cwd": "/absolute/path/to/agent",
      "env": {
        "RPC_URL": "http://127.0.0.1:8545",
        "REGISTRY_ADDRESS": "<from dev.sh output>",
        "LICENSE_NFT_ADDRESS": "<from dev.sh output>",
        "PRIVATE_KEY": "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
        "MCP_MAX_SPEND_ETH": "0.1"
      }
    }
  }
}

Try it:

  • "Register my photo sunset.jpg with personal price 0.001 ETH and commercial price 0.01 ETH, tags landscape, sunset."
  • "Search for landscape content under 0.005 ETH and purchase the best match with a personal license."

Smart Contracts

  • ContentRegistry.sol — Marketplace registry with dual license tiers. Content registration, tier-aware pricing, deactivation, license purchases with atomic payment splitting (creator + platform fee in basis points). LicenseTier enum enforces Personal vs. Commercial at the contract level.
  • LicenseNFT.sol — ERC-721 license tokens with ERC-2981 royalties (5% to original creator on secondary sales). Each license records its tier onchain. Only mintable by ContentRegistry.

Security:

  • ReentrancyGuard + checks-effects-interactions on all payment paths
  • SHA-256 content hashing for onchain integrity verification
  • .call{value} for ETH transfers (not .transfer())
  • 29 Foundry tests — all passing
cd contracts && forge test -vv

Backend API

Base URL: http://localhost:3001/api

Method Endpoint Description
GET /health Status, signer addresses, IPFS status
GET /stats Content count, license count
GET /content Paginated active content with IPFS metadata + both tier prices
GET /content/:id Single content item + metadata
POST /content Register content (multipart upload, personal + commercial prices)
PUT /content/:id/price Update tier-specific price
DELETE /content/:id Deactivate listing
POST /licenses/purchase Purchase a license (with tier selection)
GET /licenses/:tokenId License NFT details (includes tier)
GET /licenses/buyer/:address All licenses owned by a wallet
GET /verify/:address/:contentId Check license ownership
GET /trades Historical purchase events

Repository Layout

contracts/          Solidity contracts + Foundry config + 29 tests
agent/              TypeScript backend (Express API + ethers + IPFS)
  src/mcp-server.ts MCP server — 6 marketplace tools
  src/server.ts     Express REST API + IPFS integration
  src/demo.ts       Quick demo script (deploy + register + purchase + verify)
.claude/skills/     AI agent persona commands (/sell, /buy, /browse, /verify)
frontend/           Static dashboard UI
  index.html        Browser dashboard with tier picker
dev.sh              Local dev bootstrap (anvil + deploy + .env + API)
deck.html           Slide deck for judges
.mcp.json           MCP server config (auto-detected by Claude Code)
DESIGN.md           Full architectural and protocol design document

Why This Matters

Ask Claude Code to build a landing page with real stock photography right now. It will stop and ask you to go buy the images. With ACL's MCP server running, it wouldn't have to. That's what this is — agents that source, evaluate, price-compare across license tiers, and purchase licensed content autonomously, atomically, verifiably.

Property How ACL delivers
Agents that pay Buyer agent pays onchain via purchase_license, choosing Personal or Commercial tier. Atomic settlement: ETH splits to creator (97.5%) and platform (2.5%), license NFT mints with tier recorded. Human scopes spending via MCP_MAX_SPEND_ETH. Auditable on Base.
Agents that trust One onchain call: verifyLicense(address, contentId). No centralized registry can revoke access. SHA-256 content hashes stored onchain — any agent can verify integrity against IPFS independently.
Agents that cooperate Seller and buyer agents negotiate through immutable contract terms. Pricing, tier selection, payment splitting, license minting — all enforced by ContentRegistry. Succeeds or reverts atomically. No platform rewrites the deal.

Limitations — No authorship proof (hash uniqueness only, same as every decentralized marketplace). Basic onchain discovery (no full-text search). Single chain (Base). These are scope choices, not oversights.

For the full design rationale, see DESIGN.md.

About

End to end system for AI agents to register digital content on‑chain, store metadata and license terms on IPFS, and sell licenses as NFTs.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors