Skip to content

Conversation

@JonasJesus42
Copy link
Contributor

@JonasJesus42 JonasJesus42 commented Jan 7, 2026

Summary by cubic

Adds a new Google Tag Manager MCP server and expands the Meta Ads MCP with full create/update/delete flows. This enables managing GTM resources via OAuth and running complete Meta Ads campaign workflows.

  • New Features

    • Google Tag Manager MCP: new package with PKCE OAuth, typed GTM client, and tools to manage accounts, containers, workspaces (including delete), tags, triggers, and variables. Includes app.json for registry and integration with the runtime.
    • Meta Ads MCP: new CRUD tools and client methods for campaigns, ad sets, ads, and creatives, plus updated README with a step‑by‑step flow.
  • Bug Fixes

    • Meta Ads: replace Zod prefault with default, JSON‑serialize targeting for the API, handle missing ASSETS in dev, relax targeting schema, and remove image upload tool due to permissions.
    • GTM: allow partial updates for tags, triggers, and variables; update optional/required fields; remove debug logs.

Written for commit 4109149. Summary will update on new commits.

@JonasJesus42 JonasJesus42 force-pushed the feat/google-tag-manager branch from 0a84320 to f31439e Compare January 7, 2026 06:38
Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 issues found across 29 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="meta-ads/server/lib/types.ts">

<violation number="1" location="meta-ads/server/lib/types.ts:317">
P2: Type inconsistency: `bid_strategy` is typed as `string` but should use the `BidStrategy` type for consistency with `CreateAdSetParams`, `UpdateAdSetParams`, and for proper type safety. This prevents passing invalid values that would be rejected by the Meta API at runtime.</violation>
</file>

<file name="meta-ads/README.md">

<violation number="1" location="meta-ads/README.md:56">
P3: Incorrect tool count in section header. The table lists 6 tools but the header says '5 tools'.</violation>
</file>

<file name="google-tag-manager/server/main.ts">

<violation number="1" location="google-tag-manager/server/main.ts:22">
P1: Module-level `lastRedirectUri` creates a race condition in concurrent environments. Multiple OAuth flows will overwrite each other's redirect URIs, causing token exchange failures. Consider passing the redirect_uri through the OAuth state parameter instead, or storing it in a proper session/cache keyed by user session.</violation>
</file>

<file name="meta-ads/server/tools/campaigns.ts">

<violation number="1" location="meta-ads/server/tools/campaigns.ts:310">
P2: Defaulting to `true` when `response.success` is undefined could mask API failures. Consider using a pattern similar to createCreateCampaignTool that determines success based on concrete evidence, or at minimum use `!!response.success` to ensure a false value when undefined.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

].join(" ");

// Store the last used redirect_uri for token exchange
let lastRedirectUri: string | null = null;
Copy link

@cubic-dev-ai cubic-dev-ai bot Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Module-level lastRedirectUri creates a race condition in concurrent environments. Multiple OAuth flows will overwrite each other's redirect URIs, causing token exchange failures. Consider passing the redirect_uri through the OAuth state parameter instead, or storing it in a proper session/cache keyed by user session.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At google-tag-manager/server/main.ts, line 22:

<comment>Module-level `lastRedirectUri` creates a race condition in concurrent environments. Multiple OAuth flows will overwrite each other's redirect URIs, causing token exchange failures. Consider passing the redirect_uri through the OAuth state parameter instead, or storing it in a proper session/cache keyed by user session.</comment>

<file context>
@@ -0,0 +1,124 @@
+].join(" ");
+
+// Store the last used redirect_uri for token exchange
+let lastRedirectUri: string | null = null;
+
+const runtime = withRuntime<Env>({
</file context>
Fix with Cubic

lifetime_budget?: string;
start_time?: string;
stop_time?: string;
bid_strategy?: string;
Copy link

@cubic-dev-ai cubic-dev-ai bot Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Type inconsistency: bid_strategy is typed as string but should use the BidStrategy type for consistency with CreateAdSetParams, UpdateAdSetParams, and for proper type safety. This prevents passing invalid values that would be rejected by the Meta API at runtime.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At meta-ads/server/lib/types.ts, line 317:

<comment>Type inconsistency: `bid_strategy` is typed as `string` but should use the `BidStrategy` type for consistency with `CreateAdSetParams`, `UpdateAdSetParams`, and for proper type safety. This prevents passing invalid values that would be rejected by the Meta API at runtime.</comment>

<file context>
@@ -269,3 +269,385 @@ export interface ApiError {
+  lifetime_budget?: string;
+  start_time?: string;
+  stop_time?: string;
+  bid_strategy?: string;
+}
+
</file context>
Suggested change
bid_strategy?: string;
bid_strategy?: BidStrategy;
Fix with Cubic

});

