Skip to content

feat(workflows): add mcp tool to make an email template transactional - #120056

Merged
trunk-io[bot] merged 4 commits into
masterfrom
posthog/workflows-mcp-make-transactional
Oct 22, 2026
Merged

trunk-io[bot] merged 4 commits into
masterfrom
posthog/workflows-mcp-make-transactional

Conversation

@mayteio

@mayteio mayteio commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

Problem

  • An agent can create and edit email templates over MCP, but it can't make one transactional. A person has to finish each template in the UI.
  • Making a template transactional is one-way, and its sends ignore marketing opt-outs. Neither the API docs nor the UI prompt says that it can't be undone.

Changes

  • Agents get a new MCP tool, workflows-make-email-template-transactional. The typed-confirm pattern generates it as a -prepare / -execute pair.
  • Prepare shows the user that the change can't be undone and that sends ignore marketing opt-outs. Execute runs only after the user types "confirm".
  • The tool uses the same workflows-transactional-email-api flag as the endpoint. The flag targets an organization group, and the MCP server evaluates flags with organization groups.
  • The endpoint already exists, so a deploy order between MCP and Django can't cause 404s.
  • The "Make transactional" prompt in the template's API tab gets one new line: "You can't undo this. The template stays transactional."
  • The make_transactional API description now states the same two facts.
  • Mechanical: regenerated OpenAPI types, MCP tool definitions, two schema snapshots, and the flag added to the snapshot test's flag map.
Before After
make-transactional-before make-transactional-after

How did you test this code?

Manual end-to-end test on a local hogli stack, with the workflows intent so the CDP workflow and email workers ran. The MCP server ran locally against the local API, and calls went through exec, as an agent's would.

  • search transactional lists the prepare and execute tools.
  • An image went through media-image-upload-start, a presigned POST, and media-image-upload-complete.
  • A template used that image and {{ variables.user_name }}. It was created through the REST API with HTML, because the local stack has no Unlayer key to render designs.
  • Prepare returned the one-way and opt-out warning.
  • Execute with the reply "yes" was refused. Execute with "confirm" linked an active workflow with an api trigger, a function_email step and an exit.
  • A replay of the same confirmation hash was refused.
  • A second prepare and execute on the same template returned the same workflow, so the tool is idempotent.
  • A from_integration_id with no sender behind it returned the sender_unavailable 400 through the tool.
  • With the backend flag off, execute returned the endpoint's 404 through the tool, and the template stayed non-transactional.
  • A send through POST /messaging_templates/:id/send/ with a project secret API key returned 202.
  • The email reached maildev from the verified sender, with the image URL and the Liquid variable rendered.
  • A send to example.com was skipped by the existing MX check, as designed.
  • In the UI, the API tab showed the new line. "Make transactional" switched the page to the API example and showed the Metrics, Sends and Versions tabs.

Automated: tool-schema-snapshots, instructions and lint-tool-names in services/mcp pass locally.

Not checked: MCP-side hiding of the tool when the flag is off. The local MCP server forces every flag on. The gate is in the generated tool definitions.

Test rationale: No new test. The tool is generated config, and the snapshot test covers its input schema. The endpoint's behavior is unchanged and already covered by products/messaging/backend/tests/api/test_message_templates.py.

Release status

  • This change is behind a feature flag and is not available to users

Docs update

None. No doc under docs/ covers transactional emails.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Agent: Claude Code (PostHog Desktop), Opus 5.5 (claude-opus-5-5)

🤖 Generated with Claude Code


Created with PostHog Desktop

@mayteio mayteio self-assigned this Oct 20, 2026
@trunk-io

trunk-io Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

😎 Merged successfully - details.

@Gilbert09
Gilbert09 requested a review from a team October 20, 2026 07:41
@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

🤖 CI report

⚠️ Trunk lane — backend Python lane

This PR is assigned to the backend Python lane. It runs backend Python tests and may merge in parallel with PRs in other lanes.

✅ Complexity (TypeScript) — clean

Cyclomatic complexity above the limit in changed typescript files (10 for production files, 15 for test files). Warn only: worth simplifying when you next touch these functions.

