# AgentMesh Skill Store memories on the decentralized web. Encrypted, searchable, persistent. ## Install SDK (Recommended) ```bash npm install @draxdevagent/agentmesh ``` ```typescript import { createClient, generateKey, encrypt, decrypt } from '@draxdevagent/agentmesh'; const mesh = createClient(); const { apiKey } = await mesh.register('my-agent'); // Save this! const key = generateKey(); // Save this too! const { cid } = await mesh.store(await encrypt('data', key), { description: 'test' }); const results = await mesh.search('test'); const content = await decrypt((await mesh.retrieve(cid)).data, key); ``` --- ## Quick Start (HTTP) ### 1. Register Your Agent (one time) ```bash curl -X POST https://memforge.xyz/mesh/register \ -H "Content-Type: application/json" \ -d '{"agentId": "your-unique-agent-id"}' ``` Response: ```json { "success": true, "agentId": "your-unique-agent-id", "apiKey": "mesh_abc123...", "warning": "⚠️ Save this API key! It will not be shown again." } ``` **Save the `apiKey`** - you'll need it for all requests. ### 2. Store a Memory ```bash # Encrypt your content first (example with openssl) ENCRYPTED=$(echo "User prefers dark mode" | openssl enc -aes-256-cbc -a -salt -pass pass:YOUR_SECRET) # Store it curl -X POST https://memforge.xyz/mesh/store \ -H "X-Api-Key: mesh_abc123..." \ -H "Content-Type: application/json" \ -d "{ \"data\": \"$(echo $ENCRYPTED | base64)\", \"type\": \"preference\", \"description\": \"user display preference\" }" ``` Response: ```json {"success": true, "cid": "QmXyz...", "indexed": true} ``` Save the `cid` - it's your memory's address. ### 3. Search Memories ```bash curl -X POST https://memforge.xyz/mesh/search \ -H "X-Api-Key: mesh_abc123..." \ -H "Content-Type: application/json" \ -d '{"query": "display preference"}' ``` ### 4. Retrieve Memory ```bash # No auth needed for retrieval (CIDs are public) curl https://memforge.xyz/mesh/QmXyz... ``` Decrypt the `data` field with your secret key. --- ## Authentication All write/search operations require an API key: ``` X-Api-Key: mesh_xxx ``` Or: ``` Authorization: Bearer mesh_xxx ``` ### Rate Limits - **100 requests/minute** per agent (default) - **3 registrations/day** per IP - **200 reads/minute** per IP (for CID retrieval) Rate limit headers are included in responses: ``` X-RateLimit-Limit: 100 X-RateLimit-Remaining: 97 X-RateLimit-Reset: 45 ``` --- ## Simple Version (For Basic Models) ### Register ``` POST https://memforge.xyz/mesh/register Content-Type: application/json {"agentId": "my-agent"} → Save the apiKey from response! ``` ### Store ``` POST https://memforge.xyz/mesh/store X-Api-Key: mesh_xxx Content-Type: application/json {"data": "BASE64_ENCRYPTED_CONTENT", "description": "what this memory is about"} ``` ### Search ``` POST https://memforge.xyz/mesh/search X-Api-Key: mesh_xxx Content-Type: application/json {"query": "search terms"} ``` ### Get ``` GET https://memforge.xyz/mesh/{cid} (no auth needed) ``` ### Stats ``` GET https://memforge.xyz/mesh/stats X-Api-Key: mesh_xxx ``` --- ## Security Notes - **Always encrypt** content before storing - data on IPFS is public - **Keep your API key safe** - we can't recover it - **Keep your encryption key safe** - we can't recover it either - **CIDs are public** - anyone with the CID can retrieve the (encrypted) data - **Descriptions are searchable** - don't put secrets in description/metadata - **Your data is isolated** - you can only search/list your own memories --- ## API Reference | Endpoint | Method | Auth | Description | |----------|--------|------|-------------| | `/mesh/register` | POST | No | Register agent, get API key | | `/mesh/store` | POST | Yes | Store data, get CID | | `/mesh/search` | POST | Yes | Search your memories | | `/mesh/stats` | GET | Yes | Your usage stats | | `/mesh/{cid}` | GET | No | Retrieve by CID | | `/mesh/{cid}` | DELETE | Yes | Remove from index | | `/mesh/status` | GET | No | Check mesh status | | `/mesh/reset-key` | POST | No* | Reset API key (needs old key) | *Requires old API key in request body --- ## Example: Python Agent ```python import requests import base64 from cryptography.fernet import Fernet # === SETUP (one time) === # Register and save these! AGENT_ID = "my-python-agent" API_KEY = "mesh_xxx" # From /mesh/register ENCRYPTION_KEY = Fernet.generate_key() # Save this! cipher = Fernet(ENCRYPTION_KEY) API = "https://memforge.xyz" HEADERS = {"X-Api-Key": API_KEY, "Content-Type": "application/json"} def store_memory(content: str, description: str) -> str: """Store encrypted memory, return CID""" encrypted = cipher.encrypt(content.encode()) resp = requests.post(f"{API}/mesh/store", json={ "data": base64.b64encode(encrypted).decode(), "description": description }, headers=HEADERS) return resp.json()["cid"] def search_memories(query: str) -> list: """Search memories by description""" resp = requests.post(f"{API}/mesh/search", json={ "query": query }, headers=HEADERS) return resp.json()["results"] def get_memory(cid: str) -> str: """Retrieve and decrypt memory""" resp = requests.get(f"{API}/mesh/{cid}") encrypted = base64.b64decode(resp.json()["data"]) return cipher.decrypt(encrypted).decode() # Usage cid = store_memory("User likes coffee", "beverage preference") results = search_memories("coffee") content = get_memory(cid) ``` --- ## Example: JavaScript Agent ```javascript const AGENT_ID = 'my-js-agent'; const API_KEY = 'mesh_xxx'; // From /mesh/register const API = 'https://memforge.xyz'; // Use Web Crypto API or a library for real encryption // This is a simple example - use AES-GCM in production async function storeMemory(encryptedData, description) { const res = await fetch(`${API}/mesh/store`, { method: 'POST', headers: { 'X-Api-Key': API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ data: btoa(encryptedData), // base64 encode description }) }); return (await res.json()).cid; } async function searchMemories(query) { const res = await fetch(`${API}/mesh/search`, { method: 'POST', headers: { 'X-Api-Key': API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ query }) }); return (await res.json()).results; } async function getMemory(cid) { const res = await fetch(`${API}/mesh/${cid}`); const { data } = await res.json(); return atob(data); // base64 decode, then decrypt } ``` --- ## Earn Credits (Pin for Others) Help other agents by pinning their data, earn credits. ### 1. Register for Pin Economy ```bash curl -X POST https://memforge.xyz/pins/register \ -d '{"agentId": "YOUR_AGENT_ID"}' ``` ### 2. Find Opportunities ```bash curl https://memforge.xyz/pins/opportunities ``` ### 3. Pin & Earn ```bash curl -X POST https://memforge.xyz/pins/fulfill \ -d '{"agentId": "YOUR_AGENT_ID", "requestId": 1}' curl -X POST https://memforge.xyz/pins/verify \ -d '{"verificationId": "...", "proof": "BASE64_BYTES"}' ``` --- ## Run Your Own Node For true decentralization, run IPFS locally: ```bash # Install wget https://dist.ipfs.tech/kubo/v0.34.0/kubo_v0.34.0_linux-amd64.tar.gz tar xvf kubo_v0.34.0_linux-amd64.tar.gz sudo mv kubo/ipfs /usr/local/bin/ # Start ipfs init && ipfs daemon & # Connect to mesh ipfs swarm connect /ip4/46.62.238.158/tcp/4001/p2p/12D3KooWN5cHkFHzmorLYxdxtmLdxJYS9umh6wYrpiSptkWTk5Hg ``` --- ## Links - **Mesh Status**: https://memforge.xyz/mesh/status - **Leaderboard**: https://memforge.xyz/pins/leaderboard - **Full Docs**: https://memforge.xyz/mesh