return {
success: response.success ?? true,
Copy link

@cubic-dev-ai cubic-dev-ai bot Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Defaulting to true when response.success is undefined could mask API failures. Consider using a pattern similar to createCreateCampaignTool that determines success based on concrete evidence, or at minimum use !!response.success to ensure a false value when undefined.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At meta-ads/server/tools/campaigns.ts, line 310:

<comment>Defaulting to `true` when `response.success` is undefined could mask API failures. Consider using a pattern similar to createCreateCampaignTool that determines success based on concrete evidence, or at minimum use `!!response.success` to ensure a false value when undefined.</comment>

<file context>
@@ -136,8 +139,210 @@ export const createGetCampaignDetailsTool = (env: Env) =>
+      });
+
+      return {
+        success: response.success ?? true,
+      };
+    },
</file context>
Fix with Cubic

| `META_ADS_DELETE_ADSET` | Delete an ad set |

### Ads (3 tools)
### Ads (5 tools)
Copy link

@cubic-dev-ai cubic-dev-ai bot Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: Incorrect tool count in section header. The table lists 6 tools but the header says '5 tools'.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At meta-ads/README.md, line 56:

<comment>Incorrect tool count in section header. The table lists 6 tools but the header says '5 tools'.</comment>

<file context>
@@ -32,24 +35,38 @@ This MCP provides tools to analyze the performance of your Meta (Facebook/Instag
+| `META_ADS_DELETE_ADSET` | Delete an ad set |
 
-### Ads (3 tools)
+### Ads (5 tools)
 | Tool | Description |
 |------|-------------|
</file context>
Suggested change
### Ads (5 tools)
### Ads (6 tools)

✅ Addressed in cc9166c

@github-actions
Copy link

github-actions bot commented Jan 7, 2026

🚀 Preview Deployments Ready!

Your changes have been deployed to preview environments:

📦 google-tag-manager

🔗 View Preview

📦 meta-ads

🔗 View Preview

These previews will be automatically updated with new commits to this PR.


Deployed from commit: 377d555

@JonasJesus42 JonasJesus42 reopened this Jan 7, 2026
…ives

- Add create/update/delete methods for campaigns in meta-client
- Add create/update/delete methods for ad sets with targeting support
- Add create/update/delete methods for ads
- Add uploadAdImage and createAdCreative methods
- Add new types for all mutation operations
- Create META_ADS_CREATE_CAMPAIGN, UPDATE, DELETE tools
- Create META_ADS_CREATE_ADSET, UPDATE, DELETE tools
- Create META_ADS_CREATE_AD, UPDATE, DELETE tools
- Create META_ADS_UPLOAD_AD_IMAGE tool
- Create META_ADS_CREATE_AD_CREATIVE tool
- Add flow documentation in tool descriptions (5-step flow)
- Update README with new tools and usage examples
Meta API expects the targeting field to be a JSON string, not a plain object.
This fixes the 'Invalid parameter' error when creating/updating ad sets.
- Implement 23 tools for GTM management (accounts, containers, workspaces, tags, triggers, variables)
- Add proper OAuth PKCE flow with Google authentication
- Fix optional fields in API responses (shareData, fingerprint, publicId, description)
- Update operations require all mandatory fields (name, type)
- Remove delete_workspace (requires additional OAuth scope)
- All tools tested and validated with real GTM account

Tools included:
- List/Get: accounts, containers, workspaces, tags, triggers, variables
- Create: containers, workspaces, tags, triggers, variables
- Update: tags, triggers, variables (with required fields)
- Delete: containers, tags, triggers, variables
@JonasJesus42 JonasJesus42 force-pushed the feat/google-tag-manager branch from f31439e to 4109149 Compare January 7, 2026 20:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants