Skip to main content
Glama

Deploy code that runs on an app's events

anyhook_code_deploy
Destructive

Save a handler that runs on every event this app receives, in an isolated sandbox, with AnyHook's retries and replay around it: no server of your own. Each run's console output and return value are stored as that delivery's response (anyhook_inspect shows them). It can also run on a cron schedule. Pro and Scale; runs are capped per month with no overage, retries, test runs and schedule firings each count, and each run and package install is charged to the monthly compute allowance (anyhook_usage shows both). Test it with anyhook_code_test before real events arrive.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
codeYesAn ES module, run in a sandboxed Node.js on every event this app receives. Either `export default async function (event, { env }) {}` (event: { method, headers, body, raw_body, delivery_id, attempt }; method is always POST, and the query string, path and caller IP are not kept) or a Pipedream Node.js code step: `export default defineComponent({ async run({ steps, $ }) {} })`, where steps.trigger.event is that same event (a step reading query, path, url or client_ip needs changing) and $.export and $.flow.exit work. npm packages it imports are installed on deploy (pin as "pkg@1.2.3", like Pipedream; a new package list usually takes seconds, a large one a few minutes). @pipedream/platform is a stand-in. State between events: the app's store (store.get/set/has/delete/keys, set takes { ttl }); every data_store prop is that one store, an app prop's this.<prop>.$auth.<field> reads the secret <APP>_<FIELD>, any other prop the secret named after it (channelId → CHANNEL_ID). Throwing fails the delivery, which AnyHook retries. Templates for common actions (Slack, email, Google Sheets, Notion, Claude and more): https://anyhook.net/code-templates.md
api_keyNoAPI key (ahk_live_...) from anyhook_quickstart. Only needed over HTTP when no Authorization header is set; ignored over stdio.
appSlugYesThe app whose events the code runs on.
enabledNoWhether events run the code. false saves it switched off, so it runs only through anyhook_code_test. Omit: a first deploy goes live and later deploys keep the current state. Deploy off while another system still handles the same events, or both will act on each one.
secretsNoEnvironment variables for the code, read as env.NAME or process.env.NAME. Merged into the saved ones; null removes a name.
scheduleNoAlso run on a cron schedule: five fields, UTC unless prefixed CRON_TZ=Area/City, e.g. "*/15 * * * *". Each firing arrives as an anyhook.schedule event and counts as a run. null removes it; omit to keep it. Only on an app that does not verify a sender's signature.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / code / description
      Previous value: -"An ES module, run in a sandboxed Node.js on every event this app receives. Either `export default async function (event, { env }) {}` (event: { method, headers, body, raw_body, delivery_id, attempt }) or a Pipedream code step as written: `export default defineComponent({ async run({ steps, $ }) {} })` with steps.trigger.event, $.export and $.flow.exit. npm packages it imports are installed on deploy (pin as \"pkg@1.2.3\", like Pipedream; a new package list takes up to a minute). @pipedream/platform is a stand-in. State between events: the app's store (store.get/set/has/delete/keys, set takes { ttl }); a step's data_store prop is the same store, an app prop's this.<prop>.$auth.<field> reads the secret <APP>_<FIELD>, any other prop the secret named after it (channelId → CHANNEL_ID). Throwing fails the delivery, which AnyHook retries. Templates for common actions (Slack, email, Google Sheets, Notion, Claude and more): https://anyhook.net/code-templates.md"New value: +"An ES module, run in a sandboxed Node.js on every event this app receives. Either `export default async function (event, { env }) {}` (event: { method, headers, body, raw_body, delivery_id, attempt }; method is always POST, and the query string, path and caller IP are not kept) or a Pipedream Node.js code step: `export default defineComponent({ async run({ steps, $ }) {} })`, where steps.trigger.event is that same event (a step reading query, path, url or client_ip needs changing) and $.export and $.flow.exit work. npm packages it imports are installed on deploy (pin as \"pkg@1.2.3\", like Pipedream; a new package list usually takes seconds, a large one a few minutes). @pipedream/platform is a stand-in. State between events: the app's store (store.get/set/has/delete/keys, set takes { ttl }); every data_store prop is that one store, an app prop's this.<prop>.$auth.<field> reads the secret <APP>_<FIELD>, any other prop the secret named after it (channelId → CHANNEL_ID). Throwing fails the delivery, which AnyHook retries. Templates for common actions (Slack, email, Google Sheets, Notion, Claude and more): https://anyhook.net/code-templates.md"
  2. Changed1 schema field changed
    • changedInput schema / properties / code / description
      Previous value: -"An ES module, run in a sandboxed Node.js on every event this app receives. Either `export default async function (event, { env }) {}` (event: { method, headers, body, raw_body, delivery_id, attempt }) or a Pipedream code step as written: `export default defineComponent({ async run({ steps, $ }) {} })` with steps.trigger.event, $.export and $.flow.exit. npm packages it imports are installed on deploy (pin as \"pkg@1.2.3\", like Pipedream; a new package list takes up to a minute). @pipedream/platform is a stand-in. State between events: the app's store (store.get/set/has/delete/keys, set takes { ttl }); a step's data_store prop is the same store, an app prop's this.<prop>.$auth.<field> reads the secret <APP>_<FIELD>, any other prop the secret named after it (channelId → CHANNEL_ID). Throwing fails the delivery, which AnyHook retries."New value: +"An ES module, run in a sandboxed Node.js on every event this app receives. Either `export default async function (event, { env }) {}` (event: { method, headers, body, raw_body, delivery_id, attempt }) or a Pipedream code step as written: `export default defineComponent({ async run({ steps, $ }) {} })` with steps.trigger.event, $.export and $.flow.exit. npm packages it imports are installed on deploy (pin as \"pkg@1.2.3\", like Pipedream; a new package list takes up to a minute). @pipedream/platform is a stand-in. State between events: the app's store (store.get/set/has/delete/keys, set takes { ttl }); a step's data_store prop is the same store, an app prop's this.<prop>.$auth.<field> reads the secret <APP>_<FIELD>, any other prop the secret named after it (channelId → CHANNEL_ID). Throwing fails the delivery, which AnyHook retries. Templates for common actions (Slack, email, Google Sheets, Notion, Claude and more): https://anyhook.net/code-templates.md"
  3. Changed1 schema field changed
    • changedInput schema / properties / code / description
      Previous value: -"An ES module, run in a sandboxed Node.js on every event this app receives. Either `export default async function (event, { env }) {}` (event: { method, headers, body, raw_body, delivery_id, attempt }) or a Pipedream code step as written: `export default defineComponent({ async run({ steps, $ }) {} })` with steps.trigger.event, $.export and $.flow.exit. npm packages it imports are installed on deploy (pin as \"pkg@1.2.3\", like Pipedream; a new package list takes up to a minute). @pipedream/platform is a stand-in. Throwing fails the delivery, which AnyHook retries."New value: +"An ES module, run in a sandboxed Node.js on every event this app receives. Either `export default async function (event, { env }) {}` (event: { method, headers, body, raw_body, delivery_id, attempt }) or a Pipedream code step as written: `export default defineComponent({ async run({ steps, $ }) {} })` with steps.trigger.event, $.export and $.flow.exit. npm packages it imports are installed on deploy (pin as \"pkg@1.2.3\", like Pipedream; a new package list takes up to a minute). @pipedream/platform is a stand-in. State between events: the app's store (store.get/set/has/delete/keys, set takes { ttl }); a step's data_store prop is the same store, an app prop's this.<prop>.$auth.<field> reads the secret <APP>_<FIELD>, any other prop the secret named after it (channelId → CHANNEL_ID). Throwing fails the delivery, which AnyHook retries."
  4. Changed1 schema field changed
    • changedInput schema / properties / code / description
      Previous value: -"An ES module, run in a sandboxed Node.js on every event this app receives. Either `export default async function (event, { env }) {}` (event: { method, headers, body, raw_body, delivery_id, attempt }) or a Pipedream code step as written: `export default defineComponent({ async run({ steps, $ }) {} })` with steps.trigger.event, $.export and $.flow.exit. fetch is global; `axios` and `@pipedream/platform` are fetch-based stand-ins; no other package is installed. Throwing fails the delivery, which AnyHook retries."New value: +"An ES module, run in a sandboxed Node.js on every event this app receives. Either `export default async function (event, { env }) {}` (event: { method, headers, body, raw_body, delivery_id, attempt }) or a Pipedream code step as written: `export default defineComponent({ async run({ steps, $ }) {} })` with steps.trigger.event, $.export and $.flow.exit. npm packages it imports are installed on deploy (pin as \"pkg@1.2.3\", like Pipedream; a new package list takes up to a minute). @pipedream/platform is a stand-in. Throwing fails the delivery, which AnyHook retries."
  5. Changed1 schema field changed
    • addedInput schema / properties / enabled
      Added value: +{
      +  "description": "Whether events run the code. false saves it switched off, so it runs only through anyhook_code_test. Omit: a first deploy goes live and later deploys keep the current state. Deploy off while another system still handles the same events, or both will act on each one.",
      +  "type": "boolean"
      +}
  6. Added

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare write (readOnlyHint=false) and destructiveHint=true, and the description confirms and enriches this: retries and replay wrap each run, throwing fails the delivery, null removes secrets and schedules, omitted fields preserve state, and Pro/Scale plans cap runs per month with each install charged to compute allowance. This goes well beyond what the annotations convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose is front-loaded and every sentence contributes (sandbox, plan limits, schedule, test-before-live). It is dense with long parenthetical clauses, which slightly hurts scannability, but there is no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, and the description covers the return path by explaining that console output and return values are stored as the delivery's response and surfaced through anyhook_inspect. Combined with plan limits, scheduling, state, and secret semantics, an agent has everything needed to deploy correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already carries detailed semantics for code, appSlug, enabled, secrets, and schedule including cron syntax and removal-by-null. The description reiterates some of this (cron, plan/run counting) but adds little parameter syntax the schema lacks, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a concrete verb and resource: 'Save a handler that runs on every event this app receives, in an isolated sandbox.' It is immediately distinguishable from siblings like anyhook_code_get, anyhook_code_test, and anyhook_events without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Routes the agent explicitly: test with anyhook_code_test before real events arrive, view output via anyhook_inspect, check limits via anyhook_usage. It also gives a when-not: deploy off while another system still handles the same events, or both will act on each one.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.