✅ Duplication (Python) — clean

New Python code duplication introduced by this branch. Fails at 70+ tokens in app code, or 150+ tokens when both copies live in test files. Advisory while the gate proves itself: extract a shared helper instead of copying.

✅ Duplication (TypeScript) — clean

New TypeScript code duplication introduced by this branch. Fails at 70+ tokens in app code, or 150+ tokens when both copies live in test files. Advisory while the gate proves itself: extract a shared helper instead of copying.

⚠️ Bundle size — 🔺 +84 B (+0.0%)

Uncompressed size of every built .js bundle, compared against the base branch.

Total: 75.91 MiB · 🔺 +84 B (+0.0%)

No file changed by more than 1000 B.

Posted automatically by build-bundle-size-report · uncompressed bytes from dist-report

⚠️ Eager graph — 2 over budget

How much code each root ships on the eager path — downloaded and parsed before the surface is interactive. Measured from the esbuild output chunks (post-tree-shake, static imports only); lazy import() / React.lazy chunks are not counted.

Root Eager (shipped) Δ vs base Budget
entry (logged-out pages, app bootstrap)
src/index.tsx
1.01 MiB · 24 files no change █████████░ 88.6% of 1.14 MiB
logged-out boot: index + App + bootApp (preloaded by every page, including /login)
src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
2.94 MiB · 618 files no change ██████████ 96.8% of 3.03 MiB
🟡 authenticated shell (every logged-in page)
src/scenes/AuthenticatedShell.tsx
7.63 MiB · 2,631 files no change ██████████ 101.8% of 7.50 MiB
dashboard scene
src/scenes/dashboard/Dashboard.tsx
9.64 MiB · 3,696 files no change ██████████ 96.3% of 10.01 MiB
🟡 today home path
src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
8.03 MiB · 2,973 files no change ██████████ 103.8% of 7.74 MiB
events scene
src/scenes/activity/explore/EventsScene.tsx
9.12 MiB · 3,487 files no change ██████████ 95.1% of 9.59 MiB
web analytics scene
src/scenes/web-analytics/WebAnalyticsScene.tsx
9.97 MiB · 3,702 files no change █████████░ 92.0% of 10.83 MiB
replay detail scene
src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
8.20 MiB · 3,068 files no change █████████░ 86.5% of 9.47 MiB

🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/index.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/svg/ stays out of src/index.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/components/ stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/layout/navigation-3000/navigationLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/scenes/dashboard/dashboardLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/lemon-ui/LemonMarkdown/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/RichContentEditor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/CodeSnippet/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/taxonomy/core-filter-definitions-by-group.json stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 node_modules/zod/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/scenes/billing/billingLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/ProductEmptyState/productSetupPreloadLogic.ts stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/scenes/AuthenticatedShell.tsx
🟢 products/dashboards/frontend/widgets/previews/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 products/wizard/frontend/runs/WizardRunDetailsDrawer.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 zod/v4/locales/de.js stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/svg/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/components/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.tsx stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/scenes/web-analytics/tiles/WebAnalyticsTile.tsx stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/queries/validators.js stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 src/scenes/project-homepage/today/TodayReportPage.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 src/queries/Query/Query.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.tsx stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/scenes/web-analytics/tiles/WebAnalyticsTile.tsx stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/queries/validators.js stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/scenes/web-analytics/LiveMetricsDashboard/LiveWebAnalyticsMetrics.tsx stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 products/product_analytics/frontend/insights/trends/WorldMap/countryVectors.tsx stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 src/scenes/settings/SettingsMap.tsx stays out of src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
🟢 @jspm/core/nodelibs/browser/fs stays out of src/scenes/session-recordings/detail/SessionRecordingDetail.tsx

