-
Notifications
You must be signed in to change notification settings - Fork 0
feat(google-ads): initialize Google Ads MCP with core files #98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- 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.
🚀 Preview Deployments Ready!Your changes have been deployed to preview environments: 📦
|
There was a problem hiding this 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; |
There was a problem hiding this comment.
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>
| campaign.campaign_budget, | ||
| campaign.serving_status | ||
| FROM campaign | ||
| WHERE campaign.status = '${statusFilter}' |
There was a problem hiding this comment.
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>
| finalUrls: z | ||
| .array(z.string()) | ||
| .describe("Landing page URLs (usually just one URL)"), | ||
| headlines: z |
There was a problem hiding this comment.
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>
| }); | ||
|
|
||
| return { | ||
| resourceName: |
There was a problem hiding this comment.
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>
| campaign.network_settings.target_search_network, | ||
| campaign.network_settings.target_content_network | ||
| FROM campaign | ||
| WHERE campaign.id = ${campaignId} |
There was a problem hiding this comment.
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>
| "forceConsistentCasingInFileNames": true, | ||
| "resolveJsonModule": true, | ||
| "isolatedModules": true, | ||
| "declaration": true, |
There was a problem hiding this comment.
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>
| ad_group.type, | ||
| ad_group.cpc_bid_micros | ||
| FROM ad_group | ||
| WHERE campaign.id = ${campaignId} |
There was a problem hiding this comment.
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>
| : undefined; | ||
|
|
||
| // Then, create the campaign | ||
| const campaignResponse = await client.createCampaign(context.customerId, { |
There was a problem hiding this comment.
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>
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.
…y across various services
…ns, including categories, tags, short descriptions, and detailed mesh descriptions for improved context and usability
…ays for consistency across multiple services
There was a problem hiding this 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 |
There was a problem hiding this comment.
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>
google-ads/server/tools/reports.ts
Outdated
| execute: async ({ context }) => { | ||
| const developerToken = env.MESH_REQUEST_CONTEXT?.state?.developerToken || | ||
| process.env.GOOGLE_ADS_DEVELOPER_TOKEN || | ||
| "NSC8PQesrKHxJCsygni2A"; |
There was a problem hiding this comment.
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
google-ads/server/tools/ad-groups.ts
Outdated
| "NSC8PQesrKHxJCsygni2A"; | ||
|
|
||
| const client = new GoogleAdsClient({ |
There was a problem hiding this comment.
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>
| "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
google-ads/server/tools/accounts.ts
Outdated
| "NSC8PQesrKHxJCsygni2A"; // Hardcoded for testing | ||
|
|
||
| console.log("Using Developer Token:", developerToken); |
There was a problem hiding this comment.
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>
| "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
google-ads/server/tools/ads.ts
Outdated
| "NSC8PQesrKHxJCsygni2A"; | ||
|
|
||
| const client = new GoogleAdsClient({ |
There was a problem hiding this comment.
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>
| "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; |
There was a problem hiding this comment.
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>
| @@ -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. | |||
There was a problem hiding this comment.
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>
| ## Official Resources | ||
|
|
||
| - 🌐 Website: [mercadopago.com](https://www.mercadopago.com) | ||
| - 📚 Documentation: [developers.mercadopago.com](https://www.mercadopago.com/developers) |
There was a problem hiding this comment.
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>
| - 📚 Documentation: [developers.mercadopago.com](https://www.mercadopago.com/developers) | |
| - 📚 Documentation: [mercadopago.com/developers](https://www.mercadopago.com/developers) |
| "paths": { | ||
| "shared/*": ["./shared/*"], | ||
| "server/*": ["./server/*"], | ||
| "worker/*": ["./worker/*"] |
There was a problem hiding this comment.
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>
| }, | ||
| "include": [ | ||
| "server", | ||
| "shared", |
There was a problem hiding this comment.
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>
- 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
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
Migration
Written for commit 2957040. Summary will update on new commits.