Skip to content

Conversation

@JonasJesus42
Copy link
Contributor

@JonasJesus42 JonasJesus42 commented Jan 8, 2026

  • Added .gitignore to exclude node_modules, dist, and environment files.
  • Created app.json for Google Ads MCP configuration.
  • Initialized package.json with dependencies and scripts for development and build.
  • Added README.md with features, authentication details, and usage examples.
  • Set up TypeScript configuration in tsconfig.json.
  • Implemented server structure with constants, main entry, and environment handling.
  • Developed tools for account, campaign, ad group, ad, and keyword management.
  • Included reporting tools for performance metrics.
  • Defined types for Google Ads API interactions.

Summary by cubic

Initializes the Google Ads MCP server with OAuth PKCE and developer token support, plus a full toolset for accounts, campaigns, ad groups, ads, keywords, and reporting. Enables GAQL-based management of Google Ads through MCP with typed APIs and Deco runtime.

  • New Features

    • MCP server with Deco runtime and OAuth 2.0 PKCE (Google Ads scope).
    • Developer token support via runtime state for authenticated API calls.
    • Tools for listing, creating, updating, pausing/enabling: campaigns, ad groups, ads, keywords (including negative keywords).
    • Performance reports for account, campaign, ad group, and keyword metrics.
    • Typed client, endpoints, GAQL queries, and zod schemas.
    • App configuration, dev/build scripts, and TypeScript setup.
  • Migration

    • Set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET.
    • Provide the Google Ads developer token in the connection state.
    • Publish app.json and connect via Deco.
    • Run the server and complete OAuth auth; the runtime injects the access token for requests.

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

- Added .gitignore to exclude node_modules, dist, and environment files.
- Created app.json for Google Ads MCP configuration.
- Initialized package.json with dependencies and scripts for development and build.
- Added README.md with features, authentication details, and usage examples.
- Set up TypeScript configuration in tsconfig.json.
- Implemented server structure with constants, main entry, and environment handling.
- Developed tools for account, campaign, ad group, ad, and keyword management.
- Included reporting tools for performance metrics.
- Defined types for Google Ads API interactions.
@github-actions
Copy link

github-actions bot commented Jan 8, 2026

🚀 Preview Deployments Ready!

Your changes have been deployed to preview environments:

📦 cloudflare-docs

🔗 View Preview

📦 cloudflare-observability

🔗 View Preview

📦 cloudflare-workers

🔗 View Preview

📦 content-scraper

🔗 View Preview

📦 deco-llm

🔗 View Preview

📦 digitalocean-apps

🔗 View Preview

📦 digitalocean-databases

🔗 View Preview

📦 exa-search

🔗 View Preview

📦 github-mcp-server

🔗 View Preview

📦 google-ads

🔗 View Preview

📦 google-big-query

🔗 View Preview

📦 google-bigquery-official

🔗 View Preview

📦 google-calendar

🔗 View Preview

📦 google-gke-official

🔗 View Preview

📦 google-maps-official

🔗 View Preview

📦 google-tag-manager

🔗 View Preview

📦 hubspot-official

🔗 View Preview

📦 indeed-official

🔗 View Preview

📦 jam-dev

🔗 View Preview

📦 mcp-studio

🔗 View Preview

📦 mercadolibre-official

🔗 View Preview

📦 mercadopago-official

🔗 View Preview

📦 meta-ads

🔗 View Preview

📦 openrouter

🔗 View Preview

📦 registry

🔗 View Preview

📦 vercel-official

🔗 View Preview

📦 wix-official

🔗 View Preview

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


Deployed from commit: 06f1b21

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.

8 issues found across 18 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="google-ads/server/main.ts">

<violation number="1" location="google-ads/server/main.ts:19">
P1: Using module-level `lastRedirectUri` creates a race condition in concurrent OAuth flows. If multiple users authenticate simultaneously, their redirect URIs will overwrite each other, causing token exchange failures. Consider passing the redirect URI through the OAuth state parameter or using a session-based storage keyed by state/user.</violation>
</file>

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

<violation number="1" location="google-ads/server/tools/ads.ts:161">
P2: Schema validates array bounds but not individual string length constraints. Add `.max(30)` to headline strings and `.max(90)` to description strings to match the documented Google Ads API limits.</violation>
</file>

<file name="google-ads/server/tools/keywords.ts">

