Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jest.config.js
openapi.yaml
media-agent-openapi.yaml
outcome-agent-openapi.yaml
partner-api.yaml
storefront-api.yaml
platform-api.yaml

# Test files
Expand Down
111 changes: 84 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Scope3 SDK

TypeScript client for the Scope3 Agentic Platform. Supports two personas (buyer, partner) with REST and MCP adapters.
TypeScript client for the Scope3 Agentic Platform. Two entry points for two audiences:

- **REST consumers** (humans, CLI, programmatic) → `Scope3Client` with typed resource methods
- **MCP consumers** (AI agents) → `Scope3McpClient` — thin connection helper with direct `callTool`/`readResource`

## Installation

Expand All @@ -24,11 +27,11 @@ Obtain your API key from the Scope3 dashboard:

## Quick Start

The SDK uses a unified `Scope3Client` with a `persona` parameter to determine available resources.
### REST Client (Humans / CLI / Programmatic)

### Buyer Persona
The `Scope3Client` provides typed resource methods and requires a `persona` parameter.

For programmatic advertising -- manage advertisers, bundles, campaigns, and signals.
#### Buyer Persona

```typescript
import { Scope3Client } from 'scope3';
Expand Down Expand Up @@ -66,41 +69,89 @@ const campaign = await client.campaigns.createDiscovery({
await client.campaigns.execute(campaign.data.id);
```

### Partner Persona

For partner and agent management.
#### Storefront Persona

```typescript
const partnerClient = new Scope3Client({
const sfClient = new Scope3Client({
apiKey: process.env.SCOPE3_API_KEY!,
persona: 'partner',
persona: 'storefront',
});

// List partners
const partners = await partnerClient.partners.list();
// Get your storefront
const sf = await sfClient.storefront.get();

// Register an agent
const agent = await partnerClient.agents.register({
name: 'My Agent',
// Create an inventory source (registers an agent)
const source = await sfClient.inventorySources.create({
sourceId: 'my-sales-agent',
name: 'My Sales Agent',
executionType: 'agent',
type: 'SALES',
partnerId: 'partner-123',
endpointUrl: 'https://my-agent.example.com/mcp',
protocol: 'MCP',
authenticationType: 'API_KEY',
auth: { type: 'bearer', token: 'my-api-key' },
});

// Check readiness
const readiness = await sfClient.readiness.check();
```

### MCP Client (AI Agents)

The `Scope3McpClient` is a thin connection helper for AI agents. It wires up auth and the MCP URL, then exposes `callTool()`, `readResource()`, and `listTools()` as direct passthroughs. The MCP server handles routing and validation — no typed resource wrappers needed.

```typescript
import { Scope3McpClient } from 'scope3';

const mcp = new Scope3McpClient({
apiKey: process.env.SCOPE3_API_KEY!,
});
await mcp.connect();

// Call tools directly — the v2 buyer surface exposes:
// api_call, ask_about_capability, help, health
const result = await mcp.callTool('api_call', {
method: 'GET',
path: '/api/v2/buyer/advertisers',
});

// Ask what the API can do
const capabilities = await mcp.callTool('ask_about_capability', {
question: 'How do I create a campaign?',
});

// List available tools
const tools = await mcp.listTools();

await mcp.disconnect();
```

## Configuration

### Scope3Client (REST)

```typescript
const client = new Scope3Client({
apiKey: 'your-api-key', // Required: Bearer token
persona: 'buyer', // Required: 'buyer' | 'partner'
persona: 'buyer', // Required: 'buyer' | 'storefront'
environment: 'production', // Optional: 'production' (default) | 'staging'
baseUrl: 'https://custom.com', // Optional: overrides environment
adapter: 'rest', // Optional: 'rest' (default) | 'mcp'
timeout: 30000, // Optional: request timeout in ms
debug: false, // Optional: enable debug logging
});
```

### Scope3McpClient (MCP)

```typescript
const mcp = new Scope3McpClient({
apiKey: 'your-api-key', // Required: Bearer token
environment: 'production', // Optional: 'production' (default) | 'staging'
baseUrl: 'https://custom.com', // Optional: overrides environment
debug: false, // Optional: enable debug logging
});
```