Largest files eagerly shipped from src/index.tsx
Size File
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
24.6 KiB ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js
6.3 KiB ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js
4.5 KiB ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js
3.9 KiB ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js
1.4 KiB ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js
1.4 KiB src/index.tsx
1.3 KiB src/RootErrorBoundary.tsx
1.3 KiB src/lib/utils/bootTiming.ts
912 B ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js
Largest files eagerly shipped from src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
Size File
321.6 KiB ../node_modules/.pnpm/posthog-js@1.438.12_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
220.9 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
106.8 KiB src/products.tsx
98.3 KiB src/lib/api.ts
69.4 KiB src/lib/lemon-ui/icons/icons.tsx
38.7 KiB ../node_modules/.pnpm/@dnd-kit+core@6.0.8_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@dnd-kit/core/dist/core.esm.js
33.9 KiB ../node_modules/.pnpm/kea@4.0.0-pre.6_patch_hash=139b8d1f1304f9d9da452a9a1244c94ea679dbcb85687d8999563146879fb6f5_react@18.3.1/node_modules/kea/lib/index.cjs.js
29.4 KiB src/scenes/scenes.ts
26.9 KiB src/lib/constants.tsx
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
Size File
321.6 KiB ../node_modules/.pnpm/posthog-js@1.438.12_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
280.7 KiB src/taxonomy/core-filter-definitions-by-group.json
238.5 KiB ../packages/quill/packages/quill/dist/index.js
220.9 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
143.2 KiB ../packages/quill/packages/primitives/dist/index.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
106.8 KiB src/products.tsx
98.3 KiB src/lib/api.ts
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
Largest files eagerly shipped from src/scenes/dashboard/Dashboard.tsx
Size File
321.6 KiB ../node_modules/.pnpm/posthog-js@1.438.12_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
280.7 KiB src/taxonomy/core-filter-definitions-by-group.json
238.5 KiB ../packages/quill/packages/quill/dist/index.js
220.9 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
143.2 KiB ../packages/quill/packages/primitives/dist/index.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
106.8 KiB src/products.tsx
98.3 KiB src/lib/api.ts
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
Size File
321.6 KiB ../node_modules/.pnpm/posthog-js@1.438.12_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
280.7 KiB src/taxonomy/core-filter-definitions-by-group.json
238.5 KiB ../packages/quill/packages/quill/dist/index.js
220.9 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
143.2 KiB ../packages/quill/packages/primitives/dist/index.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
106.8 KiB src/products.tsx
98.3 KiB src/lib/api.ts
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
Largest files eagerly shipped from src/scenes/activity/explore/EventsScene.tsx
Size File
321.6 KiB ../node_modules/.pnpm/posthog-js@1.438.12_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
280.7 KiB src/taxonomy/core-filter-definitions-by-group.json
238.5 KiB ../packages/quill/packages/quill/dist/index.js
220.9 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
143.2 KiB ../packages/quill/packages/primitives/dist/index.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
106.8 KiB src/products.tsx
98.3 KiB src/lib/api.ts
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
Largest files eagerly shipped from src/scenes/web-analytics/WebAnalyticsScene.tsx
Size File
321.6 KiB ../node_modules/.pnpm/posthog-js@1.438.12_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
280.7 KiB src/taxonomy/core-filter-definitions-by-group.json
238.5 KiB ../packages/quill/packages/quill/dist/index.js
220.9 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
183.2 KiB src/queries/validators.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
143.2 KiB ../packages/quill/packages/primitives/dist/index.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
106.8 KiB src/products.tsx
98.3 KiB src/lib/api.ts
Largest files eagerly shipped from src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
Size File
321.6 KiB ../node_modules/.pnpm/posthog-js@1.438.12_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
315.9 KiB ../node_modules/.pnpm/posthog-js@1.438.12_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/rrweb.js
280.7 KiB src/taxonomy/core-filter-definitions-by-group.json
238.5 KiB ../packages/quill/packages/quill/dist/index.js
220.9 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
106.8 KiB src/products.tsx
98.3 KiB src/lib/api.ts
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js

Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479

✅ Toolbar bundle — eager 2.28 MiB within budget

What the toolbar ships to customer pages, measured from the esbuild output (minified, post-tree-shake). The eager set is the entry plus everything statically imported from it — fetched before any feature runs; deferred chunks load lazily. The eager guardrail is 5.72 MiB. Each output file must also stay below 10 MB, where CloudFront stops compressing it. The module boundary is enforced separately by check-toolbar-graph.

