Plugins for the Ad Context Protocol (AdCP) ecosystem
npx claudepluginhub adcontextprotocol/adcp-clientAdds the /adcp skill for calling AdCP advertising agent tools over MCP or A2A, running protocol compliance scenarios, and querying the AdCP registry. Includes built-in test agents for zero-config use. Backed by the `@adcp/sdk` npm package (formerly `@adcp/client`).
Claude Code marketplace entries for the plugin-safe Antigravity Awesome Skills library and its compatible editorial bundles.
Production-ready workflow orchestration with 79 focused plugins, 184 specialized agents, and 150 skills - optimized for granular installation and minimal token usage
Directory of popular Claude Code extensions including development tools, productivity plugins, and MCP integrations
Share bugs, ideas, or general feedback.
Official TypeScript/JavaScript client for the Ad Context Protocol (AdCP). Build distributed advertising operations that work synchronously OR asynchronously with the same code.
AdCP operations are distributed and asynchronous by default. An agent might:
Your code stays the same. You write handlers once, and they work for both sync completions and webhook deliveries.
npm install @adcp/client
import { ADCPMultiAgentClient } from '@adcp/client';
// Configure agents and handlers
const client = new ADCPMultiAgentClient([
{
id: 'agent_x',
agent_uri: 'https://agent-x.com',
protocol: 'a2a'
},
{
id: 'agent_y',
agent_uri: 'https://agent-y.com/mcp/',
protocol: 'mcp'
}
], {
// Webhook URL template (macros: {agent_id}, {task_type}, {operation_id})
webhookUrlTemplate: 'https://myapp.com/webhook/{task_type}/{agent_id}/{operation_id}',
// Activity callback - fires for ALL events (requests, responses, status changes, webhooks)
onActivity: (activity) => {
console.log(`[${activity.type}] ${activity.task_type} - ${activity.operation_id}`);
// Log to monitoring, update UI, etc.
},
// Status change handlers - called for ALL status changes (completed, failed, input-required, working, etc)
handlers: {
onGetProductsStatusChange: (response, metadata) => {
// Called for sync completion, async webhook, AND status changes
console.log(`[${metadata.status}] Got products for ${metadata.operation_id}`);
if (metadata.status === 'completed') {
db.saveProducts(metadata.operation_id, response.products);
} else if (metadata.status === 'failed') {
db.markFailed(metadata.operation_id, metadata.message);
} else if (metadata.status === 'input-required') {
// Handle clarification needed
console.log('Needs input:', metadata.message);
}
}
}
});
// Execute operation - library handles operation IDs, webhook URLs, context management
const agent = client.agent('agent_x');
const result = await agent.getProducts({ brief: 'Coffee brands' });
// onActivity fired: protocol_request
// onActivity fired: protocol_response
// Check result
if (result.status === 'completed') {
// Agent completed synchronously!
console.log('✅ Sync completion:', result.data.products.length, 'products');
// onGetProductsStatusChange handler ALREADY fired with status='completed' ✓
}
if (result.status === 'submitted') {
// Agent will send webhook when complete
console.log('⏳ Async - webhook registered at:', result.submitted?.webhookUrl);
// onGetProductsStatusChange handler will fire when webhook arrives ✓
}
When an agent needs more information, you can continue the conversation:
const result = await agent.getProducts({ brief: 'Coffee brands' });
if (result.status === 'input-required') {
console.log('❓ Agent needs clarification:', result.metadata.inputRequest?.question);
// onActivity fired: status_change (input-required)
// Continue the conversation with the same agent
const refined = await agent.continueConversation('Only premium brands above $50');
// onActivity fired: protocol_request
// onActivity fired: protocol_response
if (refined.status === 'completed') {
console.log('✅ Got refined results:', refined.data.products.length);
// onGetProductsStatusChange handler fired ✓
}
}
All webhooks (task completions AND notifications) use one endpoint with flexible URL templates.
const client = new ADCPMultiAgentClient(agents, {
// Path-based (default pattern)
webhookUrlTemplate: 'https://myapp.com/webhook/{task_type}/{agent_id}/{operation_id}',