npm package: @relayforge/carapace-sdk
Description: JavaScript/TypeScript SDK for the Carapace Protocol — federated agent identity in a single function call
Author: RelayForge
Latest version: 0.1.0

# carapace-sdk

Federated agent identity in a single function call.

This package wraps the [Carapace Protocol](https://relayforge.tools) so any AI agent can **register**, **verify**, and **discover** trustable peers in under five minutes.

Works with A2A, MCP, OpenClaw, LangChain, CrewAI — framework-agnostic.

> **Status:** Alpha — core API is stable, ARIA registry endpoint at `relayforge.tools` coming soon.

---

## Install

```bash
npm install carapace-sdk
# or
pnpm add carapace-sdk
```

---

## Quick start

```ts
import { Carapace } from 'carapace-sdk';

// One-time setup — auto-generates a keypair if ownerKey is omitted
const carapace = await Carapace.create({
  registryUrl: 'https://relayforge.tools/aria/v1',
  ownerKey: process.env.CARAPACE_OWNER_KEY  // hex Ed25519 private key (optional)
});

// Register an agent — one function call
const card = await carapace.register({
  name: 'MyAgent',
  description: 'A helpful research agent',
  framework: 'langchain',
  capabilities: [
    { id: 'research', name: 'Research', description: 'Searches and summarizes topics' }
  ],
  endpoints: [
    { protocol: 'a2a', url: 'https://my-server.com/agent/a2a' }
  ]
});

// Verify another agent — one function call
const result = await carapace.verify(card.id);
console.log(result.verified); // true

// Discover agents by capability — one function call
const peers = await carapace.discover({ capability: 'research' });

// Verify locally — no network needed
const ok = await carapace.verifyLocal(card, card.signature, card.owner.public_key);
```

**What the SDK handles silently:**
- Ed25519 key generation and derivation (private key never leaves your process)
- JCS (JSON Canonicalization Scheme, RFC 8785) before signing
- Identity card construction from minimal input
- Signature verification

**What you never have to think about:**
- Cryptography
- JSON Schema structure
- Canonicalization / encoding
- A2A / MCP compatibility

---

## API

### `Carapace.create(options): Promise<Carapace>`

Factory constructor. Auto-generates a keypair when `ownerKey` is omitted.

```ts
// With an existing key (production):
const carapace = await Carapace.create({ registryUrl, ownerKey: process.env.KEY });

// Auto-generate key (quick test / one-off):
const carapace = await Carapace.create({ registryUrl });
console.log(carapace.publicKey());   // share or store this
```

### `new Carapace(options)`

Synchronous constructor. `ownerKey` can be omitted — offline operations
(`verifyLocal`) still work; signing/registering will throw a clear error.

| Option | Type | Required | Description |
|--------|------|----------|-------------|
| `registryUrl` | `string` | Yes | Base URL of the ARIA registry |
| `ownerKey` | `string` | No | Hex-encoded Ed25519 private key (64 chars) |

### `carapace.register(options): Promise<AgentCard>`

Build, sign, and register a new agent. One call handles everything.

| Option | Type | Required |
|--------|------|----------|
| `name` | `string` | Yes |
| `description` | `string` | Yes |
| `framework` | `string` | Yes |
| `capabilities` | `Capability[]` | Yes |
| `endpoints` | `Endpoint[]` | Yes |
| `version` | `string` | No |
| `tags` | `string[]` | No |
| `metadata` | `Record<string,unknown>` | No |

### `carapace.verify(agentId): Promise<VerifyResult>`

Registry round-trip: fetch card, re-verify signature.

```ts
const { verified, agent } = await carapace.verify('some-uuid');
```

### `carapace.discover(filters?): Promise<AgentCard[]>`

Search for agents. All filters optional.

| Filter | Type | Description |
|--------|------|-------------|
| `capability` | `string` | Filter by capability id |
| `framework` | `string` | Filter by framework |
| `tag` | `string` | Filter by tag |
| `text` | `string` | Full-text search |
| `limit` | `number` | Max results (default: 20) |

### `carapace.verifyLocal(card, signature, publicKey): Promise<boolean>`

Ed25519 verification — **fully offline**, no registry call.

```ts
const ok = await carapace.verifyLocal(card, card.signature, card.owner.public_key);
```

### `carapace.get(agentId): Promise<AgentCard>`

Fetch a card by UUID from the registry.

### `carapace.publicKey(): string`

Return the hex-encoded public key derived from `ownerKey`.

---

## A2A compatibility

Generate a valid [A2A Agent Card](https://google.github.io/a2a/specification/) for `/.well-known/agent.json`:

```ts
import { generateWellKnownCard } from 'carapace-sdk';

const card = await carapace.register({ ... });
const a2aCard = generateWellKnownCard(card);

// Serve at /.well-known/agent.json
app.get('/.well-known/agent.json', (req, res) => res.json(a2aCard));
```

---

## MCP compatibility

Export capabilities as MCP `tools/list`:

```ts
import { generateToolsList, generateMcpServerConfig } from 'carapace-sdk';

const tools = generateToolsList(card);        // { tools: [...] }
const config = generateMcpServerConfig(card); // claude_desktop_config.json entry
```

---

## Low-level API (`CarapaceClient`)

For advanced use or custom flows, the lower-level `CarapaceClient` is also exported:

```ts
import { CarapaceClient, generateKeyPair, signPayload, verifyPayload } from 'carapace-sdk';

const { privateKey, publicKey } = await generateKeyPair();
const client = new CarapaceClient({ registryUrl, ownerPrivateKey: privateKey });

const card = await client.registerAgent({ ... });
const result = await client.verifyAgent('uuid');
const peers = await client.discoverAgents({ capability: 'research' });
```

---

## Security model

- **Private key never leaves your process.** Only the derived public key is sent to the registry.
- **Signatures use Ed25519** (RFC 8032) over JCS-canonical (RFC 8785) JSON.
- **No registry dependency for verification.** Use `verifyLocal` or `verifyPayload` offline.
- Revocation is soft-delete — the card stays in the registry with `status: "revoked"`.

---

## Development

```bash
pnpm install
pnpm build      # tsup → dist/
pnpm test       # vitest (no network required)
```

---

## Roadmap

- ✅ Ed25519 + JCS signing (`@noble/ed25519` v2)
- ✅ Key generation helper (`generateKeyPair`)
- ✅ `Carapace` convenience class — directive-spec API
- ✅ `register()` / `verify()` / `discover()` / `verifyLocal()`
- ✅ `generateWellKnownCard()` — A2A `/.well-known/agent.json`
- ✅ `generateToolsList()` — MCP `tools/list`
- ✅ Cross-language interop verified (JS ↔ Python byte-identical signatures)
- ✅ GitHub Actions CI (Node 20 + 22)
- 🚧 ARIA registry endpoint live at `relayforge.tools`
- ⏩ Publish alpha to npm
- ⏩ Secure key storage adapters (Node keychain, env-file, Vault)

---

MIT License — RelayForge