Metric Size Δ vs base Budget
Eager (shipped)
entry + static imports
2.28 MiB · 18 files no change ████░░░░░░ 39.9% of 5.72 MiB
Deferred (lazy) 2.10 MiB · 40 files no change n/a — loads on demand
Loader dist/toolbar.js 1.2 KiB no change █░░░░░░░░░ 6.0% of 19.5 KiB
Largest eagerly-shipped chunks
Size File
898.5 KiB dist/toolbar/toolbar-app-LIRVHRPD.css
691.1 KiB dist/toolbar/chunk-chunk-3UMULLO2.js
260.7 KiB dist/toolbar/chunk-chunk-OIINGWWL.js
131.8 KiB dist/toolbar/chunk-chunk-FDH2IBXT.js
130.4 KiB dist/toolbar/chunk-chunk-JQ6BCUXV.js
74.8 KiB dist/toolbar/toolbar-app-5OHL7N2N.js
69.0 KiB dist/toolbar/chunk-chunk-TSAL54PB.js
35.6 KiB dist/toolbar/chunk-chunk-UDDADHQK.js
21.7 KiB dist/toolbar/chunk-chunk-WDVBEMDN.js
6.8 KiB dist/toolbar/chunk-chunk-DV7IWQNF.js

Posted automatically by check-toolbar-size · sizes are toolbar output bytes (shipped, post-tree-shake) from the esbuild metafile

✅ Dist folder size — 🔺 +685 B (+0.0%)

Total size of the built frontend/dist folder (all assets), compared against the base branch.

Total: 1017.92 MiB · 🔺 +685 B (+0.0%)

ℹ️ MCP UI apps size — 34 app(s), 27964.5 KB JS

Built size of each MCP UI app (main.js + styles.css).

App JS CSS
debug 844.2 KB 209.0 KB
action 767.7 KB 209.0 KB
action-list 835.3 KB 209.0 KB
cohort 766.6 KB 209.0 KB
cohort-list 834.2 KB 209.0 KB
email-template 766.5 KB 209.0 KB
error-details 771.5 KB 209.0 KB
error-issue 768.0 KB 209.0 KB
error-issue-list 835.9 KB 209.0 KB
experiment 832.4 KB 209.0 KB
experiment-list 836.0 KB 209.0 KB
experiment-results 834.9 KB 209.0 KB
feature-flag 834.6 KB 209.0 KB
feature-flag-list 838.4 KB 209.0 KB
feature-flag-testing 769.9 KB 209.0 KB
inline-scan 767.1 KB 209.0 KB
insight-actors 833.7 KB 209.0 KB
llm-costs 831.0 KB 209.0 KB
session-recording 768.9 KB 209.0 KB
survey 768.2 KB 209.0 KB
survey-global-stats 831.1 KB 209.0 KB
survey-list 835.9 KB 209.0 KB
survey-stats 831.1 KB 209.0 KB
trace-span 767.0 KB 209.0 KB
trace-span-list 835.2 KB 209.0 KB
vision-observation-list 834.3 KB 209.0 KB
workflow 767.0 KB 209.0 KB
workflow-list 834.6 KB 209.0 KB
workflow-setup-status 766.7 KB 209.0 KB
query-results 1086.3 KB 209.0 KB
render-ui 1161.3 KB 209.0 KB
visual-review-snapshots 771.5 KB 209.0 KB
workflow-data-suggestions 769.3 KB 209.0 KB
workflow-sending-rules 768.0 KB 209.0 KB
ℹ️ MCP agent API — agent-facing tool changes

What this PR changes for agents, from the tool schema snapshots and tool definitions.

Tools added (2): workflows-make-email-template-transactional-execute (348 chars), workflows-make-email-template-transactional-prepare (332 chars)

✅ Playwright — all passed

All tests passed.

View test results →

✅ Hogbox preview — ready, open the preview

▶ Open the preview

🔑 Login test@posthog.com / 12345678 (demo data)
🧩 Running this PR's backend and frontend, on the PostHog :master base
🔗 Link stable across rebuilds: a re-push swaps the box underneath, the URL stays
🔒 Access tailnet only (PostHog VPN)
🛠️ Admin inspect & debug state in hogland
💤 Idle sleeps after ~30 min idle (snapshot to S3, zero node cost) and wakes on your next visit in ~30s, behind a brief "waking up" screen

