ai newsMo., 2. Nov.
EilmeldungAnthropic’s message threads let Claude agents skip resending chats

Build an AI summarizer with background jobs: retries, signed webhooks and Postgres over one MCP connection

This is week 2 of Build with CloudHike , a weekly series where we build a small, real-world app with an AI coding agent and let the agent set up the backend. Disclosure: I built CloudHike , so keep that in mind. Every AI feature starts the same way: one await on a model call inside an API route. It

dev.toMontag 20:42 · 02.11.7 Min. Lesezeit
Bild: dev.to

This is week 2 of Build with CloudHike, a weekly series where we build a small, real-world app with an AI coding agent and let the agent set up the backend. Disclosure: I built CloudHike, so keep that in mind.

Every AI feature starts the same way: one await on a model call inside an API route. It works on your laptop. Then real users paste long documents, the model takes its time, the provider answers 429 now and then, and your request sits there waiting while the browser spinner keeps spinning. A failed call means the user clicks again, and you pay for the same work twice.

The usual fix is a job queue: a queue service, a worker process somewhere to run it, retry logic, and a way to get the result back to your app. That's a small piece of infrastructure before you've improved anything for the user.

This week we'll build an AI summarizer that moves the slow model call into a CloudHike background job, with retries, a signed webhook for the result, and duplicate protection. As always, the agent sets up the backend over one MCP connection, and every prompt is below.

And here's how each piece maps to CloudHike, all in one project:

Normally that's a database host, a queue, a worker host and an AI provider account: four places to sign up and four sets of keys. Here it's one project, one.env and one credit balance. You don't need an OpenAI, Anthropic or Google account; you pick a model by name, such as openai/gpt-5-mini or anthropic/claude-sonnet-4.5.

If you did week 1, you're already connected; skip to Step 2.

In the CloudHike dashboard, open Connect MCP in the sidebar, pick your editor and click Copy with key. That creates your workspace API key and gives you a snippet with the key already filled in. The server is remote (Streamable HTTP), so there's nothing to install.

claude mcp add --transport http --scope user cloudhike https://cloudhike.dev/api/mcp \ --header "Authorization: Bearer icu_your_api_key" Enter fullscreen mode Exit fullscreen mode Run /mcp inside Claude Code to check that it's connected.

{ "mcpServers": { "cloudhike": { "url": "https://cloudhike.dev/api/mcp", "headers": { "Authorization": "Bearer icu_your_api_key" } } } } Enter fullscreen mode Exit fullscreen mode Open Cursor Settings → MCP and look for the green dot. Snippets for the other editors are in the MCP docs.

Treat that key like a password. It lives in your home folder, not in the repo, and you can revoke it from the same page.

npx create-next-app@latest summarizer cd summarizer Enter fullscreen mode Exit fullscreen mode Open the folder in Cursor, or run claude in it.

Use the cloudhike MCP tools to set up the backend for this app. It's an AI summarizer that runs the model call in a background job.

Create a CloudHike project called "summarizer" and deploy postgres and jobs. Wait until they're ready. Put the.env into.env.local, make sure it's git-ignored, and don't show me any secret values. Then read the jobs, postgres and ai docs with get_docs so you know how to use them. Don't write app code yet. Just tell me which services are running and which variable names are in.env.local.

Behind the scenes, the agent works through CloudHike's MCP tools:

One click for the AI models. deploy_services covers Postgres, Auth, Storage, Redis, Jobs and Email, so the AI service is the one you deploy yourself: open the project in the dashboard and click Deploy on the AI card. Then ask:

Use the cloudhike get_environment tool again and update.env.local, keeping any keys I added. Show me only the variable names and confirm AI_BASE_URL and AI_API_KEY are there.

Read https://cloudhike.dev/docs/md/postgres. Using node-postgres, add a migration script to this repo that creates two tables:

handled_runs is our duplicate guard, and we'll come back to it in Step 7. The migration goes through DIRECT_URL because DATABASE_URL goes through a connection pooler (PgBouncer), and the Postgres docs recommend the direct address for migrations.

