get_publisher_metadata
Retrieve comprehensive publisher metadata including performance metrics, verification status, and supply chain details from the OpenSincera API using publisher ID or domain.
Instructions
Get detailed publisher metadata from OpenSincera API with comprehensive field descriptions. Requires either publisherId or publisherDomain.
Returns publisher information including:
Basic Info: Publisher ID, name, domain, status, verification status, contact info, categories
Performance Metrics: Ads to Content Ratio (A2CR), Ads in View, Ad Refresh Rate, Page Weight, CPU Usage
Supply Chain: Total Supply Paths, Reseller Count, Global Publisher IDs (GPIDs)
Identity: ID Absorption Rate
Each metric includes detailed explanations of what it measures and its business implications.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| publisherId | No | Publisher ID to search for | |
| publisherDomain | No | Publisher domain to search for | |
| limit | No | Maximum number of results to return (1-100) | |
| offset | No | Number of results to skip |
Implementation Reference
- src/opensincera-service.ts:123-258 (handler)Core handler function in OpenSinceraService that performs the actual API request to OpenSincera, processes the response, maps to PublisherMetadata, and handles errors. This is the primary execution logic for the tool.async getPublisherMetadata( request: GetPublisherMetadataRequest = {} ): Promise<GetPublisherMetadataResponse> { try { let endpoint: string; if (request.publisherId) { endpoint = `/publishers?id=${encodeURIComponent(request.publisherId)}`; } else if (request.publisherDomain) { endpoint = `/publishers?domain=${encodeURIComponent(request.publisherDomain)}`; } else { throw new Error('Either publisherId or publisherDomain is required'); } console.error('Making OpenSincera API request', { baseUrl: this.config.baseUrl, endpoint, headers: { Authorization: this.config.apiKey ? 'Bearer [REDACTED]' : 'No API key', }, }); const response: AxiosResponse<any> = await this.client.get(endpoint); console.error('OpenSincera API response', { status: response.status, statusText: response.statusText, dataType: Array.isArray(response.data) ? 'array' : typeof response.data, dataLength: Array.isArray(response.data) ? response.data.length : 'N/A', hasData: !!response.data, }); if (response.status === 200) { const responseData = response.data; let publisherData: any = null; if (Array.isArray(responseData) && responseData.length > 0) { publisherData = responseData[0]; } else if (responseData && typeof responseData === 'object' && responseData.publisher_id) { publisherData = responseData; } if (publisherData) { const mappedPublisher: PublisherMetadata = { publisherId: publisherData.publisher_id || publisherData.id || '', publisherName: publisherData.name || '', ownerDomain: publisherData.owner_domain || request.publisherDomain || '', domain: publisherData.domain, status: this.mapStatus(publisherData.status), lastUpdated: publisherData.updated_at || new Date().toISOString(), contactEmail: publisherData.contact_email, categories: Array.isArray(publisherData.categories) ? publisherData.categories : publisherData.categories?.split(';') || [], verificationStatus: publisherData.visit_enabled ? 'verified' : 'unverified', parentEntityId: publisherData.parent_entity_id, similarPublishers: publisherData.similar_publishers?.content, metadata: { description: publisherData.pub_description, primarySupplyType: publisherData.primary_supply_type, avgAdsToContentRatio: publisherData.avg_ads_to_content_ratio, avgAdsInView: publisherData.avg_ads_in_view, avgAdRefresh: publisherData.avg_ad_refresh, totalUniqueGpids: publisherData.total_unique_gpids, idAbsorptionRate: publisherData.id_absorption_rate, avgPageWeight: publisherData.avg_page_weight, avgCpu: publisherData.avg_cpu, totalSupplyPaths: publisherData.total_supply_paths, resellerCount: publisherData.reseller_count, slug: publisherData.slug, }, }; return { publishers: [mappedPublisher], totalCount: 1, hasMore: false, }; } else { return { publishers: [], totalCount: 0, hasMore: false, }; } } if (response.status === 401) { throw new Error('Invalid API key or authentication failed'); } if (response.status === 403) { throw new Error('Access forbidden - insufficient permissions'); } if (response.status === 404) { throw new Error('Publisher not found'); } if (response.status === 429) { throw new Error('Rate limit exceeded - please try again later'); } throw new Error(`API request failed with status ${response.status}: ${response.statusText}`); } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; console.error('Failed to get publisher metadata', { error: errorMessage, request, }); if ( axios.isAxiosError(error) && (error.code === 'ENOTFOUND' || error.code === 'ECONNREFUSED') ) { console.error('OpenSincera API network error - check endpoint URL and connectivity', { domain: request.publisherDomain, publisherId: request.publisherId, baseUrl: this.config.baseUrl, errorCode: error.code, }); } if (axios.isAxiosError(error)) { if (error.response?.data?.error) { const apiError = error.response.data.error as OpenSinceraApiError; throw new Error(`OpenSincera API Error: ${apiError.message} (${apiError.code})`); } throw new Error( `HTTP ${error.response?.status}: ${error.response?.statusText || errorMessage}` ); } throw error; } }
- src/index.ts:140-167 (handler)MCP tool dispatch handler in index.ts that validates input with schema, calls the service handler, formats output with descriptions, and constructs the MCP response.case 'get_publisher_metadata': { const input = GetPublisherMetadataSchema.parse(request.params.arguments); const result = await openSinceraService.getPublisherMetadata(input); if (result.publishers.length > 0) { const formattedPublishers = result.publishers .map((pub) => formatPublisherWithDescriptions(pub, 'en')) .join('\n\n---\n\n'); return { content: [ { type: 'text', text: `Found ${result.totalCount} publisher(s):\n\n${formattedPublishers}`, }, ], }; } else { return { content: [ { type: 'text', text: 'No publishers found matching the criteria.', }, ], }; } }
- src/index.ts:27-36 (schema)Zod input validation schema for get_publisher_metadata tool parameters.const GetPublisherMetadataSchema = z .object({ publisherId: z.string().optional(), publisherDomain: z.string().optional(), limit: z.number().min(1).max(100).optional(), offset: z.number().min(0).optional(), }) .refine((data) => data.publisherId || data.publisherDomain, { message: 'Either publisherId or publisherDomain must be provided', });
- src/index.ts:56-93 (registration)Tool registration in ListToolsResponse, defining name, description, and inputSchema for get_publisher_metadata.{ name: 'get_publisher_metadata', description: `Get detailed publisher metadata from OpenSincera API with comprehensive field descriptions. Requires either publisherId or publisherDomain. Returns publisher information including: - Basic Info: Publisher ID, name, domain, status, verification status, contact info, categories - Performance Metrics: Ads to Content Ratio (A2CR), Ads in View, Ad Refresh Rate, Page Weight, CPU Usage - Supply Chain: Total Supply Paths, Reseller Count, Global Publisher IDs (GPIDs) - Identity: ID Absorption Rate Each metric includes detailed explanations of what it measures and its business implications.`, inputSchema: { type: 'object', properties: { publisherId: { type: 'string', description: 'Publisher ID to search for', }, publisherDomain: { type: 'string', description: 'Publisher domain to search for', }, limit: { type: 'number', description: 'Maximum number of results to return (1-100)', minimum: 1, maximum: 100, }, offset: { type: 'number', description: 'Number of results to skip', minimum: 0, }, }, required: [], additionalProperties: false, }, },
- src/metadata-descriptions.ts:172-308 (helper)Helper function used in the tool handler to format publisher metadata with comprehensive field descriptions for user-friendly output.export function formatPublisherWithDescriptions( publisher: any, language: 'en' | 'ja' = 'en' ): string { const lines: string[] = []; lines.push(`# ${publisher.publisherName || 'Unknown Publisher'}`); lines.push(''); // Basic Information lines.push('## Basic Information'); lines.push(`- **Publisher ID**: ${publisher.publisherId}`); lines.push(` ${getFieldDescription('publisherId', language)}`); lines.push(''); lines.push(`- **Owner Domain**: ${publisher.ownerDomain}`); lines.push(` ${getFieldDescription('ownerDomain', language)}`); lines.push(''); if (publisher.domain) { lines.push(`- **Domain**: ${publisher.domain}`); lines.push(` ${getFieldDescription('domain', language)}`); lines.push(''); } lines.push(`- **Status**: ${publisher.status}`); lines.push(` ${getStatusDescription(publisher.status, language)}`); lines.push(''); lines.push(`- **Verification Status**: ${publisher.verificationStatus}`); lines.push(` ${getVerificationDescription(publisher.verificationStatus, language)}`); lines.push(''); if (publisher.contactEmail) { lines.push(`- **Contact Email**: ${publisher.contactEmail}`); lines.push(` ${getFieldDescription('contactEmail', language)}`); lines.push(''); } if (publisher.categories && publisher.categories.length > 0) { lines.push(`- **Categories**: ${publisher.categories.join(', ')}`); lines.push(` ${getFieldDescription('categories', language)}`); lines.push(''); } lines.push(`- **Last Updated**: ${publisher.lastUpdated}`); lines.push(` ${getFieldDescription('lastUpdated', language)}`); lines.push(''); if (publisher.parentEntityId) { lines.push(`- **Parent Entity ID**: ${publisher.parentEntityId}`); lines.push(` ${getFieldDescription('parentEntityId', language)}`); lines.push(''); } if (publisher.similarPublishers && publisher.similarPublishers.length > 0) { lines.push(`- **Similar Publishers**: ${publisher.similarPublishers.join(', ')}`); lines.push(` ${getFieldDescription('similarPublishers', language)}`); lines.push(''); } // Metadata if (publisher.metadata) { lines.push('## Performance Metrics'); lines.push(''); const metadata = publisher.metadata; if (metadata.description) { lines.push(`### Description`); lines.push(metadata.description); lines.push(''); } if (metadata.primarySupplyType) { lines.push(`### Primary Supply Type: ${metadata.primarySupplyType}`); lines.push(getFieldDescription('primarySupplyType', language)); lines.push(''); } if (metadata.avgAdsToContentRatio !== undefined) { lines.push(`### Ads to Content Ratio: ${metadata.avgAdsToContentRatio}`); lines.push(getFieldDescription('avgAdsToContentRatio', language)); lines.push(''); } if (metadata.avgAdsInView !== undefined) { lines.push(`### Ads in View: ${metadata.avgAdsInView}`); lines.push(getFieldDescription('avgAdsInView', language)); lines.push(''); } if (metadata.avgAdRefresh !== undefined) { lines.push(`### Ad Refresh Rate: ${metadata.avgAdRefresh} seconds`); lines.push(getFieldDescription('avgAdRefresh', language)); lines.push(''); } if (metadata.totalUniqueGpids !== undefined) { lines.push(`### Total Unique GPIDs: ${metadata.totalUniqueGpids}`); lines.push(getFieldDescription('totalUniqueGpids', language)); lines.push(''); } if (metadata.idAbsorptionRate !== undefined) { lines.push(`### ID Absorption Rate: ${metadata.idAbsorptionRate}`); lines.push(getFieldDescription('idAbsorptionRate', language)); lines.push(''); } if (metadata.avgPageWeight !== undefined) { lines.push(`### Average Page Weight: ${metadata.avgPageWeight} KB`); lines.push(getFieldDescription('avgPageWeight', language)); lines.push(''); } if (metadata.avgCpu !== undefined) { lines.push(`### Average CPU Usage: ${metadata.avgCpu} seconds`); lines.push(getFieldDescription('avgCpu', language)); lines.push(''); } if (metadata.totalSupplyPaths !== undefined) { lines.push(`### Total Supply Paths: ${metadata.totalSupplyPaths}`); lines.push(getFieldDescription('totalSupplyPaths', language)); lines.push(''); } if (metadata.resellerCount !== undefined) { lines.push(`### Reseller Count: ${metadata.resellerCount}`); lines.push(getFieldDescription('resellerCount', language)); lines.push(''); } } return lines.join('\n'); }