## CLI

```bash
Expand All @@ -115,7 +166,7 @@ scope3 campaigns list --format json
scope3 bundles create --advertiser-id adv-123 --channels display,video

# Override persona per-command
scope3 --persona partner partners list
scope3 --persona storefront storefront get

# See all commands
scope3 commands
Expand All @@ -125,17 +176,23 @@ scope3 commands

### Buyer Resources

- `client.advertisers` -- CRUD and sub-resources (conversionEvents, creativeSets, testCohorts)
- `client.campaigns` -- list, get, createDiscovery, updateDiscovery, createPerformance, updatePerformance, createAudience, execute, pause
- `client.advertisers` -- CRUD and sub-resources (conversionEvents, creativeSets, testCohorts, eventSources, measurementData, catalogs, audiences, syndication, propertyLists)
- `client.campaigns` -- list, get, createDiscovery, updateDiscovery, createPerformance, updatePerformance, createAudience, execute, pause, creatives(campaignId)
- `client.bundles` -- create, discoverProducts, browseProducts, products(bundleId)
- `client.signals` -- Discover signals
- `client.reporting` -- Get reporting metrics
- `client.salesAgents` -- List sales agents, register accounts
- `client.tasks` -- Get task status
- `client.propertyListChecks` -- Run and retrieve property list check reports

### Partner Resources
### Storefront Resources

- `client.partners` -- list, create, update, archive
- `client.agents` -- list, get, register, update
- `client.storefront` -- get, create, update, delete
- `client.inventorySources` -- list, get, create, update, delete
- `client.agents` -- list, get, update
- `client.readiness` -- check
- `client.billing` -- get, connect, status, transactions, payouts, onboardingUrl
- `client.notifications` -- list, markAsRead, acknowledge, markAllAsRead

## skill.md Support

Expand Down Expand Up @@ -176,29 +233,29 @@ The SDK is manually maintained. When the Agentic API changes, update these files
1. Check the latest skill.md for your persona:
```bash
curl https://api.agentic.scope3.com/api/v2/buyer/skill.md
curl https://api.agentic.scope3.com/api/v2/partner/skill.md
curl https://api.agentic.scope3.com/api/v2/storefront/skill.md
```
2. Compare against `src/skill/bundled.ts` and update if needed
3. Update types in `src/types/index.ts` to match any schema changes
4. Update resource methods in `src/resources/` for endpoint changes
5. Update CLI commands in `src/cli/commands/` if applicable
6. Run `npm test` and `npm run build` to verify
7. Run manual workflow tests: `npm run test:buyer`, `npm run test:partner`
7. Run manual workflow tests: `npm run test:buyer`, `npm run test:storefront`

### Integration Tests

```bash
export SCOPE3_API_KEY=your_key
npm run test:buyer # Buyer workflow
npm run test:partner # Partner workflow
npm run test:storefront # Storefront workflow
npm run test:all # All workflows
```

## Documentation

- [Getting Started](docs/getting-started.md)
- [Buyer Guide](docs/buyer-guide.md)
- [Partner Guide](docs/partner-guide.md)
- [Storefront Guide](docs/storefront-guide.md)
- [CLI Reference](docs/cli-reference.md)

## Contributing
Expand Down
13 changes: 7 additions & 6 deletions docs/TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Run the test suite:
npm test
```

This runs 211 unit tests covering:
This runs 384+ unit tests covering:
- Client initialization
- REST and MCP adapters
- All resource classes
Expand All @@ -28,8 +28,8 @@ export SCOPE3_API_KEY=your_api_key
./dist/cli/index.js campaigns list
./dist/cli/index.js bundles create --advertiser-id <id> --channels display

# Test partner persona
./dist/cli/index.js --persona partner partners list
# Test storefront persona
./dist/cli/index.js --persona storefront storefront get

# Test config
./dist/cli/index.js config set apiKey your_key
Expand All @@ -48,7 +48,7 @@ export SCOPE3_API_KEY=your_api_key