commit 40083c1 · box box-be1d7ae0393e · ready in 1395s (push → usable) · build log · rebuilds on every push, torn down on close

@trunk-io

trunk-io Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Static Badge   Static Badge   Static Badge

Failed Test Failure Summary Logs
Scenes-App/Experiments ExperimentWithHealthFindings play-test The Storybook test could not find the text “Why?” in the experiment with health findings. Logs ↗︎
Scenes-App/People/Person PersonNotFound smoke-test The test timed out while waiting for loading indicators or spinners to disappear. Logs ↗︎

View Full Report ↗︎ ⋅ Docs

@mayteio
mayteio marked this pull request as ready for review October 20, 2026 10:35
@parameterai

parameterai Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Risk: No findings

This delta is a single commit that merges newer master into the branch and regenerates the MCP tool definitions: the make-transactional prepare/execute tools gain an api_operations field, and the generated MCP schemas pick up master's new template fields (sender, tags, sensitive, preheader, replyTo). I traced the sender, tag, and Idempotency-Key additions that arrived with the master merge end to end and found them correctly team-scoped and bounded, so the PR introduces no new security issues.

Sentinel reviewed c77bc94 · Review settings

@pr-assigner-resolver-posthog

Copy link
Copy Markdown

👀 Auto-assigned reviewers

These soft owners were skipped because they only have minor changes here. Nothing blocks merge, so self-assign if you'd like a look:

  • @PostHog/team-context-and-mcp (services/mcp/tests/owners.yaml)

Soft owners come from each directory's owners.yaml and each product's product.yaml (resolved nearest-file-wins). For a skipped owner, the locator is the file that decided it. Generated files and lockfiles are ignored when deciding ownership.

@posthog posthog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

PostHog Review · Standard · reviewed 16c755f: no findings.

This Standard review started from the posthog-review label. Comment @posthog review --deep for a Deep review, or @posthog help to see all commands.

@posthog posthog Bot removed the reviewhog label Oct 20, 2026
Comment thread products/workflows/mcp/email_templates.yaml Outdated
Agents can create and edit email templates over MCP but cannot make one transactional, which the move of PostHog's own transactional emails onto workflows needs.

- Add workflows-make-email-template-transactional as a typed-confirm prepare/execute pair, gated on workflows-transactional-email-api.
- Say in the tool, the API description and the UI prompt that the change can't be undone and that sends ignore marketing opt-outs.
- Regenerate OpenAPI types, MCP tool definitions and schema snapshots.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Generated-By: PostHog Desktop
Task-Id: c91d4fe4-cb37-4f9d-9598-946e91f7bc0c
… its flag

- Add workflows-transactional-email-api to the branch flags in tool-filtering.test.ts, so the required-flags count matches.
- Set destructive: true on workflows-make-email-template-transactional, because the change can't be undone. MCP clients then show their own confirm prompt too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Generated-By: PostHog Desktop
Task-Id: c91d4fe4-cb37-4f9d-9598-946e91f7bc0c
@mayteio
mayteio force-pushed the posthog/workflows-mcp-make-transactional branch from 40083c1 to 60babe1 Compare October 22, 2026 09:49
Adds the api_operations field that master's generator now emits for the make-transactional tool.

Generated-By: PostHog Desktop
Task-Id: 20d9dd00-fcbd-4c83-a5c3-68a47fd9be9a

mayteio commented Oct 22, 2026

Copy link
Copy Markdown
Contributor Author

/trunk merge

@trunk-io
trunk-io Bot merged commit ca6017e into master Oct 22, 2026
296 checks passed
@trunk-io
trunk-io Bot deleted the posthog/workflows-mcp-make-transactional branch October 22, 2026 10:35
@deployment-status-posthog

deployment-status-posthog Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-10-22 10:58 UTC Run
prod-us ✅ Deployed 2026-10-22 11:09 UTC Run
prod-eu ✅ Deployed 2026-10-22 11:10 UTC Run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants