Skip to content

Conversation

@pedrofrxncx
Copy link
Contributor

@pedrofrxncx pedrofrxncx commented Dec 11, 2025

Summary by cubic

Introduces a durable workflow engine with persisted executions, event-driven scheduling, and a sandboxed TypeScript runner. Adds workflow/execution tools, a Connection binding and gateway transport for MCPs, and an Event Bus handler for workflow events.

  • New Features

    • Durable workflow runtime with checkpoints, retries/timeouts, cancellation, and unified events/signals.
    • DAG-based executor for parallel step execution and @ref resolution.
    • QuickJS sandbox for code steps (console, fetch) with TypeScript transpilation via sucrase.
    • Workflow collections/tools: CRUD for workflows and executions, start/resume/cancel, list/get step results.
    • PostgreSQL setup with idempotent table/index creation and locking.
    • Event Bus binding with a runtime handler for "workflow.execution.created".
    • Connection Binding and MCP gateway transport for tool steps; executions track gateway_id.
    • Workflow validation on create: step type checks, @ref validation, and TypeScript validation for code steps.
  • Migration

    • Configure DATABASE, EVENT_BUS, and CONNECTION bindings; tables are created on startup.
    • Replace Meta Ads secrets with META_ACCESS_TOKEN in GitHub workflows and env; docs updated to use direct token auth.
    • Install new deps (QuickJS, sucrase, @ai-sdk/mcp, @modelcontextprotocol/sdk).

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

