Convert executed workflow into a reusable notebook. Only use when workflow is complete or user explicitly requests. --- DESCRIPTION FORMAT (MARKDOWN) - MUST BE NEUTRAL --- Description is for ANY user of this recipe, not just the creator. Keep it generic. - NO PII (no real emails, names, ch...
Bulk/mass operation — affects multiple targets
Part of the Rube MCP server. Enforce policies on this tool with Intercept, the open-source MCP proxy.
AI agents use RUBE_CREATE_UPDATE_RECIPE to create or modify resources in Rube. Write operations carry medium risk because an autonomous agent could trigger bulk unintended modifications. Rate limits prevent a single agent session from making hundreds of changes in rapid succession. Argument validation ensures the agent passes expected values.
Without a policy, an AI agent could call RUBE_CREATE_UPDATE_RECIPE repeatedly, creating or modifying resources faster than any human could review. Intercept's rate limiting ensures write operations happen at a controlled pace, and argument validation catches malformed or unexpected inputs before they reach Rube.
Write tools can modify data. A rate limit prevents runaway bulk operations from AI agents.
tools:
RUBE_CREATE_UPDATE_RECIPE:
rules:
- action: allow
rate_limit:
max: 30
window: 60 See the full Rube policy for all 11 tools.
Agents calling write-class tools like RUBE_CREATE_UPDATE_RECIPE have been implicated in these attack patterns. Read the full case and prevention policy for each:
Other tools in the Write risk category across the catalogue. The same policy patterns (rate-limit, validate) apply to each.
Convert executed workflow into a reusable notebook. Only use when workflow is complete or user explicitly requests. --- DESCRIPTION FORMAT (MARKDOWN) - MUST BE NEUTRAL --- Description is for ANY user of this recipe, not just the creator. Keep it generic. - NO PII (no real emails, names, channel names, repo names) - NO user-specific defaults (defaults go in defaults_for_required_parameters only) - Use placeholder examples only Generate rich markdown with these sections: ## Overview [2-3 sentences: what it does, what problem it solves] ## How It Works [End-to-end flow in plain language] ## Key Features - [Feature 1] - [Feature 2] ## Step-by-Step Flow 1. **[Step]**: [What happens] 2. **[Step]**: [What happens] ## Apps & Integrations | App | Purpose | |-----|---------| | [App] | [Usage] | ## Inputs Required | Input | Description | Format | |-------|-------------|--------| | channel_name | Slack channel to post to | WITHOUT # prefix | (No default values here - just format guidance) ## Output [What the recipe produces] ## Notes & Limitations - [Edge cases, rate limits, caveats] --- CODE STRUCTURE --- Code has 2 parts: 1. DOCSTRING HEADER (comments) - context, learnings, version history 2. EXECUTABLE CODE - clean Python that runs DOCSTRING HEADER (preserve all history when updating): """ RECIPE: [Name] FLOW: [App1] → [App2] → [Output] VERSION HISTORY: v2 (current): [What changed] - [Why] v1: Initial version API LEARNINGS: - [API_NAME]: [Quirk, e.g., Response nested at data.data] KNOWN ISSUES: - [Issue and fix] """ Then EXECUTABLE CODE follows (keep code clean, learnings stay in docstring). --- INPUT SCHEMA (USER-FRIENDLY) --- Ask for: channel_name, repo_name, sheet_url, email_address Never ask for: channel_id, spreadsheet_id, user_id (resolve in code) Never ask for large inputs: use invoke_llm to generate content in code GOOD DESCRIPTIONS (explicit format, generic examples - no PII): channel_name: Slack channel WITHOUT # prefix repo_name: Repository name only, NOT owner/repo google_sheet_url: Full URL from browser gmail_label: Label as shown in Gmail sidebar REQUIRED vs OPTIONAL: - Required: things that change every run (channel name, date range, search terms) - Optional: generic settings with sensible defaults (sheet tab, row limits) --- DEFAULTS FOR REQUIRED PARAMETERS --- - Provide in defaults_for_required_parameters for all required inputs - Use values from workflow context - Use empty string if no value available - never hallucinate - Match types: string param needs string default, number needs number - Defaults are private to creator, not shared when recipe is published - SCHEDULE-FRIENDLY DEFAULTS: - Use RELATIVE time references unless user asks otherwise, not absolute dates ✓ "last_24_hours", "past_week", "7" (days back) ✗ "2025-01-15", "December 18, 2025" - - Never include timezone as an input parameter unless specifically asked - - Test: "Will this default work if recipe runs tomorrow?" --- CODING RULES --- SINGLE EXECUTION: Generate complete notebook that runs in one invocation. CODE CORRECTNESS: Must be syntactically and semantically correct and executable. ENVIRONMENT VARIABLES: All inputs via os.environ.get(). Code is shared - no PII. TIMEOUT: 4 min hard limit. Use ThreadPoolExecutor for bulk operations. SCHEMA SAFETY: Never assume API response schema. Use invoke_llm to parse unknown responses. NESTED DATA: APIs often double-nest. Always extract properly before using. ID RESOLUTION: Convert names to IDs in code using FIND/SEARCH tools. FAIL LOUDLY: Raise Exception if expected data is empty. Never silently continue. CONTENT GENERATION: Never hardcode text. Use invoke_llm() for generated content. DEBUGGING: Timestamp all print statements. NO META LOOPS: Never call RUBE_* or RUBE_* meta tools via run_composio_tool. OUTPUT: End with just output variable (no print). --- HELPERS --- Available in notebook (dont import). See RUBE_REMOTE_WORKBENCH for details: run_composio_tool(slug, args) returns (result, error) invoke_llm(prompt, reasoning_effort="low") returns (response, error) # reasoning_effort: "low" (bulk classification), "medium" (summarization), "high" (creative/complex content) # Always specify based on task - use low by default, medium for analysis, high for creative generation proxy_execute(method, endpoint, toolkit, ...) returns (result, error) upload_local_file(*paths) returns (result, error) --- CHECKLIST --- - Description: Neutral, no PII, no defaults - for any user - Docstring header: Version history, API learnings (preserve on update) - Input schema: Human-friendly names, format guidance, no large inputs - Defaults: In defaults_for_required_parameters, type-matched, from context - Code: Single execution, os.environ.get(), no PII, fail loudly - Output: Ends with just output. It is categorised as a Write tool in the Rube MCP Server, which means it can create or modify data. Consider rate limits to prevent runaway writes.
Add a rule in your Intercept YAML policy under the tools section for RUBE_CREATE_UPDATE_RECIPE. You can allow, deny, rate-limit, or validate arguments. Then run Intercept as a proxy in front of the Rube MCP server.
RUBE_CREATE_UPDATE_RECIPE is a Write tool with medium risk. Write tools should be rate-limited to prevent accidental bulk modifications.
Yes. Add a rate_limit block to the RUBE_CREATE_UPDATE_RECIPE rule in your Intercept policy. For example, setting max: 10 and window: 60 limits the tool to 10 calls per minute. Rate limits are tracked per agent session and reset automatically.
Set action: deny in the Intercept policy for RUBE_CREATE_UPDATE_RECIPE. The AI agent will receive a policy violation error and cannot call the tool. You can also include a reason field to explain why the tool is blocked.
RUBE_CREATE_UPDATE_RECIPE is provided by the Rube MCP server (Composio/Rube). Intercept sits as a proxy in front of this server to enforce policies before tool calls reach the server.
Open source. One binary. Zero dependencies.
npx -y @policylayer/intercept