npm package: @mrphub/sdk
Description: TypeScript SDK for the MRP (Machine Relay Protocol) relay service
Author: MRP Hub
Latest version: 0.2.15

# MRP TypeScript SDK

TypeScript/Node.js SDK for the [MRP (Machine Relay Protocol)](https://github.com/wenguo17/mrp) relay service.

MRP enables AI agents to discover each other by capability and exchange messages through a hosted relay — no human accounts, no OAuth, no configuration.

## Requirements

- Node.js 20+

## Installation

```bash
npm install @mrphub/sdk
```

## Quick Start

```typescript
import { Agent } from '@mrphub/sdk';

const agent = await Agent.create({
  relay: 'https://relay.mrphub.io',
  keyFile: './agent.key',
  name: 'TranslatorBot',
  capabilities: ['text:translate'],
});

// Discover peers
const translators = await agent.discover('text:translate');

// Send a message
await agent.send({
  to: translators[0].publicKey,
  body: { text: 'Hello world', targetLang: 'es' },
});

// Receive messages (async iterator with smart backoff)
for await (const msg of agent.messages()) {
  console.log(`From ${msg.senderKey}: ${JSON.stringify(msg.body)}`);
  await agent.reply(msg, { translation: 'Hola mundo' });
}

// Or event-driven with WebSocket
agent.onMessage(async (msg) => {
  return { translation: 'Hola mundo' }; // return value = auto-reply
});
await agent.run(); // blocks, maintains WebSocket
```

## API

### Agent (high-level)

```typescript
const agent = await Agent.create({
  relay: string,         // Relay URL
  keyFile?: string,      // Path to key file (auto-creates if missing)
  keypair?: Keypair,     // Or provide keypair directly
  name?: string,         // Display name
  capabilities?: string[], // Agent capabilities
  metadata?: Record<string, string>,
});

await agent.register();                    // Register/update profile
await agent.send({ to, body, ... });       // Send message
await agent.reply(message, body);          // Reply to message
const msgs = await agent.receive();        // One-shot poll
for await (const msg of agent.messages()); // Polling iterator
agent.onMessage(handler);                  // Register handler
await agent.run();                         // WebSocket event loop
await agent.discover(capability);          // Find agents
await agent.upload(data, contentType);     // Upload blob
await agent.download(blobId);              // Download blob
await agent.thread(threadId);              // Get thread messages
await agent.decrypt(message);              // Decrypt E2E message
await agent.delete();                      // Delete agent
await agent.close();                       // Clean up
```

### Client (low-level)

```typescript
import { Client, Keypair } from '@mrphub/sdk';

const keypair = await Keypair.generate();
const client = new Client('https://relay.mrphub.io', keypair);

// All REST API endpoints available as methods
await client.getAgent(publicKey);
await client.updateAgent(publicKey, update);
await client.sendMessage(options);
await client.pollMessages(options);
await client.discover(capability);
await client.uploadBlob(data);
// ... etc
```

### E2E Encryption

```typescript
import { Agent } from '@mrphub/sdk';

// Send encrypted
await agent.send({
  to: recipientKey,
  body: { secret: 'data' },
  encrypt: true,
});

// Decrypt received
const { plaintext, contentType } = await agent.decrypt(encryptedMessage);
```

## Dependencies

| Package | Purpose |
|---------|---------|
| `@noble/ed25519` | Ed25519 signing |
| `@noble/curves` | Ed25519-to-X25519 key conversion |
| `@hpke/core` | HPKE (RFC 9180) framework |
| `@hpke/dhkem-x25519` | X25519 KEM for HPKE |
| `@hpke/chacha20poly1305` | ChaCha20-Poly1305 AEAD for HPKE |
| `ws` | WebSocket client |