Fred • Engineering
From a chat message to an inbox of checked apartments
Overview
Fred is a tool-using AI agent with a web app around it. You chat with it in plain words, and it saves your search, starts crawlers on the listing sites, checks every building with the city and writes up the places that fit, while the app shows each step as it happens.
Why we built it. James and I built Fred at the AI Engineer NYC hackathon on October 11, 2026, because we’re hunting for an apartment ourselves and were tired of checking every site and alert email by hand. It had to be live by the end of the day, so we picked tools that ship fast, run without servers to look after, and let two people and their agents work at the same time without stepping on each other.
- Role
- I built the web app; James built the API, the agent and the crawlers
- Stack
- TypeScript · Next.js · Mastra · Claude · Hono · Zod · Cloudflare
- Surface
- Web app, chat and email alerts
- Focus
- Showing the agent’s work · nothing sent without you
Problem
Listings are scattered, incomplete and sometimes fake, and an agent has to act on them.
No listing site has an API
StreetEasy, Zillow and the rest only show their listings on their own pages, so every source needs its own crawler.
Search results leave things out
A listing card rarely says the fees, the pet policy or the laundry, which are the things renters ask about first.
The costly cases are the quiet ones
A broker fee, a building with open violations or a scam deposit is exactly where a confident wrong answer hurts most.
Trust needs receipts
To believe an agent, you need to see what it checked, where each number came from and what it doesn’t know.
How it works
Chat in, checked places out.
Four stages, with you in charge of anything that leaves the app.
1. You say what you want
Fred turns “1 bed under $4,500 in Greenpoint, dog OK” into a saved search: dealbreakers, nice-to-haves with a weight, and notes in its memory.
2. Fred checks the sites
It starts crawlers on StreetEasy, Zillow, RentHop, Zumper, Compass, Nooklyn, Craigslist and landlords’ own sites for that search. The same apartment on several sites becomes one place.
3. It checks each place
Code drops places that clearly miss a dealbreaker. Fred reads the full listing page when facts are missing, looks at the photos, and scores the building from NYC Open Data.
4. It writes up the ones that fit
Fred adds them to your inbox with why it picked each one, emails strong fits if you asked, and drafts messages to landlords that only send after you approve.
How it’s built
A tool-using agent behind one typed contract.
The loop
Fred is a Mastra agent on Claude Sonnet 5.5 at low effort, for speed. It works in a loop, calling tools and reading what they return, and it only writes its reply once the tools are done, so the places it talks about are ones it has actually looked up. The model is one setting, so the same agent runs on Gemini too, and 15 scripted conversations check what Fred did, not just what it said.
The hands
Every action is one of 25 typed tools with a Zod schema. The model never touches the database. It calls tools that read and write the same data the app shows, so whatever Fred changes, you see.
| Tools | What Fred can do | Count |
|---|---|---|
| Search | Read and change your search, search the listings, start the crawlers and check on them | 5 |
| Places | Add places to your inbox, look through it, open a place and update it | 4 |
| Research | Read a listing’s full page, search the web for the landlord and the building, look at the photos | 3 |
| Messages and tours | Draft, send or cancel a message to a landlord, request a tour, list and update tours | 6 |
| Alerts | Set up email alerts, verify the address and send a test | 3 |
| Memory | Keep notes about you, recall earlier chats and update your profile | 3 |
| Replies | Suggest answers you can tap | 1 |
The wiring, and why
Everything runs on Cloudflare, so there was no server to set up or look after, and the app and the API share one domain.
| Piece | What we used | Why |
|---|---|---|
| Web app | Next.js and Tailwind on a Cloudflare Worker, through OpenNext | The same host as the API, so a service binding serves both on one domain |
| Chat | Vercel AI SDK (useChat), streamed over server-sent events | Each tool call arrives as its own part, so the app can show Fred’s steps live |
| API | Hono on a Worker, with Zod schemas for every route | One contract generates the app’s types, so the two sides can’t drift apart |
| Agent | Mastra with Claude Sonnet 5.5 | A tool loop, memory and evals, with the model as one setting |
| Data | Cloudflare D1, R2 for photos, Workers AI for chat recall | Built into the same Worker, with nothing extra to run |
| Listings | Apify crawlers, started on demand | No listing site has an API, and on-demand runs search your areas, not all of NYC |
| Buildings | NYC Open Data, and NYPD complaint data for area safety | Free and public, with a record for every building |
| Research | Nimble for the web, Gemini for photos | Reading a full listing page or a landlord’s reviews when the card leaves it out |
| Maps | MapLibre with OpenFreeMap tiles | No key or account, and the tiles have a dark style |
| Errors | Sentry in the Worker and the app | Seeing what broke during a one-day build |
Two people and a few agents
We each worked with a few Claude Code agents. They coordinated on a shared message board, where they posted contract changes, bugs and questions for each other, and the API contract lived in one place (packages/api) that both sides built from. CI checked the Worker, the app and the contract on every push, so a change on one side that broke the other failed the checks.
The part I’m proudest of
The app shows Fred’s work as it happens.
My side was the web app, and the hard part was making an agent’s work readable while it streams in.
Live steps from the stream
Each tool call arrives as its own part. I turn it into plain words (“Searching Greenpoint”, then “Searched Greenpoint”), refresh the inbox when a tool that changes it finishes, and fold the steps into one line. Next’s compression was holding the whole stream until the end, so every step showed up at once; turning it off in Next, since Cloudflare compresses at the edge, fixed it.
A contract both sides build from
The app’s types are generated from the Zod schemas, and CI fails if they’re stale. When I wanted a dealbreaker level, my agent asked James’s agent on the board, the contract changed first, and my Profile change shipped on top of it.
Every place has a URL
The open listing, the view and the sort live in the URL, so a listing can be shared, a reload keeps your place and the back button closes the modal. The places on either side load in the background, so the arrows feel instant.
Maps and voice with no keys
MapLibre and OpenFreeMap need no account. Next doesn’t bundle MapLibre’s web worker, so a build step copies it in, and a browser without WebGL2 gets a note instead of a broken page. The mic records in the browser, and Whisper turns it into text right there.
Challenges
What broke during the day, and what we did.
The newest Next broke every page
Next 16.4 added a file the Cloudflare adapter doesn’t bundle, so every page returned a 500. I pinned 16.3.8 until the adapter catches up.
One site blocked every crawler
Apartments.com’s bot protection stopped every approach we tried, so it isn’t a source.
Search cards leave out the facts
Zillow’s results have no fees, pets or descriptions, so its crawler reads each listing page once and keeps it for 14 days, and Fred reads a page itself when it needs to know.
The crawlers ran the wrong search
We found they’d been running a placeholder search instead of the one in the app. Now Fred starts them on demand, for your own search.
By the numbers
- The tools Fred can call, in cloud/src/agent.
- 25
- Scripted conversations in evals/fred.ts that check what Fred did, not just what it said.
- 15
- StreetEasy, Zillow, RentHop, Zumper, Compass, Nooklyn and Craigslist, plus big landlords’ own sites.
- 7
- My commits to the Fred repo on October 11, 2026, not counting merges.
- 37
You can try all of it in the live demo, which signs you in as a fresh guest with an example search.
What I’d do next
- Read the full listing page on every site, not only Zillow, so fewer facts say Unknown.
- Run the evals in CI and block a deploy when one fails.
- Send alerts by text as well as email.
- Open it to renters beyond the two of us, with real accounts instead of two logins and a demo.