<violation number="1" location="google-ads/server/tools/keywords.ts:324">
P2: The update tool always returns `success: true` without validating that the response contains results. If the API returns empty results (which could indicate failure), this would mask the error. Consider adding validation consistent with `createCreateKeywordTool` that throws an error when `response.results[0]?.resourceName` is missing.</violation>
</file>

<file name="google-ads/server/lib/google-ads-client.ts">

<violation number="1" location="google-ads/server/lib/google-ads-client.ts:211">
P1: GAQL injection vulnerability: `statusFilter` is directly interpolated into the query string with single quotes. An attacker could inject additional query clauses. Consider validating the status value against an allowlist of valid enum values before interpolation.</violation>

<violation number="2" location="google-ads/server/lib/google-ads-client.ts:249">
P2: Unvalidated ID parameters are directly interpolated into GAQL queries. While IDs are expected to be numeric strings, consider validating with a regex like `/^\d+$/` or using parameterized queries if the API supports them to prevent injection attacks.</violation>
</file>

<file name="google-ads/tsconfig.json">

<violation number="1" location="google-ads/tsconfig.json:15">
P2: Options `declaration`, `declarationMap`, and `sourceMap` have no effect when `noEmit: true` is set. TypeScript's `noEmit` prevents all file emission including declarations. Consider removing these redundant options for clarity, or if declaration files are needed, use `emitDeclarationOnly: true` instead of `noEmit: true`.</violation>
</file>

<file name="google-ads/server/constants.ts">

<violation number="1" location="google-ads/server/constants.ts:254">
P2: The `campaignId` parameter is directly interpolated into the GAQL query without numeric validation. Consider validating that the ID contains only digits before interpolation to prevent potential GAQL injection:

```typescript
LIST_AD_GROUPS_BY_CAMPAIGN: (campaignId: string) => {
  if (!/^\d+$/.test(campaignId)) {
    throw new Error('Invalid campaign ID format');
  }
  return `SELECT ... WHERE campaign.id = ${campaignId} ...`;
}
```</violation>
</file>

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

<violation number="1" location="google-ads/server/tools/campaigns.ts:266">
P2: If campaign creation fails after the budget is created, the budget will be orphaned. Consider wrapping the campaign creation in a try-catch and deleting the budget on failure, or documenting this limitation.</violation>
</file>

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

const GOOGLE_ADS_SCOPES = ["https://www.googleapis.com/auth/adwords"].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 8, 2026

Choose a reason for hiding this comment

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

P1: Using module-level lastRedirectUri creates a race condition in concurrent OAuth flows. If multiple users authenticate simultaneously, their redirect URIs will overwrite each other, causing token exchange failures. Consider passing the redirect URI through the OAuth state parameter or using a session-based storage keyed by state/user.

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

<comment>Using module-level `lastRedirectUri` creates a race condition in concurrent OAuth flows. If multiple users authenticate simultaneously, their redirect URIs will overwrite each other, causing token exchange failures. Consider passing the redirect URI through the OAuth state parameter or using a session-based storage keyed by state/user.</comment>

