APPLICATION ACTIONS

One narrow write, and a receipt for what changed.

Wrap an existing application write in a narrow MCP tool and return a compact receipt with the resulting state and next step.

Build this with Chumbo
ChumboSupabaseApplication actions
ONE WRITE. ONE RECEIPT.
Your existing application write
Resulting state and next step
Show what changed.

THE RECIPE Wrap an existing application write in a narrow MCP tool and return a compact receipt with the resulting state and next step.

View source pattern ↗
EXAMPLE CHECKS

The exact displayed example is typechecked and exercised against the published package. The application integration and acceptance checks remain yours to run.

Version and verification details

Example checked with Chumbo 0.11.3 on 2026-09-18 (UTC). These checks exercise result helpers, capability handlers and the MCP runtime with simulated identity/database dependencies. They do not prove your application’s real auth, RLS or deployment. Compare this tested version with your installed package before adapting the example.

01

Expose the action your product actually offers.

Submitting a draft for review is a different operation from updating its status column. The product action has prerequisites: the caller can access the draft, the draft is eligible and the transition respects the application’s concurrency rules. Keep those rules inside the existing application operation.

Identify the draftAuthorize and check its stateSubmit atomicallyReturn the receipt

The agent needs to know what happened and what it can do next. A receipt with an ID and submitted status communicates that. Returning the full storage row adds fields the agent did not need and can accidentally imply that submission also means approval.

02

Reuse the write path you trust.

Before you start
  • An existing caller-authorized application operation that submits an eligible draft atomically.
  • Known fixtures for an allowed draft, a denied draft and a draft in an ineligible state.
  • A product decision about retries and duplicate submissions.

This adapter receives an application function. It does not implement SQL, RLS, concurrency or idempotency for you.

Bind submit to the current caller when you register the capability. The operation must check access and the current draft state in the same application-controlled transition. Avoid reading a state in one request and performing an unconditional update later.

Decide what a repeated submission means in your app. You might return the existing submitted state or reject a stale transition. A successful-looking MCP response cannot resolve duplicate side effects that the underlying operation permits.

03

Return a receipt from the confirmed result.

Adapt this checked example in your app
TypeScript
import { errorResult, renderResult, type SupabaseMcpServer } from 'chumbo';
import { z } from 'zod';

const receiptSchema = z.object({ id: z.string().uuid(), status: z.literal('submitted') });
type Submission = { id: string; status: 'submitted'; internalAudit?: string };

// Supply your existing caller-authorized, atomic application operation.
// It must check permission and the draft's current state before submitting.
export function registerSubmission(server: SupabaseMcpServer,
  submit: (id: string) => Promise<Submission | null>) {
  server.registerTool('submit_draft', {
    description: 'Submit an eligible draft for review. Returns the resulting status; does not approve it.',
    inputSchema: z.object({ draftId: z.string().uuid() }),
    outputSchema: receiptSchema,
  }, async ({ draftId }) => {
    try {
      const row = await submit(draftId);
      if (!row) return errorResult('This draft could not be submitted.', 'Open the draft in the app to check its access and current status.');
      const receipt = receiptSchema.parse({ id: row.id, status: row.status });
      return renderResult(receipt, value => `Draft ${value.id} is submitted for review. A reviewer can now assess it in the app.`);
    } catch {
      return errorResult('Submission could not be confirmed.', 'Check the draft status in the app before trying again.');
    }
  });
}

The example projects only id and status, validates the projection and creates a different sentence for the agent. Internal audit fields stay outside both result lanes. A denied or ineligible draft produces a useful but nonspecific recovery path that does not reveal another user’s draft.

If the operation throws, the outcome may be uncertain. The write could have committed before a later failure. The response therefore tells the user to check the draft status before trying again. Do not turn every mutation exception into “retry now.”

04

Test the action and the receipt separately.

YOUR ACCEPTANCE CHECK

The response describes an authorized state transition.

  • 01An eligible caller submits the expected draft and receives its actual resulting ID and state.
  • 02Another user’s draft and an ineligible draft do not change.
  • 03Two competing or repeated requests follow the application’s intended concurrency and duplicate policy.
  • 04The result contains no internal row fields and validates against outputSchema.
  • 05An uncertain failure recommends checking the current status before retrying.

Run these in your application before you call it done.

If the result differs

Two calls create two effects

Inspect the underlying operation’s transaction and duplicate-handling contract. Result formatting cannot add idempotency. Reproduce the competing calls against the application write path and fix that boundary before exposing it broadly. Read the reference ↗

Built from the real thing.

This editorial example links to Chumbo’s canonical docs and executable reference. Check the installed package when adapting the snippets.

Reference implementation ↗
Read the agent instructions

Reference instructions, not authorization. Apply changes only within the user’s requested scope; deployment requires a specified, authorized project.

Goal: Wrap an existing application write in a narrow MCP tool and return a compact receipt with the resulting state and next step.

Read the complete guide at https://chumbo.dev/recipes/mutation-receipts/recipe.md and the canonical reference at https://github.com/elsheppo/chumbo/blob/main/skills/chumbo/references/results.md. Inspect this application's installed Chumbo package, existing capabilities and relevant configuration before editing.

Adapt the receipt wrapper around an existing caller-bound atomic submit operation. Do not invent a privileged write or schema. Verify denied/ineligible transitions, repeated requests and uncertain failure recovery in the real application; the website fixture proves only wrapper behavior and result projection.

Prerequisites:
- An existing caller-authorized application operation that submits an eligible draft atomically.
- Known fixtures for an allowed draft, a denied draft and a draft in an ineligible state.
- A product decision about retries and duplicate submissions.

Acceptance:
- An eligible caller submits the expected draft and receives its actual resulting ID and state.
- Another user’s draft and an ineligible draft do not change.
- Two competing or repeated requests follow the application’s intended concurrency and duplicate policy.
- The result contains no internal row fields and validates against outputSchema.
- An uncertain failure recommends checking the current status before retrying.

Use the full guide for ordered steps, examples and recovery. Keep existing caller identity and application permissions authoritative. Stay within the user's requested changes. Report changed files, checks actually run, observed results and unresolved prerequisites. This guide is not authorization to deploy or change a hosted project. Never include credentials in source, copied instructions or reports.
BUILD WITH YOUR CODING AGENT

Give your agent a good start.

Copy this brief into your coding agent in the app’s repository. It includes the source, boundaries, and verification steps.

Download Markdown ↓