# CLI workflow tests
npm run test:buyer # Buyer persona: advertisers, bundles, campaigns
npm run test:partner # Partner persona: health check
npm run test:storefront # Storefront persona: health check

# TypeScript SDK test
npm run test:sdk
Expand All @@ -75,9 +75,10 @@ export SCOPE3_ENVIRONMENT=staging
- Bundle creation and product discovery
- Campaign creation and lifecycle

### Partner Workflow (`test-partner-workflow.sh`)
- Partner listing
### Storefront Workflow (`test-storefront-workflow.sh`)
- Storefront get
- Agent listing
- Inventory source listing
- Config management
- Skill.md fetching

Expand Down
93 changes: 89 additions & 4 deletions docs/buyer-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@

The buyer persona enables AI-powered programmatic advertising with:

- Advertiser management
- Advertiser management with rich sub-resources (conversion events, creative sets, test cohorts, event sources, measurement data, catalogs, audiences, syndication, property lists)
- Bundle-based inventory discovery
- 3 campaign types (discovery, performance, audience)
- 3 campaign types (discovery, performance, audience) with creative management
- Reporting and analytics
- Reporting and sales agents
- Sales agents
- Async task tracking
- Property list checks

## Setup

Expand Down Expand Up @@ -130,6 +132,19 @@ Signal-based audience targeting (coming soon).
await client.campaigns.createAudience({ ... });
```

## Campaign Sub-Resources

### Creatives

```typescript
const creatives = client.campaigns.creatives(campaignId);
await creatives.list();
await creatives.list({ quality: 'high', take: 5 });
await creatives.get('creative-123');
await creatives.update('creative-123', { /* updates */ });
await creatives.delete('creative-123');
```

## Advertiser Sub-Resources

Access sub-resources scoped to an advertiser.
Expand Down Expand Up @@ -158,6 +173,67 @@ await cohorts.list();
await cohorts.create({ name: 'A/B Test', splitPercentage: 50 });
```

### Event Sources

```typescript
const eventSources = client.advertisers.eventSources(advId);
await eventSources.sync({ /* event source config */ });
await eventSources.list();
await eventSources.create({ /* event source data */ });
await eventSources.get('es-123');
await eventSources.update('es-123', { /* updates */ });
await eventSources.delete('es-123');
```

### Measurement Data

```typescript
const measurementData = client.advertisers.measurementData(advId);
await measurementData.sync({ /* measurement data config */ });
```

### Catalogs

```typescript
const catalogs = client.advertisers.catalogs(advId);
await catalogs.sync({ /* catalog data */ });
await catalogs.list();
await catalogs.list({ type: 'product', take: 10 });
```

### Audiences

```typescript
const audiences = client.advertisers.audiences(advId);
await audiences.sync({ /* audience data */ });
await audiences.list();
```

### Syndication

```typescript
const syndication = client.advertisers.syndication(advId);
await syndication.syndicate({ /* syndication config */ });
await syndication.status();
await syndication.status({ resourceType: 'campaign' });
```

### Property Lists

```typescript
const propertyLists = client.advertisers.propertyLists(advId);
await propertyLists.create({ /* property list data */ });
await propertyLists.list();
await propertyLists.list({ purpose: 'inclusion' });
await propertyLists.get('pl-123');
await propertyLists.update('pl-123', { /* updates */ });
await propertyLists.delete('pl-123');

// Top-level property list checks (not advertiser-scoped)
await client.propertyListChecks.check({ domains: ['example.com'] });
await client.propertyListChecks.getReport('report-123');
```

## Signals

```typescript
Expand All @@ -184,10 +260,19 @@ const agents = await client.salesAgents.list();

// Register an account for an agent
await client.salesAgents.registerAccount('agent-123', {
name: 'My Account',
advertiserId: 'adv-123',
accountIdentifier: 'my-account-id',
});
```

## Tasks

Check the status of async tasks.

```typescript
const task = await client.tasks.get('task-123');
```

## Pagination

All list methods support pagination:
Expand Down
Loading
Loading