<file context>
@@ -0,0 +1,125 @@
+const GOOGLE_ADS_SCOPES = ["https://www.googleapis.com/auth/adwords"].join(" ");
+
+// Store the last used redirect_uri for token exchange
+let lastRedirectUri: string | null = null;
+
+interface OAuthTokenResponse {
</file context>
Fix with Cubic

campaign.campaign_budget,
campaign.serving_status
FROM campaign
WHERE campaign.status = '${statusFilter}'
Copy link

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

Choose a reason for hiding this comment

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

P1: GAQL injection vulnerability: statusFilter is directly interpolated into the query string with single quotes. An attacker could inject additional query clauses. Consider validating the status value against an allowlist of valid enum values before interpolation.

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

<comment>GAQL injection vulnerability: `statusFilter` is directly interpolated into the query string with single quotes. An attacker could inject additional query clauses. Consider validating the status value against an allowlist of valid enum values before interpolation.</comment>

<file context>
@@ -0,0 +1,1015 @@
+          campaign.campaign_budget,
+          campaign.serving_status
+        FROM campaign
+        WHERE campaign.status = '${statusFilter}'
+        ORDER BY campaign.name
+      `;
</file context>
Fix with Cubic

finalUrls: z
.array(z.string())
.describe("Landing page URLs (usually just one URL)"),
headlines: z
Copy link

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

Choose a reason for hiding this comment

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

P2: Schema validates array bounds but not individual string length constraints. Add .max(30) to headline strings and .max(90) to description strings to match the documented Google Ads API limits.

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

<comment>Schema validates array bounds but not individual string length constraints. Add `.max(30)` to headline strings and `.max(90)` to description strings to match the documented Google Ads API limits.</comment>

<file context>
@@ -0,0 +1,309 @@
+      finalUrls: z
+        .array(z.string())
+        .describe("Landing page URLs (usually just one URL)"),
+      headlines: z
+        .array(z.string())
+        .min(3)
</file context>
Fix with Cubic

});

return {
resourceName:
Copy link

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

Choose a reason for hiding this comment

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

P2: The update tool always returns success: true without validating that the response contains results. If the API returns empty results (which could indicate failure), this would mask the error. Consider adding validation consistent with createCreateKeywordTool that throws an error when response.results[0]?.resourceName is missing.

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

<comment>The update tool always returns `success: true` without validating that the response contains results. If the API returns empty results (which could indicate failure), this would mask the error. Consider adding validation consistent with `createCreateKeywordTool` that throws an error when `response.results[0]?.resourceName` is missing.</comment>

<file context>
@@ -0,0 +1,466 @@
+      });
+
+      return {
+        resourceName:
+          response.results[0]?.resourceName || context.keywordResourceName,
+        success: true,
</file context>
Fix with Cubic

campaign.network_settings.target_search_network,
campaign.network_settings.target_content_network
FROM campaign
WHERE campaign.id = ${campaignId}
Copy link

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

Choose a reason for hiding this comment

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

P2: Unvalidated ID parameters are directly interpolated into GAQL queries. While IDs are expected to be numeric strings, consider validating with a regex like /^\d+$/ or using parameterized queries if the API supports them to prevent injection attacks.

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

<comment>Unvalidated ID parameters are directly interpolated into GAQL queries. While IDs are expected to be numeric strings, consider validating with a regex like `/^\d+$/` or using parameterized queries if the API supports them to prevent injection attacks.</comment>

<file context>
@@ -0,0 +1,1015 @@
+        campaign.network_settings.target_search_network,
+        campaign.network_settings.target_content_network
+      FROM campaign
+      WHERE campaign.id = ${campaignId}
+    `;
+
</file context>
Fix with Cubic

"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"isolatedModules": true,
"declaration": true,
Copy link

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

Choose a reason for hiding this comment

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

P2: Options declaration, declarationMap, and sourceMap have no effect when noEmit: true is set. TypeScript's noEmit prevents all file emission including declarations. Consider removing these redundant options for clarity, or if declaration files are needed, use emitDeclarationOnly: true instead of noEmit: true.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At google-ads/tsconfig.json, line 15:

<comment>Options `declaration`, `declarationMap`, and `sourceMap` have no effect when `noEmit: true` is set. TypeScript's `noEmit` prevents all file emission including declarations. Consider removing these redundant options for clarity, or if declaration files are needed, use `emitDeclarationOnly: true` instead of `noEmit: true`.</comment>

<file context>
@@ -0,0 +1,31 @@
+    "forceConsistentCasingInFileNames": true,
+    "resolveJsonModule": true,
+    "isolatedModules": true,
+    "declaration": true,
+    "declarationMap": true,
+    "sourceMap": true,
</file context>
Fix with Cubic

ad_group.type,
ad_group.cpc_bid_micros
FROM ad_group
WHERE campaign.id = ${campaignId}
Copy link

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

Choose a reason for hiding this comment

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

P2: The campaignId parameter is directly interpolated into the GAQL query without numeric validation. Consider validating that the ID contains only digits before interpolation to prevent potential GAQL injection:

LIST_AD_GROUPS_BY_CAMPAIGN: (campaignId: string) => {
  if (!/^\d+$/.test(campaignId)) {
    throw new Error('Invalid campaign ID format');
  }
  return `SELECT ... WHERE campaign.id = ${campaignId} ...`;
}
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At google-ads/server/constants.ts, line 254:

<comment>The `campaignId` parameter is directly interpolated into the GAQL query without numeric validation. Consider validating that the ID contains only digits before interpolation to prevent potential GAQL injection:

```typescript
LIST_AD_GROUPS_BY_CAMPAIGN: (campaignId: string) => {
  if (!/^\d+$/.test(campaignId)) {
    throw new Error('Invalid campaign ID format');
  }
  return `SELECT ... WHERE campaign.id = ${campaignId} ...`;
}
```</comment>

<file context>
@@ -0,0 +1,402 @@
+      ad_group.type,
+      ad_group.cpc_bid_micros
+    FROM ad_group
+    WHERE campaign.id = ${campaignId}
+    ORDER BY ad_group.name
+  `,
</file context>
Fix with Cubic

: undefined;

// Then, create the campaign
const campaignResponse = await client.createCampaign(context.customerId, {
Copy link

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

Choose a reason for hiding this comment

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

P2: If campaign creation fails after the budget is created, the budget will be orphaned. Consider wrapping the campaign creation in a try-catch and deleting the budget on failure, or documenting this limitation.

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

<comment>If campaign creation fails after the budget is created, the budget will be orphaned. Consider wrapping the campaign creation in a try-catch and deleting the budget on failure, or documenting this limitation.</comment>

<file context>
@@ -0,0 +1,456 @@
+        : undefined;
+
+      // Then, create the campaign
+      const campaignResponse = await client.createCampaign(context.customerId, {
+        name: context.name,
+        advertisingChannelType:
</file context>
Fix with Cubic

mcandeia and others added 27 commits January 9, 2026 18:38
Signed-off-by: Marcos Candeia <marrcooos@gmail.com>
- Migrate from old Cloudflare Workers structure to new Bun runtime
- Implement Google OAuth PKCE flow (based on google-calendar pattern)
- Add BigQueryClient class with full API support
- Create 4 tools: query, list_datasets, list_tables, get_table_schema
- Use @decocms/runtime and createPrivateTool pattern
- Add proper TypeScript types for all BigQuery API responses
- Changed app name from "Grain mcp" to "grain-mcp" and added "Grain Official" as the frandryName.
- Updated category to "Collaboration".
- Translated README content from Portuguese to English for better accessibility.
- Improved clarity and consistency in the documentation regarding usage and connection details.
…cations

- Changed scopeName from specific identifiers to "official" for consistency across various app configurations, including Cloudflare Docs, Observability, Workers, DigitalOcean, Google services, and others.
- Changed scopeName from "official" to specific identifiers for various applications, including Cloudflare Docs, Observability, Workers, DigitalOcean, Google services, and others, to enhance clarity and specificity.
…ltiple applications

- Updated scopeName to a more general identifier "cloudflare" for Cloudflare-related apps and "digitalocean" for DigitalOcean apps.
- Changed frandryName to friendly_name for consistency in naming conventions across all app configurations, including Google services, Exa Search, HubSpot, and others.
…ions

- Updated friendly_name to friendlyName for consistency in naming conventions across various app configurations, including Cloudflare, DigitalOcean, Google services, and others.
- Updated friendlyName for various applications to remove "Official" from the name, enhancing clarity and consistency across Cloudflare, DigitalOcean, Google, Exa Search, HubSpot, and others.
* Adds deco llm binding

Signed-off-by: Marcos Candeia <marrcooos@gmail.com>

* Rebase

Signed-off-by: Marcos Candeia <marrcooos@gmail.com>

---------

Signed-off-by: Marcos Candeia <marrcooos@gmail.com>
Signed-off-by: Marcos Candeia <marrcooos@gmail.com>
Signed-off-by: Marcos Candeia <marrcooos@gmail.com>
Signed-off-by: Marcos Candeia <marrcooos@gmail.com>
Signed-off-by: Marcos Candeia <marrcooos@gmail.com>
- Changed Google Tag Manager icon URL to a new asset location.
- Updated Grain MCP name to "grain-mcp" and added a friendly name "Grain".
- Revised Grain MCP description for clarity and conciseness.
- Enhanced Grain MCP metadata with category, tags, and detailed descriptions for better context.
…ns, including categories, tags, short descriptions, and detailed mesh descriptions for improved context and usability
…ays for consistency across multiple services
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.

17 issues found across 88 files (changes from recent commits).

Note: This PR contains a large number of files. cubic only reviews up to 75 files per PR, so some files may not have been reviewed.

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="grain-official/app.json">

<violation number="1" location="grain-official/app.json:5">
P0: Unresolved git merge conflict markers in JSON file. This will cause JSON parsing errors and break the application configuration. The conflict markers `<<<<<<< HEAD`, `=======`, and `>>>>>>> 2795092` must be resolved before merging.</violation>
</file>

<file name="mercadopago-official/README.md">

<violation number="1" location="mercadopago-official/README.md:34">
P3: Link text `developers.mercadopago.com` is misleading - it suggests a subdomain but the actual URL points to `www.mercadopago.com/developers` (a path on the main domain). Consider updating the link text to match the actual URL structure for consistency.</violation>
</file>

<file name="digitalocean-databases/app.json">

<violation number="1" location="digitalocean-databases/app.json:18">
P2: Inconsistent database listing: `mesh_description` includes "OpenSearch" but the `description` field and README only list PostgreSQL, MySQL, Redis, and MongoDB. Either add OpenSearch to all descriptions or remove it from `mesh_description` for consistency.</violation>
</file>

<file name="google-ads/server/tools/reports.ts">

<violation number="1" location="google-ads/server/tools/reports.ts:73">
P0: **Critical security vulnerability**: Hardcoded Google Ads developer token will be exposed in version control. Developer tokens are sensitive API credentials that should be stored in environment variables or secrets management, never in source code. Remove the hardcoded fallback value and throw an error if no developer token is configured.</violation>
</file>

<file name="google-ads/server/tools/ad-groups.ts">

<violation number="1" location="google-ads/server/tools/ad-groups.ts:48">
P0: **Critical security issue:** Hardcoded Google Ads developer token in source code. This credential will be exposed in version control. Remove the hardcoded fallback value and either throw an error when the token is missing, or require it via environment configuration only.</violation>
</file>

<file name="google-ads/server/tools/accounts.ts">

<violation number="1" location="google-ads/server/tools/accounts.ts:36">
P0: Critical security issue: Hardcoded Google Ads developer token in source code. Credentials should never be committed to version control, even for testing. Remove the hardcoded token and require it to be provided via environment variables only.</violation>

<violation number="2" location="google-ads/server/tools/accounts.ts:38">
P1: Security issue: Logging the developer token exposes credentials in application logs. Remove this console.log statement or mask the token value if debugging is needed.</violation>
</file>

<file name="google-big-query/server/main.ts">

<violation number="1" location="google-big-query/server/main.ts:21">
P1: Race condition: module-level `lastRedirectUri` shared across concurrent OAuth flows will cause token exchange failures. Consider passing the redirect_uri through the OAuth state parameter or using a request-scoped storage mechanism.</violation>
</file>

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

<violation number="1" location="google-ads/server/tools/ads.ts:49">
P0: Hardcoded Google Ads developer token is a security vulnerability. This credential will be exposed in version control and could be misused. Remove the hardcoded fallback and throw an error if no token is configured instead.</violation>
</file>

<file name="google-big-query/server/lib/bigquery-client.ts">

<violation number="1" location="google-big-query/server/lib/bigquery-client.ts:211">
P1: The comment claims to handle pagination automatically, but the implementation only handles job completion polling. For large result sets, BigQuery returns data in pages via `pageToken`, but this method never fetches additional pages. This will silently return incomplete results while claiming to return 'complete results'. Either implement pagination or update the comment to reflect actual behavior.</violation>
</file>

<file name="content-scraper/app.json">

<violation number="1" location="content-scraper/app.json:17">
P2: The `mesh_description` does not accurately describe this MCP's functionality. According to the README, this MCP uses **Firecrawl and Supabase**, not n8n. The description also claims features like "proxy support", "user-agent rotation", and "anti-bot detection bypass" that aren't documented in the README. This could mislead users about the MCP's actual capabilities.</violation>
</file>

<file name="openrouter/server/lib/env.ts">

<violation number="1" location="openrouter/server/lib/env.ts:5">
P2: Error message doesn't reflect the new fallback behavior. Consider updating it to mention both valid sources: the authorization header and the `OPENROUTER_API_KEY` environment variable.</violation>
</file>

<file name="google-ads/server/tools/keywords.ts">

<violation number="1" location="google-ads/server/tools/keywords.ts:50">
P0: Hardcoded Google Ads developer token exposed in source code. This credential should be loaded exclusively from environment variables or secure secret management. If the token isn't configured, the code should throw a descriptive error rather than fall back to a hardcoded value.</violation>
</file>

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

<violation number="1" location="google-ads/server/tools/campaigns.ts:51">
P0: Critical security issue: Hardcoded Google Ads developer token. Never commit API tokens or secrets to source code. The fallback `"NSC8PQesrKHxJCsygni2A"` should be removed, and the code should require the token from environment variables or throw a meaningful error if missing.</violation>
</file>

<file name="github-mcp-server/README.md">

<violation number="1" location="github-mcp-server/README.md:3">
P2: The claim that this is 'provided directly by the GitHub team' and has 'Direct support and features maintained by the GitHub team' is misleading. This is a wrapper in a third-party repository (maintained by decocms team), not code provided/maintained by GitHub. Consider clarifying that this MCP *connects to* GitHub's official MCP server, but the wrapper itself is community-maintained.</violation>
</file>

<file name="deco-llm/tsconfig.json">

<violation number="1" location="deco-llm/tsconfig.json:31">
P3: Path aliases `shared/*` and `worker/*` reference directories that don't exist. Consider removing unused aliases or creating the corresponding directories.</violation>

<violation number="2" location="deco-llm/tsconfig.json:39">
P3: The `include` array references `shared` and `vite.config.ts` which don't exist in this project. Consider removing these entries or adding the missing files.</violation>
</file>

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

"name": "Grain mcp",
"name": "grain-mcp",
"friendlyName": "Grain",
<<<<<<< HEAD
Copy link

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

Choose a reason for hiding this comment

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

P0: Unresolved git merge conflict markers in JSON file. This will cause JSON parsing errors and break the application configuration. The conflict markers <<<<<<< HEAD, =======, and >>>>>>> 2795092 must be resolved before merging.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At grain-official/app.json, line 5:

<comment>Unresolved git merge conflict markers in JSON file. This will cause JSON parsing errors and break the application configuration. The conflict markers `<<<<<<< HEAD`, `=======`, and `>>>>>>> 2795092` must be resolved before merging.</comment>

<file context>
@@ -1,13 +1,24 @@
-  "name": "Grain mcp",
+  "name": "grain-mcp",
+  "friendlyName": "Grain",
+<<<<<<< HEAD
+  "category": "Collaboration",
+=======
</file context>
Fix with Cubic

execute: async ({ context }) => {
const developerToken = env.MESH_REQUEST_CONTEXT?.state?.developerToken ||
process.env.GOOGLE_ADS_DEVELOPER_TOKEN ||
"NSC8PQesrKHxJCsygni2A";
Copy link

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

Choose a reason for hiding this comment

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

P0: Critical security vulnerability: Hardcoded Google Ads developer token will be exposed in version control. Developer tokens are sensitive API credentials that should be stored in environment variables or secrets management, never in source code. Remove the hardcoded fallback value and throw an error if no developer token is configured.

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

<comment>**Critical security vulnerability**: Hardcoded Google Ads developer token will be exposed in version control. Developer tokens are sensitive API credentials that should be stored in environment variables or secrets management, never in source code. Remove the hardcoded fallback value and throw an error if no developer token is configured.</comment>

<file context>
@@ -68,9 +68,14 @@ export const createGetAccountPerformanceTool = (env: Env) =>
-      });
+        const developerToken = env.MESH_REQUEST_CONTEXT?.state?.developerToken || 
+                              process.env.GOOGLE_ADS_DEVELOPER_TOKEN ||
+                              "NSC8PQesrKHxJCsygni2A";
+        
+        const client = new GoogleAdsClient({
</file context>

✅ Addressed in 2957040

Comment on lines 48 to 50
"NSC8PQesrKHxJCsygni2A";

const client = new GoogleAdsClient({
Copy link

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

Choose a reason for hiding this comment

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

P0: Critical security issue: Hardcoded Google Ads developer token in source code. This credential will be exposed in version control. Remove the hardcoded fallback value and either throw an error when the token is missing, or require it via environment configuration only.

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

<comment>**Critical security issue:** Hardcoded Google Ads developer token in source code. This credential will be exposed in version control. Remove the hardcoded fallback value and either throw an error when the token is missing, or require it via environment configuration only.</comment>

<file context>
@@ -43,9 +43,14 @@ export const createListAdGroupsTool = (env: Env) =>
-      });
+        const developerToken = env.MESH_REQUEST_CONTEXT?.state?.developerToken || 
+                              process.env.GOOGLE_ADS_DEVELOPER_TOKEN ||
+                              "NSC8PQesrKHxJCsygni2A";
+        
+        const client = new GoogleAdsClient({
</file context>
Suggested change
"NSC8PQesrKHxJCsygni2A";
const client = new GoogleAdsClient({
const developerToken = env.MESH_REQUEST_CONTEXT?.state?.developerToken ||
process.env.GOOGLE_ADS_DEVELOPER_TOKEN;
if (!developerToken) {
throw new Error("Google Ads developer token is required. Set GOOGLE_ADS_DEVELOPER_TOKEN environment variable.");
}

✅ Addressed in 2957040

Comment on lines 36 to 38
"NSC8PQesrKHxJCsygni2A"; // Hardcoded for testing

console.log("Using Developer Token:", developerToken);
Copy link

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

Choose a reason for hiding this comment

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

P0: Critical security issue: Hardcoded Google Ads developer token in source code. Credentials should never be committed to version control, even for testing. Remove the hardcoded token and require it to be provided via environment variables only.

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

<comment>Critical security issue: Hardcoded Google Ads developer token in source code. Credentials should never be committed to version control, even for testing. Remove the hardcoded token and require it to be provided via environment variables only.</comment>

<file context>
@@ -30,10 +30,17 @@ export const createListAccessibleCustomersTool = (env: Env) =>
+      execute: async () => {
+        const developerToken = env.MESH_REQUEST_CONTEXT?.state?.developerToken || 
+                              process.env.GOOGLE_ADS_DEVELOPER_TOKEN ||
+                              "NSC8PQesrKHxJCsygni2A"; // Hardcoded for testing
+        
+        console.log("Using Developer Token:", developerToken);
</file context>
Suggested change
"NSC8PQesrKHxJCsygni2A"; // Hardcoded for testing
console.log("Using Developer Token:", developerToken);
const developerToken = env.MESH_REQUEST_CONTEXT?.state?.developerToken ||
process.env.GOOGLE_ADS_DEVELOPER_TOKEN;
if (!developerToken) {
throw new Error("Developer token is required. Set GOOGLE_ADS_DEVELOPER_TOKEN environment variable.");
}

✅ Addressed in 2957040

Comment on lines 49 to 51
"NSC8PQesrKHxJCsygni2A";

const client = new GoogleAdsClient({
Copy link

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

Choose a reason for hiding this comment

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

P0: Hardcoded Google Ads developer token is a security vulnerability. This credential will be exposed in version control and could be misused. Remove the hardcoded fallback and throw an error if no token is configured instead.

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

<comment>Hardcoded Google Ads developer token is a security vulnerability. This credential will be exposed in version control and could be misused. Remove the hardcoded fallback and throw an error if no token is configured instead.</comment>

<file context>
@@ -44,9 +44,14 @@ export const createListAdsTool = (env: Env) =>
-      });
+        const developerToken = env.MESH_REQUEST_CONTEXT?.state?.developerToken || 
+                              process.env.GOOGLE_ADS_DEVELOPER_TOKEN ||
+                              "NSC8PQesrKHxJCsygni2A";
+        
+        const client = new GoogleAdsClient({
</file context>
Suggested change
"NSC8PQesrKHxJCsygni2A";
const client = new GoogleAdsClient({
const developerToken = env.MESH_REQUEST_CONTEXT?.state?.developerToken ||
process.env.GOOGLE_ADS_DEVELOPER_TOKEN;
if (!developerToken) {
throw new Error("Google Ads developer token is required. Set GOOGLE_ADS_DEVELOPER_TOKEN environment variable.");
}

✅ Addressed in 2957040

export const getOpenRouterApiKey = (env: Env) => {
const authorization = env.MESH_REQUEST_CONTEXT.authorization;
const authorization =
env.MESH_REQUEST_CONTEXT.authorization ?? process.env.OPENROUTER_API_KEY;
Copy link

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

Choose a reason for hiding this comment

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

P2: Error message doesn't reflect the new fallback behavior. Consider updating it to mention both valid sources: the authorization header and the OPENROUTER_API_KEY environment variable.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At openrouter/server/lib/env.ts, line 5:

<comment>Error message doesn't reflect the new fallback behavior. Consider updating it to mention both valid sources: the authorization header and the `OPENROUTER_API_KEY` environment variable.</comment>

<file context>
@@ -1,7 +1,8 @@
 export const getOpenRouterApiKey = (env: Env) => {
-  const authorization = env.MESH_REQUEST_CONTEXT.authorization;
+  const authorization =
+    env.MESH_REQUEST_CONTEXT.authorization ?? process.env.OPENROUTER_API_KEY;
   if (!authorization) {
     throw new Error("Authorization header is required");
</file context>
Fix with Cubic

@@ -0,0 +1,43 @@
# GitHub MCP Server Official

This is the **official GitHub MCP Server**, provided directly by the GitHub team for integration with the GitHub platform through Model Context Protocol.
Copy link

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

Choose a reason for hiding this comment

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

P2: The claim that this is 'provided directly by the GitHub team' and has 'Direct support and features maintained by the GitHub team' is misleading. This is a wrapper in a third-party repository (maintained by decocms team), not code provided/maintained by GitHub. Consider clarifying that this MCP connects to GitHub's official MCP server, but the wrapper itself is community-maintained.

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

<comment>The claim that this is 'provided directly by the GitHub team' and has 'Direct support and features maintained by the GitHub team' is misleading. This is a wrapper in a third-party repository (maintained by decocms team), not code provided/maintained by GitHub. Consider clarifying that this MCP *connects to* GitHub's official MCP server, but the wrapper itself is community-maintained.</comment>

<file context>
@@ -0,0 +1,43 @@
+# GitHub MCP Server Official
+
+This is the **official GitHub MCP Server**, provided directly by the GitHub team for integration with the GitHub platform through Model Context Protocol.
+
+## About GitHub MCP Server
</file context>
Fix with Cubic

## Official Resources

- 🌐 Website: [mercadopago.com](https://www.mercadopago.com)
- 📚 Documentation: [developers.mercadopago.com](https://www.mercadopago.com/developers)
Copy link

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

Choose a reason for hiding this comment

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

P3: Link text developers.mercadopago.com is misleading - it suggests a subdomain but the actual URL points to www.mercadopago.com/developers (a path on the main domain). Consider updating the link text to match the actual URL structure for consistency.

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

<comment>Link text `developers.mercadopago.com` is misleading - it suggests a subdomain but the actual URL points to `www.mercadopago.com/developers` (a path on the main domain). Consider updating the link text to match the actual URL structure for consistency.</comment>

<file context>
@@ -0,0 +1,44 @@
+## Official Resources
+
+- 🌐 Website: [mercadopago.com](https://www.mercadopago.com)
+- 📚 Documentation: [developers.mercadopago.com](https://www.mercadopago.com/developers)
+- 🆘 Support: Contact through official Mercado Pago support
+
</file context>
Suggested change
- 📚 Documentation: [developers.mercadopago.com](https://www.mercadopago.com/developers)
- 📚 Documentation: [mercadopago.com/developers](https://www.mercadopago.com/developers)
Fix with Cubic

"paths": {
"shared/*": ["./shared/*"],
"server/*": ["./server/*"],
"worker/*": ["./worker/*"]
Copy link

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

Choose a reason for hiding this comment

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

P3: Path aliases shared/* and worker/* reference directories that don't exist. Consider removing unused aliases or creating the corresponding directories.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At deco-llm/tsconfig.json, line 31:

<comment>Path aliases `shared/*` and `worker/*` reference directories that don't exist. Consider removing unused aliases or creating the corresponding directories.</comment>

<file context>
@@ -0,0 +1,42 @@
+    "paths": {
+      "shared/*": ["./shared/*"],
+      "server/*": ["./server/*"],
+      "worker/*": ["./worker/*"]
+    },
+
</file context>
Fix with Cubic

},
"include": [
"server",
"shared",
Copy link

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

Choose a reason for hiding this comment

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

P3: The include array references shared and vite.config.ts which don't exist in this project. Consider removing these entries or adding the missing files.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At deco-llm/tsconfig.json, line 39:

<comment>The `include` array references `shared` and `vite.config.ts` which don't exist in this project. Consider removing these entries or adding the missing files.</comment>

<file context>
@@ -0,0 +1,42 @@
+  },
+  "include": [
+    "server",
+    "shared",
+    "vite.config.ts"
+  ]
</file context>
Fix with Cubic

- Remove hardcoded developer token (security issue)
- Extract repeated logic to createGoogleAdsClient() helper
- Add custom error classes (GoogleAdsApiError, GoogleAdsAuthError, GoogleAdsConfigError)
- Improve constants typing with derived types
- Remove unused imports (CampaignBudget, DATE_RANGE_PRESETS)
- Fix typing error in listCampaigns()
- Add types for DateRangePreset and other constant values
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.

5 participants