get_publisher_metadata
Retrieve detailed metadata for digital advertising publishers using OpenSincera API by entering a publisher ID or domain. Supports result filtering with limit and offset parameters.
Instructions
Get publisher metadata from OpenSincera API. Requires either publisherId or publisherDomain.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of results to return (1-100) | |
| offset | No | Number of results to skip | |
| publisherDomain | No | Publisher domain to search for | |
| publisherId | No | Publisher ID to search for |
Implementation Reference
- src/index.ts:141-168 (handler)MCP CallToolRequestSchema handler case for 'get_publisher_metadata': validates input with schema, calls OpenSinceraService.getPublisherMetadata, formats results with descriptions, constructs and returns MCP content responsecase '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-37 (schema)Zod input validation schema for get_publisher_metadata toolconst 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:57-94 (registration)Tool registration in ListToolsRequestSchema response: defines name 'get_publisher_metadata', detailed description, and JSON inputSchema matching Zod schema{ 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/opensincera-service.ts:120-252 (helper)OpenSinceraService.getPublisherMetadata: core helper function implementing API call to retrieve and map publisher metadata from OpenSincera API, with comprehensive error handlingasync 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 || '', publisherDomain: publisherData.owner_domain || request.publisherDomain || '', 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', 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/opensincera-service.ts:10-46 (schema)TypeScript interfaces defining request, response, and PublisherMetadata types used by getPublisherMetadataexport interface GetPublisherMetadataRequest { publisherId?: string; publisherDomain?: string; limit?: number; offset?: number; } export interface PublisherMetadata { publisherId: string; publisherName: string; publisherDomain: string; status: 'active' | 'inactive' | 'suspended'; lastUpdated: string; contactEmail?: string; categories: string[]; verificationStatus: 'verified' | 'unverified' | 'pending'; metadata?: { description?: string; primarySupplyType?: string; avgAdsToContentRatio?: number; avgAdsInView?: number; avgAdRefresh?: number; totalUniqueGpids?: number; idAbsorptionRate?: number; avgPageWeight?: number; avgCpu?: number; totalSupplyPaths?: number; resellerCount?: number; slug?: string; }; } export interface GetPublisherMetadataResponse { publishers: PublisherMetadata[]; totalCount: number; hasMore: boolean; }