Connect Ad Platform
platform_connectRegister a Google Ads or Meta Ads account in the AdOps workspace to enable campaign management tools. Accepts platform, name, and account ID; returns active connection.
Instructions
Register a Google Ads or Meta Ads account in the AdOps workspace so subsequent tools (campaign_list, campaign_create, ads_report) can target it. Input: platform ("google_ads"|"meta_ads"), name (display label), account_id (the external ad account id). Returns the stored connection object with a generated UUID and status="active". Safe to call with the same platform+account_id — returns the existing connection instead of erroring (idempotent).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| platform | Yes | Ad platform to connect | |
| name | Yes | Friendly connection name | |
| account_id | Yes | Platform-specific ad account ID (Google: 10 digits, Meta: act_XXXXXXXXX) |
Implementation Reference
- src/index.ts:193-230 (registration)The tool 'platform_connect' is registered with the MCP server using server.registerTool(), with inputSchema from PlatformConnectInputSchema and an async handler function.
// ── Tool 1: platform_connect ──────────────────────────────────────── server.registerTool( 'platform_connect', { title: 'Connect Ad Platform', description: 'Register a Google Ads or Meta Ads account in the AdOps workspace so subsequent tools (campaign_list, campaign_create, ads_report) can target it. Input: platform ("google_ads"|"meta_ads"), name (display label), account_id (the external ad account id). Returns the stored connection object with a generated UUID and status="active". Safe to call with the same platform+account_id — returns the existing connection instead of erroring (idempotent).', inputSchema: PlatformConnectInputSchema, annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false }, }, async ({ platform, name, account_id }) => { try { const existing = await storage.getAllConnections(); const duplicate = existing.find((c) => c.platform === platform && c.account_id === account_id); if (duplicate) { return { content: [{ type: 'text' as const, text: JSON.stringify({ message: 'Connection already exists', connection: duplicate, }, null, 2) }] }; } const conn = await storage.addConnection({ id: uuidv4(), platform, name, account_id, connected_at: new Date().toISOString(), last_sync_at: null, status: 'active', }); return { content: [{ type: 'text' as const, text: JSON.stringify({ message: `Successfully connected ${platform} account "${name}"`, connection: conn, }, null, 2) }] }; } catch (e) { return handleToolError(e); } }, ); - src/index.ts:203-229 (handler)The handler function for platform_connect that checks for duplicate connections (idempotent), creates a new PlatformConnection object with a UUID, and stores it via storage.addConnection().
async ({ platform, name, account_id }) => { try { const existing = await storage.getAllConnections(); const duplicate = existing.find((c) => c.platform === platform && c.account_id === account_id); if (duplicate) { return { content: [{ type: 'text' as const, text: JSON.stringify({ message: 'Connection already exists', connection: duplicate, }, null, 2) }] }; } const conn = await storage.addConnection({ id: uuidv4(), platform, name, account_id, connected_at: new Date().toISOString(), last_sync_at: null, status: 'active', }); return { content: [{ type: 'text' as const, text: JSON.stringify({ message: `Successfully connected ${platform} account "${name}"`, connection: conn, }, null, 2) }] }; } catch (e) { return handleToolError(e); } }, - src/models/adops.ts:378-389 (schema)PlatformConnectInputSchema defines the input validation for platform_connect: platform (google|meta), name (1-100 chars), account_id with format validation via .refine().
export const PlatformConnectInputSchema = z.object({ platform: PlatformSchema.describe('Ad platform to connect'), name: z.string().min(1).max(100).describe('Friendly connection name'), account_id: z.string().min(1).describe('Platform-specific ad account ID (Google: 10 digits, Meta: act_XXXXXXXXX)'), }).refine( (data) => { if (data.platform === 'google') return /^\d{10}$/.test(data.account_id.replace(/-/g, '')); if (data.platform === 'meta') return /^act_\d+$/.test(data.account_id); return true; }, { message: 'Invalid account ID format. Google: 10 digits (no dashes). Meta: act_XXXXXXXXX.' }, ); - src/models/adops.ts:28-37 (schema)PlatformConnectionSchema defines the structure of the connection object returned/stored by platform_connect, including id, platform, name, account_id, connected_at, last_sync_at, and status.
export const PlatformConnectionSchema = z.object({ id: z.string().uuid(), platform: PlatformSchema, name: z.string().describe('Friendly connection name'), account_id: z.string().describe('Platform-specific account ID'), connected_at: z.string(), last_sync_at: z.string().nullable(), status: z.enum(['active', 'expired', 'error']), }); export type PlatformConnection = z.infer<typeof PlatformConnectionSchema>; - src/services/storage.ts:82-103 (helper)Storage helper methods used by the platform_connect handler: getAllConnections() to check for duplicates, and addConnection() to persist the new PlatformConnection.
async getAllConnections(): Promise<PlatformConnection[]> { return this.read<PlatformConnection[]>(this.connectionsPath); } async getConnectionById(id: string): Promise<PlatformConnection | null> { const conns = await this.read<PlatformConnection[]>(this.connectionsPath); return conns.find((c) => c.id === id) ?? null; } async getConnectionsByPlatform(platform: string): Promise<PlatformConnection[]> { const conns = await this.read<PlatformConnection[]>(this.connectionsPath); return conns.filter((c) => c.platform === platform); } async addConnection(conn: PlatformConnection): Promise<PlatformConnection> { return this.lock.run(async () => { const conns = await this.read<PlatformConnection[]>(this.connectionsPath); conns.push(conn); await this.write(this.connectionsPath, conns); return conn; }); }