viktormarinho and others added 30 commits November 24, 2025 20:52
- Introduced drizzle ORM as a dependency in package.json and updated zod version.
- Added drizzle configuration file and SQL migration scripts for the 'agents' table.
- Implemented database connection logic in server/db.ts and created CRUD tools for the agents collection.
- Updated wrangler.toml to include new database bindings and added a .gitignore file for sensitive variables.
- Enhanced the shared types in deco.gen.ts to accommodate new database operations and structures.
- Introduced drizzle ORM as a dependency in package.json and updated zod version.
- Added drizzle configuration file and SQL migration scripts for the 'agents' table.
- Implemented database connection logic in server/db.ts and created CRUD tools for the agents collection.
- Updated wrangler.toml to include new database bindings and added a .gitignore file for sensitive variables.
- Enhanced the shared types in deco.gen.ts to accommodate new database operations and structures.
- Removed drizzle ORM configurations and related files, including SQL migration scripts and schema definitions for the 'agents' table.
- Introduced PostgreSQL connection handling with automatic table creation for agents.
- Updated server tools to implement CRUD operations for agents using PostgreSQL.
- Enhanced the state schema to include a PostgreSQL connection string for better database management.
- Adjusted package dependencies and versions in package.json and bun.lock to reflect the changes.
- Removed unused database bindings from wrangler.toml.
- Refactored deco.gen.ts to introduce new interfaces and types for Deco Chat operations, including input and output structures for agent management.
- Added CRUD operation interfaces for agents, enhancing the overall structure and clarity of the type definitions.
- Updated StateSchema to reflect changes in the data model, ensuring better alignment with the new agent management features.
- Introduced a new package `@deco/cf-sandbox` for executing JavaScript code securely in Cloudflare Workers using QuickJS.
- Added essential files including `package.json`, `bun.lock`, and TypeScript configuration for the new package.
- Implemented core functionalities such as context creation, console logging, and fetch API support within the sandbox environment.
- Updated `vibecoding-toolkit` to include the new package as a dependency and adjusted related configurations.
- Enhanced README documentation for the CF Sandbox, detailing usage and features for developers.
- Added support for resolving @refs in workflow inputs, allowing for dynamic input referencing across steps.
- Updated `handleSandboxStep` to accept a context parameter, enabling better state management during execution.
- Refactored input handling in `runWorkflowTool` to parse and merge step inputs, improving flexibility and error handling.
- Made input and output schemas optional in the StepSchema, accommodating steps that do not require them.
- Updated TypeScript definitions in `deco.gen.ts` to reflect changes in the workflow structure, ensuring type safety and clarity.
- Introduced drizzle ORM as a dependency in package.json and updated zod version.
- Added drizzle configuration file and SQL migration scripts for the 'agents' table.
- Implemented database connection logic in server/db.ts and created CRUD tools for the agents collection.
- Updated wrangler.toml to include new database bindings and added a .gitignore file for sensitive variables.
- Enhanced the shared types in deco.gen.ts to accommodate new database operations and structures.
- Removed drizzle ORM configurations and related files, including SQL migration scripts and schema definitions for the 'agents' table.
- Introduced PostgreSQL connection handling with automatic table creation for agents.
- Updated server tools to implement CRUD operations for agents using PostgreSQL.
- Enhanced the state schema to include a PostgreSQL connection string for better database management.
- Adjusted package dependencies and versions in package.json and bun.lock to reflect the changes.
- Removed unused database bindings from wrangler.toml.
- Refactored deco.gen.ts to introduce new interfaces and types for Deco Chat operations, including input and output structures for agent management.
- Added CRUD operation interfaces for agents, enhancing the overall structure and clarity of the type definitions.
- Updated StateSchema to reflect changes in the data model, ensuring better alignment with the new agent management features.
- Introduced a new workspace for 'cfm' in package.json, enhancing project structure.
- Updated bun.lock to include 'cfm' dependencies and devDependencies for improved functionality.
- Refactored DataForSEO tools to utilize updated state management for API credentials, replacing 'DATAFORSEO_LOGIN' and 'DATAFORSEO_PASSWORD' with 'login' and 'password' for consistency.
- Removed the 'cfm' workspace from package.json and corresponding entries from bun.lock to streamline project structure.
- Introduced a new helper function, getClientFromEnv, to simplify client creation for DataForSEO tools, enhancing code maintainability and readability.
- Updated multiple tool files to replace direct client instantiation with the new helper function, ensuring consistent handling of API credentials.
- Introduced drizzle ORM as a dependency in package.json and updated zod version.
- Added drizzle configuration file and SQL migration scripts for the 'agents' table.
- Implemented database connection logic in server/db.ts and created CRUD tools for the agents collection.
- Updated wrangler.toml to include new database bindings and added a .gitignore file for sensitive variables.
- Enhanced the shared types in deco.gen.ts to accommodate new database operations and structures.
- Removed drizzle ORM configurations and related files, including SQL migration scripts and schema definitions for the 'agents' table.
- Introduced PostgreSQL connection handling with automatic table creation for agents.
- Updated server tools to implement CRUD operations for agents using PostgreSQL.
- Enhanced the state schema to include a PostgreSQL connection string for better database management.
- Adjusted package dependencies and versions in package.json and bun.lock to reflect the changes.
- Updated `.gitignore` to include `packages/` directory.
- Added `sucrase` as a dependency in `package.json` and updated `typescript` version.
- Introduced a new `script.ts` for TypeScript to JavaScript conversion using `sucrase`.
- Created comprehensive documentation for workflow patterns, implementation guides, and scheduler architecture.
- Implemented a durable queue handler to process all messages in a batch with error isolation and retry logic.
- Refactored workflow execution logic to support phase-based execution and improved error handling.
- Added database utility functions for retry mechanisms and workflow execution tracking.
pedrofrxncx and others added 12 commits December 29, 2025 11:02
- Added `@ai-sdk/mcp` and updated `@modelcontextprotocol/sdk` to version `1.25.1` in `package.json`.
- Refactored execution logic to replace `workflow_id` with `gateway_id` in execution-related functions and database queries.
- Enhanced `ExecutionContext` to include `gatewayId`.
- Updated tool execution to utilize the new gateway transport for MCP calls.
- Improved database schema for `workflow_execution` to accommodate `gateway_id`.
- Cleaned up unused code and improved validation logic for workflow steps.
…uteToolStepWithTimeout` and directly invoking `executeToolStep`. This simplifies the code and improves readability.
- Remove OAuth PKCE flow from main.ts
- Update getMetaAccessToken to use META_ACCESS_TOKEN environment variable
- Update README with token-based authentication instructions
- Update GitHub Actions workflows to use META_ACCESS_TOKEN secret
- Update SECRETS.md documentation for token-based auth
- Remove OAuth-related constants and comments
- Replace OAuth with configuration-based state schema
- Add StateSchema to allow users to configure access token during MCP installation
- Update getMetaAccessToken to read from env.state.accessToken
- Add shared/deco.gen.ts for StateSchema support
- Add types.d.ts to handle runtime dependency type issues
- Update check script to use oxlint instead of tsc
- Update tsconfig.json to exclude dist directory
@pedrofrxncx pedrofrxncx marked this pull request as ready for review December 30, 2025 17:28
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.

25 issues found across 42 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="mcp-studio/server/sandbox/index.ts">

<violation number="1" location="mcp-studio/server/sandbox/index.ts:117">
P1: Setting the interrupt handler on the shared runtime inside `createContext` causes a race condition. Since the runtime is cached and shared (line 73), each new context overwrites the previous interrupt handler, meaning only the last context&#39;s deadline will be enforced. Earlier contexts will not have their timeouts respected, which could allow runaway code execution in a sandbox environment.</violation>
</file>

<file name="mcp-studio/server/tools/execution.ts">

<violation number="1" location="mcp-studio/server/tools/execution.ts:150">
P2: Missing `outputSchema` in `createGetTool`. All other tools in this file define an outputSchema, and `GET_BINDING.outputSchema` is validated to exist on line 28. Consider adding `outputSchema: GET_BINDING.outputSchema` for consistency.</violation>
</file>

<file name="connection-binding/app.json">

<violation number="1" location="connection-binding/app.json:14">
P2: The `inputSchema` for `COLLECTION_CONNECTIONS_GET` is missing `required` and `additionalProperties` fields. For a GET operation, the `id` parameter should be required. Without this, the schema allows calling GET without an id, which would be invalid.</violation>
</file>

<file name="mcp-studio/server/db/schemas/workflow.ts">

<violation number="1" location="mcp-studio/server/db/schemas/workflow.ts:31">
P2: Missing FOREIGN KEY constraint on `workflow_collection_id`. Other tables in this schema (like `workflow_execution_step_result` and `workflow_event`) properly define foreign key constraints. Consider adding `FOREIGN KEY (workflow_collection_id) REFERENCES workflow_collection(id)` for data integrity.</violation>

<violation number="2" location="mcp-studio/server/db/schemas/workflow.ts:49">
P2: Missing FOREIGN KEY constraint on `workflow_id`. Other tables in this schema properly define foreign key constraints. Consider adding `FOREIGN KEY (workflow_id) REFERENCES workflow(id)` for data integrity, or use inline syntax.</violation>
</file>

<file name="mcp-studio/server/tools/workflow.ts">

<violation number="1" location="mcp-studio/server/tools/workflow.ts:246">
P2: Malformed JSON example in the description. The step definition is truncated and starts with `true }` which is invalid JSON. This will confuse users trying to understand the workflow syntax. The step should include the full definition with `name` and `action` properties.</violation>
</file>

<file name="mcp-studio/server/db/transformers.ts">

<violation number="1" location="mcp-studio/server/db/transformers.ts:115">
P2: Using `Number(row.visible_at)` directly can produce `NaN` (if undefined) or `0` (if null) without validation. Consider using `toNumberOrNull` or adding explicit null handling like the `consumed_at` field does.</violation>

<violation number="2" location="mcp-studio/server/db/transformers.ts:117">
P2: This duplicates the `safeJsonParse` logic defined earlier in the file. Using `payload: safeJsonParse(row.payload)` would be more consistent and includes error handling that this inline version lacks.</violation>
</file>

<file name="mcp-studio/server/engine/steps/code-step.ts">

<violation number="1" location="mcp-studio/server/engine/steps/code-step.ts:173">
P1: Memory leak: `runtime` is created with a unique ID but never disposed. Only `ctx` is disposed in the finally block, leaving the runtime cached indefinitely. Use `using` syntax or manually call `runtime[Symbol.dispose]()` in the finally block.</violation>
</file>

<file name="mcp-studio/server/tools/_helpers.ts">

<violation number="1" location="mcp-studio/server/tools/_helpers.ts:72">
P0: SQL injection vulnerability: `fieldName` is interpolated directly into SQL without validation. While values use parameterized queries (`?`), identifiers are not protected. Consider validating field names against an allowlist of permitted columns.</violation>

<violation number="2" location="mcp-studio/server/tools/_helpers.ts:151">
P0: SQL injection vulnerability: `direction` is directly interpolated into SQL without validation. It should be restricted to only &#39;ASC&#39; or &#39;DESC&#39;.</violation>

<violation number="3" location="mcp-studio/server/tools/_helpers.ts:152">
P1: SQL injection vulnerability: `nulls` is directly interpolated into SQL without validation. It should be restricted to only &#39;FIRST&#39; or &#39;LAST&#39;.</violation>
</file>

<file name="mcp-studio/server/sandbox/builtins/fetch.ts">

<violation number="1" location="mcp-studio/server/sandbox/builtins/fetch.ts:45">
P2: Memory leak: handles created by `ctx.newNumber()` are not tracked or disposed. In QuickJS-emscripten, handles passed to `setProp` should be disposed after use, or tracked for later cleanup.</violation>
</file>

<file name="mcp-studio/server/engine/context.ts">

<violation number="1" location="mcp-studio/server/engine/context.ts:34">
P2: If `getExecution` returns `null` (execution not found), this method silently continues without error. A missing execution during cancellation check could indicate data corruption or an invalid `executionId`. Consider throwing an error when the execution doesn&#39;t exist.</violation>
</file>

<file name="mcp-studio/server/sandbox/utils/call-function.ts">

<violation number="1" location="mcp-studio/server/sandbox/utils/call-function.ts:11">
P1: Memory leak: QuickJS handles (`thisArgHandle`, `argHandles`, `result`, `resultPromise`) are never disposed. Each call leaks memory since QuickJS requires manual handle cleanup.</violation>
</file>

<file name="mcp-studio/server/types/env.ts">

<violation number="1" location="mcp-studio/server/types/env.ts:45">
P2: The optional parameter contradicts the comment stating MCP rejects undefined inputs. If MCP validation truly rejects undefined, this parameter should be required, not optional.</violation>
</file>

<file name="bun.lock">

<violation number="1" location="bun.lock:2693">
P0: Absolute path from a developer&#39;s local machine was accidentally committed to the lock file (`file:/Users/pedrofranca/Documents/dev/decocms/mesh/packages/bindings`). This will cause build failures for anyone else and leaks local filesystem information.</violation>
</file>

<file name="mcp-studio/server/engine/executor.ts">

<violation number="1" location="mcp-studio/server/engine/executor.ts:182">
P1: The `updateStepResult` call is not awaited. This async function may not complete before the error is re-thrown, potentially leaving step failures unrecorded in the database and causing an unhandled promise rejection.</violation>
</file>

<file name="mcp-studio/server/events/handler.ts">

<violation number="1" location="mcp-studio/server/events/handler.ts:22">
P1: Fire-and-forget async calls may cause lost workflow executions. The function spawns async `executeWorkflow` calls without awaiting them or returning the promises. If the execution context terminates (common in serverless/workers), pending workflows will be dropped. Consider making the function async and using `Promise.allSettled()` to await all executions, or use `waitUntil()` if in a Cloudflare Worker context.</violation>
</file>

<file name="mcp-studio/server/db/queries/executions.ts">

<violation number="1" location="mcp-studio/server/db/queries/executions.ts:310">
P1: Return type mismatch: When `ON CONFLICT DO NOTHING` triggers (race condition), `result[0]` will be `undefined` but the return type promises `WorkflowExecutionStepResult`. Either change return type to `WorkflowExecutionStepResult | null` or use `ON CONFLICT DO UPDATE ... RETURNING *` to always return a result.</violation>

<violation number="2" location="mcp-studio/server/db/queries/executions.ts:419">
P1: Pagination is broken: `totalCount` is set to the returned result count (after LIMIT), not the actual total in the database. This makes `hasMore` always false. You need a separate `COUNT(*)` query to get the true total count.</violation>
</file>

<file name="mcp-studio/server/sandbox/utils/to-quickjs.ts">

<violation number="1" location="mcp-studio/server/sandbox/utils/to-quickjs.ts:23">
P1: Memory leak: QuickJS handle `hv` is not disposed after `ctx.setProp()`. Each object property conversion leaks memory since handles are not freed after use.</violation>
</file>

<file name="mcp-studio/server/utils/ref-resolver.ts">

<violation number="1" location="mcp-studio/server/utils/ref-resolver.ts:60">
P1: The condition `refStr.startsWith(&quot;input&quot;)` incorrectly matches step names starting with &#39;input&#39; (e.g., `@inputName`, `@inputData`) as input references. Should use the same pattern as &#39;item&#39;: check for exact match OR prefix with dot.</violation>
</file>

<file name="mcp-studio/server/engine/steps/tool-step.ts">

<violation number="1" location="mcp-studio/server/engine/steps/tool-step.ts:188">
P1: MCP client connection is never closed, causing a resource leak. The client should be closed in a `finally` block to ensure cleanup regardless of success or error.</violation>
</file>

<file name="mcp-studio/package.json">

<violation number="1" location="mcp-studio/package.json:18">
P1: Local file references (`file:../../mesh/packages/...`) point to paths outside the repository that don&#39;t exist. This will break package installation in CI/CD and for other developers. Consider using the original npm package versions, workspace references, or ensuring the path exists in the monorepo structure.</violation>
</file>

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

};

// Set up interrupt handler for this context
runtime.setInterruptHandler(() => {
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 30, 2025

Choose a reason for hiding this comment

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

P1: Setting the interrupt handler on the shared runtime inside createContext causes a race condition. Since the runtime is cached and shared (line 73), each new context overwrites the previous interrupt handler, meaning only the last context's deadline will be enforced. Earlier contexts will not have their timeouts respected, which could allow runaway code execution in a sandbox environment.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At mcp-studio/server/sandbox/index.ts, line 117:

<comment>Setting the interrupt handler on the shared runtime inside `createContext` causes a race condition. Since the runtime is cached and shared (line 73), each new context overwrites the previous interrupt handler, meaning only the last context&#39;s deadline will be enforced. Earlier contexts will not have their timeouts respected, which could allow runaway code execution in a sandbox environment.</comment>

<file context>
@@ -0,0 +1,146 @@
+    };
+
+    // Set up interrupt handler for this context
+    runtime.setInterruptHandler(() =&gt; {
+      const shouldInterrupt = deadline &gt; 0 &amp;&amp; Date.now() &gt; deadline;
+      if (shouldInterrupt) {
</file context>
Fix with Cubic

createPrivateTool({
id: "COLLECTION_WORKFLOW_EXECUTION_GET",
description: "Get a single workflow execution by ID with step results",
inputSchema: GET_BINDING.inputSchema,
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 30, 2025

Choose a reason for hiding this comment

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

P2: Missing outputSchema in createGetTool. All other tools in this file define an outputSchema, and GET_BINDING.outputSchema is validated to exist on line 28. Consider adding outputSchema: GET_BINDING.outputSchema for consistency.

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

<comment>Missing `outputSchema` in `createGetTool`. All other tools in this file define an outputSchema, and `GET_BINDING.outputSchema` is validated to exist on line 28. Consider adding `outputSchema: GET_BINDING.outputSchema` for consistency.</comment>

<file context>
@@ -0,0 +1,205 @@
+  createPrivateTool({
+    id: &quot;COLLECTION_WORKFLOW_EXECUTION_GET&quot;,
+    description: &quot;Get a single workflow execution by ID with step results&quot;,
+    inputSchema: GET_BINDING.inputSchema,
+    execute: async ({
+      context,
</file context>
Fix with Cubic

{
"name": "COLLECTION_CONNECTIONS_UPDATE",
"description": "Update an existing MCP connection in the organization",
"inputSchema": {
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 30, 2025

Choose a reason for hiding this comment

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

P2: The inputSchema for COLLECTION_CONNECTIONS_GET is missing required and additionalProperties fields. For a GET operation, the id parameter should be required. Without this, the schema allows calling GET without an id, which would be invalid.

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

<comment>The `inputSchema` for `COLLECTION_CONNECTIONS_GET` is missing `required` and `additionalProperties` fields. For a GET operation, the `id` parameter should be required. Without this, the schema allows calling GET without an id, which would be invalid.</comment>

<file context>
@@ -0,0 +1,617 @@
+    {
+      &quot;name&quot;: &quot;COLLECTION_CONNECTIONS_UPDATE&quot;,
+      &quot;description&quot;: &quot;Update an existing MCP connection in the organization&quot;,
+      &quot;inputSchema&quot;: {
+        &quot;type&quot;: &quot;object&quot;,
+        &quot;properties&quot;: {
</file context>
Fix with Cubic

const postgresWorkflowExecutionTableIdempotentQuery = `
CREATE TABLE IF NOT EXISTS workflow_execution (
id TEXT PRIMARY KEY,
workflow_id TEXT NOT NULL,
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 30, 2025

Choose a reason for hiding this comment

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

P2: Missing FOREIGN KEY constraint on workflow_id. Other tables in this schema properly define foreign key constraints. Consider adding FOREIGN KEY (workflow_id) REFERENCES workflow(id) for data integrity, or use inline syntax.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At mcp-studio/server/db/schemas/workflow.ts, line 49:

<comment>Missing FOREIGN KEY constraint on `workflow_id`. Other tables in this schema properly define foreign key constraints. Consider adding `FOREIGN KEY (workflow_id) REFERENCES workflow(id)` for data integrity, or use inline syntax.</comment>

<file context>
@@ -0,0 +1,165 @@
+const postgresWorkflowExecutionTableIdempotentQuery = `
+CREATE TABLE IF NOT EXISTS workflow_execution (
+  id TEXT PRIMARY KEY,
+  workflow_id TEXT NOT NULL,
+  status TEXT NOT NULL CHECK(status IN (&#39;enqueued&#39;, &#39;cancelled&#39;, &#39;success&#39;, &#39;error&#39;, &#39;running&#39;)),
+  input JSONB,
</file context>
Fix with Cubic

const postgresWorkflowTableIdempotentQuery = `
CREATE TABLE IF NOT EXISTS workflow (
id TEXT PRIMARY KEY,
workflow_collection_id TEXT,
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 30, 2025

Choose a reason for hiding this comment

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

P2: Missing FOREIGN KEY constraint on workflow_collection_id. Other tables in this schema (like workflow_execution_step_result and workflow_event) properly define foreign key constraints. Consider adding FOREIGN KEY (workflow_collection_id) REFERENCES workflow_collection(id) for data integrity.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At mcp-studio/server/db/schemas/workflow.ts, line 31:

<comment>Missing FOREIGN KEY constraint on `workflow_collection_id`. Other tables in this schema (like `workflow_execution_step_result` and `workflow_event`) properly define foreign key constraints. Consider adding `FOREIGN KEY (workflow_collection_id) REFERENCES workflow_collection(id)` for data integrity.</comment>

<file context>
@@ -0,0 +1,165 @@
+const postgresWorkflowTableIdempotentQuery = `
+  CREATE TABLE IF NOT EXISTS workflow (
+    id TEXT PRIMARY KEY,
+    workflow_collection_id TEXT,
+    steps JSONB NOT NULL DEFAULT &#39;{}&#39;,
+    input JSONB,
</file context>
Fix with Cubic

[...params, limit, offset],
);

const totalCount = result.length;
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 30, 2025

Choose a reason for hiding this comment

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

P1: Pagination is broken: totalCount is set to the returned result count (after LIMIT), not the actual total in the database. This makes hasMore always false. You need a separate COUNT(*) query to get the true total count.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At mcp-studio/server/db/queries/executions.ts, line 419:

<comment>Pagination is broken: `totalCount` is set to the returned result count (after LIMIT), not the actual total in the database. This makes `hasMore` always false. You need a separate `COUNT(*)` query to get the true total count.</comment>

<file context>
@@ -0,0 +1,555 @@
+    [...params, limit, offset],
+  );
+
+  const totalCount = result.length;
+
+  return {
</file context>
Fix with Cubic

if (Array.isArray(value)) {
const arr = ctx.newArray();
value.forEach((v, i) => {
const hv = toQuickJS(ctx, v);
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 30, 2025

Choose a reason for hiding this comment

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

P1: Memory leak: QuickJS handle hv is not disposed after ctx.setProp(). Each object property conversion leaks memory since handles are not freed after use.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At mcp-studio/server/sandbox/utils/to-quickjs.ts, line 23:

<comment>Memory leak: QuickJS handle `hv` is not disposed after `ctx.setProp()`. Each object property conversion leaks memory since handles are not freed after use.</comment>

<file context>
@@ -0,0 +1,126 @@
+      if (Array.isArray(value)) {
+        const arr = ctx.newArray();
+        value.forEach((v, i) =&gt; {
+          const hv = toQuickJS(ctx, v);
+          ctx.setProp(arr, String(i), hv);
+        });
</file context>
Fix with Cubic

}

// Input reference: @input.path.to.value
if (refStr.startsWith("input")) {
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 30, 2025

Choose a reason for hiding this comment

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

P1: The condition refStr.startsWith("input") incorrectly matches step names starting with 'input' (e.g., @inputName, @inputData) as input references. Should use the same pattern as 'item': check for exact match OR prefix with dot.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At mcp-studio/server/utils/ref-resolver.ts, line 60:

<comment>The condition `refStr.startsWith(&quot;input&quot;)` incorrectly matches step names starting with &#39;input&#39; (e.g., `@inputName`, `@inputData`) as input references. Should use the same pattern as &#39;item&#39;: check for exact match OR prefix with dot.</comment>

<file context>
@@ -0,0 +1,299 @@
+  }
+
+  // Input reference: @input.path.to.value
+  if (refStr.startsWith(&quot;input&quot;)) {
+    const path = refStr.length &gt; 5 ? refStr.substring(6) : &quot;&quot;; // Remove &#39;input.&#39; or &#39;input&#39;
+    return { type: &quot;input&quot;, path };
</file context>
Fix with Cubic

},
],
});
await client.connect(transport);
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 30, 2025

Choose a reason for hiding this comment

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

P1: MCP client connection is never closed, causing a resource leak. The client should be closed in a finally block to ensure cleanup regardless of success or error.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At mcp-studio/server/engine/steps/tool-step.ts, line 188:

<comment>MCP client connection is never closed, causing a resource leak. The client should be closed in a `finally` block to ensure cleanup regardless of success or error.</comment>

<file context>
@@ -0,0 +1,258 @@
+      },
+    ],
+  });
+  await client.connect(transport);
+
+  // Fetch tool schema for type coercion
</file context>
Fix with Cubic

"@decocms/bindings": "1.0.1-alpha.26",
"@decocms/runtime": "1.0.0-alpha.31",
"@ai-sdk/mcp": "^1.0.1",
"@decocms/bindings": "file:../../mesh/packages/bindings",
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 30, 2025

Choose a reason for hiding this comment

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

P1: Local file references (file:../../mesh/packages/...) point to paths outside the repository that don't exist. This will break package installation in CI/CD and for other developers. Consider using the original npm package versions, workspace references, or ensuring the path exists in the monorepo structure.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At mcp-studio/package.json, line 18:

<comment>Local file references (`file:../../mesh/packages/...`) point to paths outside the repository that don&#39;t exist. This will break package installation in CI/CD and for other developers. Consider using the original npm package versions, workspace references, or ensuring the path exists in the monorepo structure.</comment>

<file context>
@@ -14,40 +14,40 @@
-    &quot;@decocms/bindings&quot;: &quot;1.0.1-alpha.26&quot;,
-    &quot;@decocms/runtime&quot;: &quot;1.0.0-alpha.31&quot;,
+    &quot;@ai-sdk/mcp&quot;: &quot;^1.0.1&quot;,
+    &quot;@decocms/bindings&quot;: &quot;file:../../mesh/packages/bindings&quot;,
+    &quot;@decocms/runtime&quot;: &quot;file:../../mesh/packages/runtime&quot;,
+    &quot;@jitl/quickjs-wasmfile-release-sync&quot;: &quot;^0.31.0&quot;,
</file context>

✅ Addressed in b34caa5

@pedrofrxncx
Copy link
Contributor Author

@cubic-ai

@cubic-dev-ai
Copy link

cubic-dev-ai bot commented Dec 30, 2025

@cubic-ai

@pedrofrxncx I have started the AI code review. It will take a few minutes to complete.

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.

23 issues found across 54 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="mcp-studio/server/sandbox/builtins/fetch.ts">

<violation number="1" location="mcp-studio/server/sandbox/builtins/fetch.ts:29">
P2: The `_headers` variable is parsed from init options but never used. Headers passed to the Response constructor are silently ignored. Either implement the headers functionality or remove the dead code.</violation>
</file>

<file name="mcp-studio/server/types/env.ts">

<violation number="1" location="mcp-studio/server/types/env.ts:45">
P2: Optional parameter contradicts the comment. If MCP tool validation rejects `undefined` inputs, then `params` should be required (not optional) to ensure callers always pass an empty object `{}`.</violation>
</file>

<file name="mcp-studio/server/tools/workflow.ts">

<violation number="1" location="mcp-studio/server/tools/workflow.ts:246">
P2: Malformed JSON example in documentation. Line 229 starts with `true },` which is invalid - the first step definition is truncated. It should likely be something like `{ &quot;name&quot;: &quot;fetch_users&quot;, &quot;action&quot;: { &quot;toolName&quot;: &quot;GET_USERS&quot; }, &quot;transformCode&quot;: &quot;export default async (i) =&gt; i[0]&quot; },`</violation>
</file>

<file name="mcp-studio/server/engine/executor.ts">

<violation number="1" location="mcp-studio/server/engine/executor.ts:182">
P1: Missing `await` on async `updateStepResult` call. The database update may not complete before the error is thrown, and any database errors will be silently lost as unhandled promise rejections.</violation>
</file>

<file name="mcp-studio/server/engine/context.ts">

<violation number="1" location="mcp-studio/server/engine/context.ts:32">
P1: `checkCancelled()` silently succeeds if the execution doesn&#39;t exist. When `getExecution` returns null/undefined, the optional chaining causes the status check to evaluate to false, and no error is thrown. Consider throwing an error when the execution is not found to prevent operations on non-existent executions.</violation>
</file>

<file name="mcp-studio/server/tools/_helpers.ts">

<violation number="1" location="mcp-studio/server/tools/_helpers.ts:77">
P0: SQL injection vulnerability: `fieldName` is directly interpolated into SQL without sanitization. While values are properly parameterized, field names are not. Consider validating field names against an allowlist or using a safe identifier escaping function.</violation>

<violation number="2" location="mcp-studio/server/tools/_helpers.ts:151">
P0: SQL injection vulnerability: `direction` is not validated before interpolation. It should be restricted to &#39;ASC&#39; or &#39;DESC&#39; only.</violation>

<violation number="3" location="mcp-studio/server/tools/_helpers.ts:152">
P0: SQL injection vulnerability: `nulls` is not validated before interpolation. It should be restricted to &#39;FIRST&#39; or &#39;LAST&#39; only.</violation>
</file>

<file name="mcp-studio/server/db/schemas/workflow.ts">

<violation number="1" location="mcp-studio/server/db/schemas/workflow.ts:49">
P2: Missing FOREIGN KEY constraint on `workflow_id`. This column references the `workflow` table but has no FK constraint, unlike similar relationships elsewhere in this schema (e.g., `workflow_execution_step_result.execution_id` and `workflow_event.execution_id` both have FK constraints). This could lead to orphaned executions referencing non-existent workflows.</violation>
</file>

<file name="mcp-studio/server/utils/ref-resolver.ts">

<violation number="1" location="mcp-studio/server/utils/ref-resolver.ts:60">
P1: Bug: `startsWith(&quot;input&quot;)` incorrectly matches step names like `@inputs` or `@inputData`. Should use the same pattern as the &quot;item&quot; case: exact match OR dot prefix.</violation>
</file>

<file name="mcp-studio/server/engine/steps/code-step.ts">

<violation number="1" location="mcp-studio/server/engine/steps/code-step.ts:37">
P2: Regex `[^}]*` will fail for interfaces with nested object types. The pattern stops at the first `}`, so `interface Input { user: { name: string }; }` would extract incomplete content. Consider using a brace-counting approach or a proper parser, or document this as a known limitation for simple interfaces only.</violation>
</file>

<file name=".github/workflows/SECRETS.md">

<violation number="1" location=".github/workflows/SECRETS.md:38">
P2: Missing warning about short-lived tokens. Tokens from Graph API Explorer typically expire in 1-2 hours. For production deployments via GitHub Actions, users should be warned to exchange for a long-lived token (60 days) or the deployment will break. Consider adding a note like:
  - ⚠️ **Important**: Tokens from Graph API Explorer are short-lived. For production, exchange for a long-lived token (see meta-ads/README.md)</violation>
</file>

<file name="connection-binding/app.json">

<violation number="1" location="connection-binding/app.json:14">
P1: The `inputSchema` for `COLLECTION_CONNECTIONS_GET` is missing `required: [&quot;id&quot;]` and `additionalProperties: false`. Without marking `id` as required, the schema allows GET requests without specifying which connection to retrieve, which would fail at runtime.</violation>
</file>

<file name="mcp-studio/server/db/queries/executions.ts">

<violation number="1" location="mcp-studio/server/db/queries/executions.ts:426">
P1: Pagination logic is broken: `totalCount` is set to the returned items count instead of actual total count from database. This causes `hasMore` to always be `false`. A separate `COUNT(*)` query is needed for accurate pagination.</violation>
</file>

<file name="mcp-studio/server/sandbox/utils/call-function.ts">

<violation number="1" location="mcp-studio/server/sandbox/utils/call-function.ts:11">
P1: Memory leak: QuickJS handles are created but never disposed. Following the pattern in other files (e.g., `to-quickjs.ts`, `console.ts`, `fetch.ts`), handles should be disposed after use. Consider wrapping in try/finally to dispose `thisArgHandle`, `argHandles`, `result`, and `resultPromise.handle`.</violation>
</file>

<file name="mcp-studio/server/sandbox/index.ts">

<violation number="1" location="mcp-studio/server/sandbox/index.ts:112">
P2: The `setDeadline` function is defined but never exposed to callers. It&#39;s not returned or attached to the context, making it inaccessible and effectively dead code. If dynamic deadline updates are intended, consider exposing this function; otherwise, remove it to reduce confusion.</violation>

<violation number="2" location="mcp-studio/server/sandbox/index.ts:117">
P1: Interrupt handler is set per-context but QuickJS only supports one handler per runtime. When multiple contexts are created, only the last context&#39;s deadline will be checked. Earlier contexts will never be interrupted, potentially causing runaway executions.

Consider moving deadline tracking to a shared structure at the runtime level (e.g., a Map of context IDs to deadlines), and have a single interrupt handler check all active deadlines.</violation>
</file>

<file name="mcp-studio/server/tools/execution.ts">

<violation number="1" location="mcp-studio/server/tools/execution.ts:30">
P2: Copy-paste error: Error message references wrong binding name. This checks `CREATE_BINDING` but the error message says `COLLECTION_WORKFLOW_EXECUTION_GET` instead of `COLLECTION_WORKFLOW_EXECUTION_CREATE`.</violation>
</file>

<file name="mcp-studio/server/engine/steps/tool-step.ts">

<violation number="1" location="mcp-studio/server/engine/steps/tool-step.ts:136">
P3: Comment says &quot;force http if not local&quot; but code sets `https:`. The comment should say &quot;force https if not local&quot;.</violation>
</file>

<file name="mcp-studio/server/sandbox/utils/to-quickjs.ts">

<violation number="1" location="mcp-studio/server/sandbox/utils/to-quickjs.ts:23">
P1: Memory leak: QuickJS handles created for object properties are not disposed after `setProp`. Add `hv.dispose()` after the `setProp` call.</violation>
</file>

<file name="mcp-studio/server/events/handler.ts">

<violation number="1" location="mcp-studio/server/events/handler.ts:22">
P1: Unwaited async operation in event handler. `executeWorkflow` returns a Promise but is not awaited, so the function returns before workflow execution completes. In event bus handlers, this can cause the runtime to terminate early, dropping workflow executions. Consider making the handler async and using `Promise.allSettled()` to wait for all executions.</violation>
</file>

<file name=".github/workflows/deploy.yml">

<violation number="1" location=".github/workflows/deploy.yml:77">
P1: The `META_ACCESS_TOKEN` secret won&#39;t be deployed. The `scripts/deploy.ts` file still references `META_APP_ID` and `META_APP_SECRET` in the `envVarsToPass` array (lines 149-150) but doesn&#39;t include the new `META_ACCESS_TOKEN`. This means the secret is available in the runner but won&#39;t be propagated to the deployed MCPs.</violation>
</file>

<file name="meta-ads/package.json">

<violation number="1" location="meta-ads/package.json:12">
P2: Replacing `tsc --noEmit` with `oxlint` removes type checking from the `check` script. These tools serve different purposes—`tsc` catches type errors while `oxlint` catches linting/style issues. Consider keeping both: `&quot;check&quot;: &quot;tsc --noEmit &amp;&amp; bun run oxlint server/&quot;`.</violation>
</file>

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

let status = 200;
let statusText = "OK";
// @ts-ignore
let _headers: Record<string, string> = {};
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 30, 2025

Choose a reason for hiding this comment

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

P2: The _headers variable is parsed from init options but never used. Headers passed to the Response constructor are silently ignored. Either implement the headers functionality or remove the dead code.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At mcp-studio/server/sandbox/builtins/fetch.ts, line 29:

<comment>The `_headers` variable is parsed from init options but never used. Headers passed to the Response constructor are silently ignored. Either implement the headers functionality or remove the dead code.</comment>

<file context>
@@ -0,0 +1,186 @@
+        let status = 200;
+        let statusText = &quot;OK&quot;;
+        // @ts-ignore
+        let _headers: Record&lt;string, string&gt; = {};
+
+        if (init &amp;&amp; init !== ctx.null &amp;&amp; init !== ctx.undefined) {
</file context>

✅ Addressed in 2a62a6c

};
}>;
// Accepts an (empty) object because MCP tool validation rejects `undefined` inputs.
COLLECTION_CONNECTIONS_LIST: (params?: Record<string, never>) => Promise<{
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 30, 2025

Choose a reason for hiding this comment

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

P2: Optional parameter contradicts the comment. If MCP tool validation rejects undefined inputs, then params should be required (not optional) to ensure callers always pass an empty object {}.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At mcp-studio/server/types/env.ts, line 45:

<comment>Optional parameter contradicts the comment. If MCP tool validation rejects `undefined` inputs, then `params` should be required (not optional) to ensure callers always pass an empty object `{}`.</comment>

<file context>
@@ -0,0 +1,66 @@
+    };
+  }&gt;;
+  // Accepts an (empty) object because MCP tool validation rejects `undefined` inputs.
+  COLLECTION_CONNECTIONS_LIST: (params?: Record&lt;string, never&gt;) =&gt; Promise&lt;{
+    items: {
+      id: string;
</file context>

✅ Addressed in e5155fe

Example workflow with a step that references the output of another step:
{ "title": "Get first user and then fetch orders", "steps": [
true }, "transformCode": "export default async (i) => i[0]" },
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 30, 2025

Choose a reason for hiding this comment

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

P2: Malformed JSON example in documentation. Line 229 starts with true }, which is invalid - the first step definition is truncated. It should likely be something like { "name": "fetch_users", "action": { "toolName": "GET_USERS" }, "transformCode": "export default async (i) => i[0]" },

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

<comment>Malformed JSON example in documentation. Line 229 starts with `true },` which is invalid - the first step definition is truncated. It should likely be something like `{ &quot;name&quot;: &quot;fetch_users&quot;, &quot;action&quot;: { &quot;toolName&quot;: &quot;GET_USERS&quot; }, &quot;transformCode&quot;: &quot;export default async (i) =&gt; i[0]&quot; },`</comment>

<file context>
@@ -0,0 +1,379 @@
+
+Example workflow with a step that references the output of another step:
+{ &quot;title&quot;: &quot;Get first user and then fetch orders&quot;, &quot;steps&quot;: [
+  true }, &quot;transformCode&quot;: &quot;export default async (i) =&gt; i[0]&quot; },
+  { &quot;name&quot;: &quot;fetch_orders&quot;, &quot;action&quot;: { &quot;toolName&quot;: &quot;GET_ORDERS&quot; }, &quot;input&quot;: { &quot;user&quot;: &quot;@fetch_users.user&quot; } },
+]}
</file context>
Fix with Cubic

return { step, result };
} catch (err) {
console.error("Step failed", step.name, err);
updateStepResult(env, executionId, step.name, {
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 30, 2025

Choose a reason for hiding this comment

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

P1: Missing await on async updateStepResult call. The database update may not complete before the error is thrown, and any database errors will be silently lost as unhandled promise rejections.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At mcp-studio/server/engine/executor.ts, line 182:

<comment>Missing `await` on async `updateStepResult` call. The database update may not complete before the error is thrown, and any database errors will be silently lost as unhandled promise rejections.</comment>

<file context>
@@ -0,0 +1,219 @@
+        return { step, result };
+      } catch (err) {
+        console.error(&quot;Step failed&quot;, step.name, err);
+        updateStepResult(env, executionId, step.name, {
+          error: err instanceof Error ? err.message : String(err),
+          completed_at_epoch_ms: Date.now(),
</file context>
Fix with Cubic

return this.env.MESH_REQUEST_CONTEXT?.meshUrl ?? "";
}

async checkCancelled(): Promise<void> {
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 30, 2025

Choose a reason for hiding this comment

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

P1: checkCancelled() silently succeeds if the execution doesn't exist. When getExecution returns null/undefined, the optional chaining causes the status check to evaluate to false, and no error is thrown. Consider throwing an error when the execution is not found to prevent operations on non-existent executions.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At mcp-studio/server/engine/context.ts, line 32:

<comment>`checkCancelled()` silently succeeds if the execution doesn&#39;t exist. When `getExecution` returns null/undefined, the optional chaining causes the status check to evaluate to false, and no error is thrown. Consider throwing an error when the execution is not found to prevent operations on non-existent executions.</comment>

<file context>
@@ -0,0 +1,73 @@
+    return this.env.MESH_REQUEST_CONTEXT?.meshUrl ?? &quot;&quot;;
+  }
+
+  async checkCancelled(): Promise&lt;void&gt; {
+    const execution = await getExecution(this.env, this.executionId);
+    if (execution?.status === &quot;cancelled&quot;) {
</file context>
Fix with Cubic

const fixProtocol = (url: URL) => {
const isLocal = url.hostname === "localhost" || url.hostname === "127.0.0.1";
if (!isLocal) {
// force http if not local
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 30, 2025

Choose a reason for hiding this comment

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

P3: Comment says "force http if not local" but code sets https:. The comment should say "force https if not local".

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At mcp-studio/server/engine/steps/tool-step.ts, line 136:

<comment>Comment says &quot;force http if not local&quot; but code sets `https:`. The comment should say &quot;force https if not local&quot;.</comment>

<file context>
@@ -0,0 +1,258 @@
+const fixProtocol = (url: URL) =&gt; {
+  const isLocal = url.hostname === &quot;localhost&quot; || url.hostname === &quot;127.0.0.1&quot;;
+  if (!isLocal) {
+    // force http if not local
+    url.protocol = &quot;https:&quot;;
+  }
</file context>
Fix with Cubic

if (Array.isArray(value)) {
const arr = ctx.newArray();
value.forEach((v, i) => {
const hv = toQuickJS(ctx, v);
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 30, 2025

Choose a reason for hiding this comment

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

P1: Memory leak: QuickJS handles created for object properties are not disposed after setProp. Add hv.dispose() after the setProp call.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At mcp-studio/server/sandbox/utils/to-quickjs.ts, line 23:

<comment>Memory leak: QuickJS handles created for object properties are not disposed after `setProp`. Add `hv.dispose()` after the `setProp` call.</comment>

<file context>
@@ -0,0 +1,126 @@
+      if (Array.isArray(value)) {
+        const arr = ctx.newArray();
+        value.forEach((v, i) =&gt; {
+          const hv = toQuickJS(ctx, v);
+          ctx.setProp(arr, String(i), hv);
+        });
</file context>
Fix with Cubic

/**
* Handle a batch of workflow events.
*/
export function handleWorkflowEvents(events: WorkflowEvent[], env: Env): void {
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 30, 2025

Choose a reason for hiding this comment

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

P1: Unwaited async operation in event handler. executeWorkflow returns a Promise but is not awaited, so the function returns before workflow execution completes. In event bus handlers, this can cause the runtime to terminate early, dropping workflow executions. Consider making the handler async and using Promise.allSettled() to wait for all executions.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At mcp-studio/server/events/handler.ts, line 22:

<comment>Unwaited async operation in event handler. `executeWorkflow` returns a Promise but is not awaited, so the function returns before workflow execution completes. In event bus handlers, this can cause the runtime to terminate early, dropping workflow executions. Consider making the handler async and using `Promise.allSettled()` to wait for all executions.</comment>

<file context>
@@ -0,0 +1,34 @@
+/**
+ * Handle a batch of workflow events.
+ */
+export function handleWorkflowEvents(events: WorkflowEvent[], env: Env): void {
+  for (const event of events) {
+    if (!event.subject) continue;
</file context>
Fix with Cubic

PERPLEXITY_API_KEY: ${{ secrets.PERPLEXITY_API_KEY }}
META_APP_ID: ${{ secrets.META_APP_ID }}
META_APP_SECRET: ${{ secrets.META_APP_SECRET }}
META_ACCESS_TOKEN: ${{ secrets.META_ACCESS_TOKEN }}
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 30, 2025

Choose a reason for hiding this comment

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

P1: The META_ACCESS_TOKEN secret won't be deployed. The scripts/deploy.ts file still references META_APP_ID and META_APP_SECRET in the envVarsToPass array (lines 149-150) but doesn't include the new META_ACCESS_TOKEN. This means the secret is available in the runner but won't be propagated to the deployed MCPs.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/deploy.yml, line 77:

<comment>The `META_ACCESS_TOKEN` secret won&#39;t be deployed. The `scripts/deploy.ts` file still references `META_APP_ID` and `META_APP_SECRET` in the `envVarsToPass` array (lines 149-150) but doesn&#39;t include the new `META_ACCESS_TOKEN`. This means the secret is available in the runner but won&#39;t be propagated to the deployed MCPs.</comment>

<file context>
@@ -74,8 +74,7 @@ jobs:
           PERPLEXITY_API_KEY: ${{ secrets.PERPLEXITY_API_KEY }}
-          META_APP_ID: ${{ secrets.META_APP_ID }}
-          META_APP_SECRET: ${{ secrets.META_APP_SECRET }}
+          META_ACCESS_TOKEN: ${{ secrets.META_ACCESS_TOKEN }}
 
       - name: Notify success
</file context>
Fix with Cubic

"build": "bun run build:server",
"publish": "cat app.json | deco registry publish -w /shared/deco -y",
"check": "tsc --noEmit",
"check": "bun run oxlint server/",
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 30, 2025

Choose a reason for hiding this comment

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

P2: Replacing tsc --noEmit with oxlint removes type checking from the check script. These tools serve different purposes—tsc catches type errors while oxlint catches linting/style issues. Consider keeping both: "check": "tsc --noEmit && bun run oxlint server/".

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

<comment>Replacing `tsc --noEmit` with `oxlint` removes type checking from the `check` script. These tools serve different purposes—`tsc` catches type errors while `oxlint` catches linting/style issues. Consider keeping both: `&quot;check&quot;: &quot;tsc --noEmit &amp;&amp; bun run oxlint server/&quot;`.</comment>

<file context>
@@ -9,7 +9,7 @@
     &quot;build&quot;: &quot;bun run build:server&quot;,
     &quot;publish&quot;: &quot;cat app.json | deco registry publish -w /shared/deco -y&quot;,
-    &quot;check&quot;: &quot;tsc --noEmit&quot;,
+    &quot;check&quot;: &quot;bun run oxlint server/&quot;,
     &quot;dev:tunnel&quot;: &quot;deco link -p 3003 -- PORT=3003 bun run dev&quot;
   },
</file context>

✅ Addressed in 27da5de

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.

1 issue found across 6 files (changes from recent commits).

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="mcp-studio/server/tools/workflow.ts">

<violation number="1" location="mcp-studio/server/tools/workflow.ts:305">
P0: Typo introduces SQL syntax error. The stray `y` character at the beginning of the `UPDATE` statement will cause all workflow update operations to fail with a syntax error.</violation>
</file>

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

params.push(id);

const sql = `
y UPDATE workflow_collection
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 31, 2025

Choose a reason for hiding this comment

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

P0: Typo introduces SQL syntax error. The stray y character at the beginning of the UPDATE statement will cause all workflow update operations to fail with a syntax error.

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

<comment>Typo introduces SQL syntax error. The stray `y` character at the beginning of the `UPDATE` statement will cause all workflow update operations to fail with a syntax error.</comment>

<file context>
@@ -302,7 +302,7 @@ async function updateWorkflowCollection(
 
   const sql = `
-        UPDATE workflow_collection
+y        UPDATE workflow_collection
         SET ${setClauses.join(&quot;, &quot;)}
         WHERE id = ?
</file context>
Suggested change
y UPDATE workflow_collection
UPDATE workflow_collection
Fix with Cubic

Signed-off-by: Marcos Candeia <[email protected]>
Signed-off-by: Marcos Candeia <[email protected]>
Signed-off-by: Marcos Candeia <[email protected]>
Signed-off-by: Marcos Candeia <[email protected]>
@mcandeia mcandeia merged commit 23c4e9d into main Dec 31, 2025
10 of 13 checks passed
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.

7 participants