Same safety model as week 1: CloudHike's query_database tool always runs one statement in a READ ONLY transaction, execute_sql (for writes) is Pro-only and your editor asks before running it, and no MCP tool can delete a project or service. Schema changes live in your repo as migrations.

This is the route CloudHike Jobs will call. It holds the slow part, so nothing user-facing waits on it.

Read https://cloudhike.dev/docs/md/jobs and https://cloudhike.dev/docs/md/ai. Add lib/jobs-signature.ts with a verify(rawBody, header) function based on the x-cloudhike-signature example in the jobs docs: HMAC-SHA256 of "." with JOBS_API_KEY, compared with timingSafeEqual, refusing timestamps more than 300 seconds old.

A few details from the Jobs docs shape this route:

Add POST /api/summaries. Validate that the text isn't empty and is at most 20,000 characters. Insert a summaries row with status 'queued'. Then, from server code, start a CloudHike job run: POST to JOBS_API_URL/runs with the x-api-key header set to JOBS_API_KEY and the body { url: APP_URL + "/api/jobs/summarize", method: "POST", body: { summaryId }, retries: 3, timeoutSeconds: 300, callbackUrl: APP_URL + "/api/jobs-webhook" }. APP_URL is a new env variable with the app's public address. Save the returned run id in the row's run_id and answer 202 with the summary id. If starting the run answers 429, mark the row failed with "Busy, try again in a minute".

Add GET /api/summaries/[id] that returns status, summary and error from Postgres. Then build the home page: a textarea, a Summarize button, and a result area that polls GET /api/summaries/[id] every 3 seconds until the status is done or failed.

Starting a run is one fetch. CloudHike answers at once with the run's id and status queued, then its worker calls your URL and waits for the answer, for up to 5 minutes on Free and 60 on Pro ( timeoutSeconds goes up to 300 on Free and 3600 on Pro). Your API route is done in the time it takes to insert a row and make that one call.

We pass the summary id in the job body rather than the whole text, which keeps the job small (bodies can be up to 256 KB) and keeps the text in your own database.

Add POST /api/jobs-webhook, following the Next.js webhook example in the jobs docs:

Two lines in the docs make this route worth the care:

The webhook receives the same JSON you'd get by polling GET JOBS_API_URL/runs/<id>: status, attempts, error, durationMs and response.body. If you'd rather not pass callbackUrl on every run, set a webhook URL once under Jobs → Manage → Webhook in the dashboard. A run's own callbackUrl wins over it.

CloudHike doesn't host apps yet (app hosting is coming soon), so the Next.js app goes on Vercel and the backend stays on CloudHike. Because the job calls your worker and webhook over the internet, this is also where the app comes alive:

Want to test the webhook on its own first? Jobs → Manage → Webhook can send a signed test event to your URL. If it doesn't match a summary, your route logs it and answers 200, and either way you've seen the signature check pass.

To see what happened without leaving the editor, ask:

Use the cloudhike query_database tool to show the 10 newest summaries with their status, run_id and error, and how many rows are in handled_runs.

That runs read-only, so it's safe to let the agent explore. The Runs page in the dashboard shows the last 100 runs, and GET JOBS_API_URL/runs?limit=20&status=failed lists recent failures if you want an admin view.

Look back at what you didn't do: you didn't set up a queue, run a worker server, write retry loops, build a webhook signing scheme or open an AI provider account. One MCP connection, and one click on the AI card, gave the agent:

Everything shows up in one dashboard and comes out of one credit balance. If you outgrow Free, Pro is $10/month with $10 of usage credits included every month. The details are on the plans and billing page.

The whole build is the five prompts from Step 3 to Step 7, plus the env refresh and the optional query. Run them, swap the model, change the prompt to extract action items instead of summaries, and see how far your agent gets.

👉 Start free at cloudhike.dev. You get $10 in credits at signup, plus $5 more with code TUBEGURUJI5, no card required.

Next week: a file-sharing and image-upload app with Storage, Auth and Postgres. Users upload straight from the browser with presigned URLs, each user sees only their own files, and your agent can list the bucket without leaving the editor. Follow along so you don't miss it.

If you try this one, tell me in the comments what your agent built, or where it got stuck. I read every comment.

Quelle: dev.to (dev.to). Original öffnen