Skip to content
Recipes

Recipes

Practical multi-step patterns that solve real customer problems. Each one runs against the live API with a real key. Click a language tab to switch the snippet — same recipe, your language.

Compress a PDF under a target size

PDFLoopingFile ops

You have a 30 MB PDF and need to email it (Gmail 25 MB limit). The compressor returns the file size of the output — call it in a loop, lowering quality until the threshold is met, capped at 4 attempts so we don't spin forever.

import { JohnsEssentials } from "@johns-essentials/sdk";
const je = new JohnsEssentials({ apiKey: process.env.JE_API_KEY });

const target = 25 * 1024 * 1024; // 25 MB
const qualities = ["high", "medium", "low", "screen"];

let out;
for (const quality of qualities) {
  out = await je.tools.pdf.compress({
    file: await readFile("./report.pdf"),
    quality,
  });
  if (out.size <= target) break;
}
console.log(`Settled at ${out.quality}: ${out.size} bytes`);

Turn a folder of invoices into a structured CSV

AgentOCRBatch

Drop 200 PDF invoices in S3, get one CSV with vendor / date / amount / line items. Uses the agent endpoint with the bundled `invoice_to_spreadsheet` prompt — the orchestrator picks the right tools (OCR → entity extract → join) without you wiring them.

import { JohnsEssentials } from "@johns-essentials/sdk";
const je = new JohnsEssentials({ apiKey: process.env.JE_API_KEY });

const fileIds = await Promise.all(
  invoicePaths.map(p => je.files.upload(p)),
).then(rs => rs.map(r => r.id));

for await (const ev of je.agent.runStream({
  prompt: "Extract each invoice into one CSV: vendor, date, amount, line items.",
  files: fileIds,
})) {
  if (ev.type === "cost") console.log(`spent so far: $${ev.cost_usd_so_far}`);
  if (ev.type === "complete") console.log("done:", ev.result);
}

Remove backgrounds from a batch of product photos

PhotoBatchIdempotency

Marketplace listings need transparent backgrounds. Loop the `image_remove_background` tool — it returns PNGs with alpha. Use `Idempotency-Key` so a network blip doesn't double-bill you.

import { JohnsEssentials } from "@johns-essentials/sdk";
import crypto from "node:crypto";

const je = new JohnsEssentials({ apiKey: process.env.JE_API_KEY });

await Promise.all(images.map(async (img) => {
  const r = await je.tools.image.removeBackground({
    file: img,
    idempotencyKey: crypto.randomUUID(),
  });
  await writeFile(`out/${img.name}.png`, r.data);
}));

Get a webhook when a long-running tool finishes

WebhooksHMACAsync

Agent runs and big OCR jobs can take minutes. Poll long enough and you'll annoy your rate limit. Register a webhook URL, kick off the work, get pinged when it's done. Signature scheme is Stripe-style HMAC with a 5-minute replay window.

// Express receiver — verify-then-act.
import crypto from "node:crypto";
import express from "express";

const app = express();
app.post("/hook", express.raw({ type: "application/json" }), (req, res) => {
  const sig = req.header("X-JE-Signature") ?? "";
  const [tPair, v1Pair] = sig.split(",");
  const t  = +tPair.split("=")[1];
  const v1 = v1Pair.split("=")[1];
  // 5-minute replay guard.
  if (Math.abs(Date.now() / 1000 - t) > 300) return res.status(400).send("stale");
  const expected = crypto.createHmac("sha256", SECRET)
    .update(`${t}.${req.body.toString()}`).digest("hex");
  if (!crypto.timingSafeEqual(Buffer.from(v1, "hex"), Buffer.from(expected, "hex"))) {
    return res.status(400).send("bad signature");
  }
  // ... safe to act on JSON.parse(req.body)
  res.status(200).end();
});

Connect Claude Desktop to your John's Essentials account

MCPClaude DesktopSetup

One paste, every tool. Claude Desktop reads its MCP servers from a JSON config file. Drop ours in, restart Claude, and all 110+ tools appear inside the app — same auth key you already use.

// 2. Edit Claude Desktop config:
//      macOS:   ~/Library/Application Support/Claude/claude_desktop_config.json
//      Windows: %APPDATA%\Claude\claude_desktop_config.json
//
// {
//   "mcpServers": {
//     "johns-essentials": {
//       "url": "https://api.johnsessentials.com/mcp/sse",
//       "headers": { "Authorization": "Bearer je_live_sk_..." }
//     }
//   }
// }
//
// 3. Restart Claude Desktop. Tools appear in the slash-menu.
Loading John’s Essentials