Skip to content
Open
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
152 changes: 129 additions & 23 deletions app/api/v1/paid/[product]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,133 @@ function paymentRequired(req: NextRequest, product: NonNullable<ReturnType<typeo
);
}

const VENDOR_LEAD_PROFILES = [
{
segment: 'mcp',
target: 'MCP servers with paid or data-heavy tools',
discovery_queries: ['topic:mcp server pricing', '"Model Context Protocol" "api key"', '"mcp" "paid tool"'],
signals: ['tool schema exposed', 'usage has data/API cost', 'clear buyer-agent workflow'],
base_score: 92,
pitch: 'Add an optional x402 payment gate and list the paid tool in Pyrimid so buyer agents can discover and purchase it.',
catalog_category: 'devtools',
},
{
segment: 'agent-frameworks',
target: 'Agent frameworks with plugin or marketplace systems',
discovery_queries: ['agent framework marketplace', '"AI agent" plugins github', 'site:github.com agent toolkit marketplace'],
signals: ['plugin ecosystem', 'developer distribution channel', 'agent runtime already integrates external tools'],
base_score: 84,
pitch: 'Ship Pyrimid as a default paid-tool discovery layer so builders can earn affiliate USDC from product recommendations.',
catalog_category: 'agent-discovery',
},
{
segment: 'api-tools',
target: 'AI/API services with per-call cost or quota limits',
discovery_queries: ['"AI API" "pricing" "per request"', '"API" "credits" "agent"', 'site:github.com "x402" "api"'],
signals: ['metered pricing', 'machine-readable API docs', 'repeatable per-call value'],
base_score: 88,
pitch: 'Turn one high-value API call into an agent-purchasable x402 product with a Pyrimid catalog listing.',
catalog_category: 'api-tools',
},
] as const;

function normalizeToken(value?: string) {
return (value || '').trim().toLowerCase();
}

function scoreLead(profile: (typeof VENDOR_LEAD_PROFILES)[number], requestedSegment: string) {
const exactSegment = requestedSegment === profile.segment;
const broadRequest = !requestedSegment || requestedSegment === 'all';
return Math.min(100, profile.base_score + (exactSegment ? 7 : broadRequest ? 0 : -9));
}

function buildVendorLeadDiscovery(query: Record<string, string>) {
const requestedSegment = normalizeToken(query.segment) || 'mcp';
const limit = Math.max(1, Math.min(Number(query.limit) || 3, 5));

const leads = VENDOR_LEAD_PROFILES
.map((profile) => ({
segment: profile.segment,
target: profile.target,
fit_score: scoreLead(profile, requestedSegment),
priority: scoreLead(profile, requestedSegment) >= 90 ? 'high' : 'medium',
discovery_queries: profile.discovery_queries,
qualifying_signals: profile.signals,
pitch: profile.pitch,
suggested_product: {
product_id_hint: `${profile.segment}-paid-tool`,
category: profile.catalog_category,
price_range_usdc: '$0.05-$0.25 per call',
affiliate_bps: 2500,
},
next_step: 'Confirm the vendor has a callable tool/API, then ask for one paid endpoint to list with x402 and Pyrimid metadata.',
}))
.sort((a, b) => b.fit_score - a.fit_score)
.slice(0, limit);

return {
segment: requestedSegment,
scoring_model: {
max_score: 100,
factors: ['x402 fit', 'agent discoverability', 'per-call value', 'Pyrimid affiliate-distribution upside'],
},
leads,
clean_json_output: true,
};
}

function classifyMcpUrl(url: string) {
const text = normalizeToken(url);
if (/github|gitlab|repo/.test(text)) return 'code-hosted MCP server';
if (/search|crawl|browser|web/.test(text)) return 'web/search MCP server';
if (/data|market|price|signal|analytics/.test(text)) return 'data API MCP server';
if (/tool|api|mcp/.test(text)) return 'developer-tool MCP server';
return 'generic MCP server';
}

function buildMcpServerAudit(query: Record<string, string>) {
const url = query.url || 'https://example.com/mcp';
const serverType = classifyMcpUrl(url);
const requestedPrice = query.price || '$0.05';
const paidToolCandidates = [
{ name: 'search', price: requestedPrice, reason: 'Search-style tools have repeatable per-call value and clear buyer-agent intent.' },
{ name: 'enrich', price: '$0.10', reason: 'Enrichment often combines external data and compute, making per-call pricing natural.' },
{ name: 'export', price: '$0.05', reason: 'Export is easy to gate while leaving browse/list tools free for discovery.' },
{ name: 'analyze', price: '$0.25', reason: 'Analysis tools can justify higher prices when they consume model or data-provider budget.' },
];

return {
audit: {
url,
server_type: serverType,
monetization_readiness_score: serverType === 'generic MCP server' ? 72 : 86,
recommended_paid_tools: paidToolCandidates,
route_shape: {
unpaid_request: 'Return HTTP 402 with x402 accepts[] metadata when X-PAYMENT is missing.',
paid_retry: 'Verify X-PAYMENT or X-PAYMENT-TX on Base, then execute the paid MCP tool.',
free_discovery: 'Keep server info, tool list, and lightweight previews free so buyer agents can evaluate the product.',
},
catalog_metadata: {
tags: ['mcp', 'paid-tools', 'x402', 'base-usdc'],
output_schema_required: true,
agents_txt_hint: 'Advertise paid tool endpoints and pricing so buyer agents can preflight before payment.',
},
risk_notes: [
'Do not gate the MCP initialize/list_tools flow; gate only high-value tool calls.',
'Publish max price and output schema to reduce failed buyer-agent purchases.',
'Log payment tx hashes separately from user prompts or private tool inputs.',
],
launch_checklist: [
'Choose one paid tool with obvious per-call value',
'Add a 402/x402 challenge response for unpaid calls',
'Publish Pyrimid catalog metadata with price, endpoint, and output schema',
'Add an agents.txt or server card note describing the paid tool',
'Run one unpaid preflight and one paid retry demo',
],
},
};
}

function payload(productId: string, req: NextRequest, proof: string) {
const query = Object.fromEntries(req.nextUrl.searchParams.entries());

Expand Down Expand Up @@ -52,31 +179,10 @@ function payload(productId: string, req: NextRequest, proof: string) {
};
}
case 'vendor-lead-discovery': {
const segment = query.segment || 'mcp';
return {
segment,
leads: [
{ segment: 'mcp', target: 'MCP servers with paid/data-heavy tools', pitch: 'Add optional x402 payment gate + Pyrimid catalog listing.' },
{ segment: 'agent-frameworks', target: 'Agent frameworks with marketplace/plugin systems', pitch: 'Let builders sell tools to agents with Base USDC settlement.' },
{ segment: 'api-tools', target: 'AI API services with per-call cost', pitch: 'Turn API calls into agent-purchasable products.' },
],
};
return buildVendorLeadDiscovery(query);
}
case 'mcp-server-audit': {
const url = query.url || 'https://example.com/mcp';
return {
audit: {
url,
recommended_paid_tools: ['search', 'enrich', 'export', 'analyze'],
pricing: '$0.01-$0.25 per call depending on compute/data cost',
integration_steps: [
'Add 402 response with x402 accepts[] metadata',
'Register vendor/product in Pyrimid catalog',
'Expose tool schema in MCP server card',
'Add affiliateBps for distribution agents',
],
},
};
return buildMcpServerAudit(query);
}
case 'x402-integration-plan': {
const service = query.service || 'agent-api';
Expand Down