It's a great day to build something.

A Blank Slate Labs project

Resources/Workshop guide

Beyond Vibe Coding: Build a Research Agent

A follow-along guide from the Beyond Vibe Coding: Agents build night. Scaffold an AI agent, wire it to a live API, give it a research methodology, then go connect a data source of your own.

Workshop guideBeginner9 min read

A follow-along guide from tonight's build night. Event page: luma.com/bg6rgm4r.

In about 30 minutes we'll scaffold an AI agent, wire it to a real external data source, give it a research methodology, and chat with it in a web app running on your own machine.

What we're building: a clinical-trial research analyst. A web-chat agent connected live to the ClinicalTrials.gov API (595,000+ studies) that can survey a disease area, trace a drug's development, and cross-reference trial records against news, filings, and press coverage.

Why this one: the trials API is a stand-in for the thing you actually care about. Once you've seen an agent reach into a live API, you'll know how to point it at your company's data. That's the assignment at the end.

The stack: eve (the agent framework) · Next.js · Claude Code · Vercel AI Gateway · ClinicalTrials.gov.


What you'll need

Get these done before the session so you're building instead of setting up accounts.

Accounts

  • A Vercel account, for the AI Gateway (this is how your agent reaches a language model).
  • A few dollars of AI Gateway credit. $5 to $10 is plenty for tonight. $5 is probably enough.

Software

  • Node.js + npm installed.
  • VS Code with the Claude Code extension installed and signed in.

Set up in the first two minutes

  1. Create an empty folder and open it in VS Code (File → Open Folder).
  2. If VS Code shows Restricted Mode, click Trust. Without it, VS Code can't run commands and nothing tonight will work.
  3. Open the Claude Code panel and the integrated terminal.
Housekeeping

You'll create an API key tonight. Set an expiry and a small spend quota when you make it, and delete it when you're done. This is a demo, not something you're shipping.


What an agent actually is

Two minutes of grounding before we build. Every agent, no matter how complex, is three buckets:

Triggerwhat starts it
  • chat message
  • form submit
  • schedule
  • webhook
Workwhat it's made of
  • instructions
  • skills (know-how)
  • connections (APIs)
  • tools (your code)
Outputwhat you get
  • a reply
  • a report
  • an email
  • a DB write

Tonight the trigger is a chat message and the output is a written analysis, because chat is the fastest thing to get working in half an hour. The more useful version is the one where you're not in the loop: you hand it a question and walk away, and it emails you the report.

In eve, each building block is a file in the agent/ folder:

BlockIn plain termsThe file
ModelWhich AI it thinks withagent/agent.ts
InstructionsWho it is, how it behavesagent/instructions.md
SkillsHow you do this work, written downagent/skills/…
ConnectionsA service you plug inagent/connections/…
ToolsSomething you build by hand(Step 8)
ChannelsHow people reach itagent/channels/eve.ts

Two of these do the heavy lifting tonight:

  • A connection is plugging in a service that already exists. Most serious services publish a machine-readable menu of what they can do (an OpenAPI spec, or an MCP server). You point eve at that menu and it wires up every operation automatically. One prompt, and the agent can search 595,000 studies.
  • A skill is where your expertise lives. It's a plain Markdown file where you write down how you actually do the work: what you look at first, your order of operations, the questions you always ask. The scaffold is free and the same for everyone. The skill is what makes the agent yours.

The build

Run the commands yourself, paste the prompts where noted. Every step tells you what you should see.

1. Scaffold the project. In your empty folder's terminal, run this and answer y when npx offers to install eve:

terminal
npx eve@latest init . --channel-web-nextjs

Two details that are easy to get wrong: the . installs into the folder you're already in (the docs' init my-agent makes a subfolder instead), and --channel-web-nextjs is two dashes (one throws unknown option). The web channel is what gives you a chat UI immediately.

2. Connect a model via Vercel AI Gateway. When init finishes, choose Start eve dev. It drops you into a chat REPL and tells you it needs a model. Type:

eve repl
/model

Choose Bring your own key. Then in a browser go to Vercel → AI Gateway → API Keys, Create key, name it something like research-agent-test, copy it, paste it back at the prompt, and press Enter. eve writes it to .env.local for you. Run /model again to confirm:

eve repl
/model
└ Connected to AI Gateway via AI_GATEWAY_API_KEY in .env.local.

:2000  anthropic/claude-sonnet-5 via ai-gateway(api-key)

Say hey, how's it going? to prove the model responds, then type /exit.

Swapping the model (optional)

The model is one line in agent/agent.ts. Change anthropic/claude-sonnet-5 to any model the gateway offers and eve hot-reloads on save. For tonight's multi-step research, a stronger model like anthropic/claude-opus-4.8 is a defensible one-line upgrade.

3. Start the real dev server. The REPL was just for setup. Now run the front end and the agent together:

terminal
npm run dev

Open http://localhost:3000 and say heyyy. Your agent replies. Right now it's a chat with a language model plus built-in web search, and nothing else. No knowledge of your data, no methodology. That's the baseline we're about to improve.

4. Add a live data connection. Open Claude Code in the side panel and send this. It's the longest wait tonight (around 5 to 6 minutes), and the most interesting part of the build to watch:

prompt
I want to set up a new connection connected to clinicaltrials.gov, and I'll provide the API link below. I want you to add this as a new connection in the agent that we have set up here.

https://clinicaltrials.gov/data-api/api

Use the OpenAPI 3.0 setup for connections.

While it works, watch it read eve's own bundled docs, fetch the OpenAPI spec, and then test against the live API before writing anything. That testing step is the whole point: on the dry run it caught that Phases and Conditions are invalid field names (the singular Phase and Condition are correct), and one bad field name fails the entire request. It verifies instead of guessing. You'll know it landed when the terminal hot-reloads:

terminal
[eve:dev] change detected (add agent/connections/clinicaltrials.ts), rebuilding...
[eve:dev] authored artifacts updated.

5. Test the connection. Refresh http://localhost:3000 for a clean session and ask:

prompt
Can you tell me the clinical trials that ended in 2026 for Alzheimer's disease.

Watch the tool chain render in the chat. It tells the whole story: the agent discovers your connection, then calls the operation you defined.

chat
🔧 connection_search              ✅ Completed
🔧 clinicaltrials__listStudies    ✅ Completed

You'll get a few hundred studies back in a table. (Your numbers will differ, it's a live registry.) Notice what's missing though: the agent is a competent API client and nothing more. It has no point of view on how to research a disease area. That gap is the next step.

6. Turn it into a research analyst. Back in Claude Code (second long wait, around 5 minutes):

prompt
Alright turn this agent into a research analyst for understanding the development of treatments for diseases. It should have a skill that specifically searches clinical trials and finds relevant online information about them outside of the actual trial info.

That last clause is the trick. "Outside of the actual trial info" is what turns a database front end into a research agent: it has to connect registry records to the world around them (published literature, regulatory filings, press coverage). The skill it writes doesn't just gather, it knows what a discrepancy looks like: a completed trial that never published, a "business reasons" stop while the press reports a safety signal, endpoints that keep slipping. That's the part worth stealing for your own domain.

7. Test the research agent. Refresh the chat, say hi, and it now introduces itself with an actual point of view. Then ask it something real:

prompt
What is the latest from Eli Lilly on their development of drugs for Alzheimer's?

The tool chain is three deep now, with a new first step: load_skill pulls in your methodology before it does anything else.

chat
🔧 load_skill                     ✅ Completed
🔧 connection_search              ✅ Completed
🔧 clinicaltrials__listStudies    ✅ Completed

The output should be sourced, dated, and graded by evidence quality, separating "a regulator confirmed it" from "the company says so." That hedging is the skill doing its job, not the model.

8. Give it a tool that takes action (optional). Reading data is half the picture. To close the loop, the agent needs to do something:

prompt
Create a tool to connect Resend to send emails.

You'll need a Resend account and a RESEND_API_KEY in .env.local before it can actually send, so this is a fine one to finish at home. Why a tool here and not a connection? Resend publishes a spec, so you could wire it as a connection. You write it by hand when you want control, like rendering a Markdown report into styled HTML before it goes out.

Gate anything that acts

A tool that sends real email should pause for human approval before it fires. Same for a connection that files issues or moves money. eve lets you set any connection or tool to check with a human first: every time, just the first time, or never.


Now build your own

Next, you build one on your own. Here's the structure for that.

First, a 30-second check

Before you commit to a source, spend half a minute and you'll know what you're in for.

  1. Does it publish an OpenAPI spec? Search <service> openapi spec or <service> swagger.json. If yes, your connection is close to one prompt.
  2. Does it have an MCP server? Search <service> MCP server. If yes, use defineMcpClientConnection instead, even less work.
  3. Neither? Point Claude Code at the API docs and ask it to build the spec. Slower, deserves more verification, but it's exactly what happened tonight.
  4. What does auth look like? This is what actually decides whether it takes ten minutes or an evening:
Auth styleDifficulty
None, fully publicEasiest
API key in a headerEasy, one env var
OAuth, one account (yours)Moderate, one-time setup
OAuth, per end userHardest, real identity plumbing
Start easy, even if the ambitious one is what you want

Getting one connection working end to end teaches you more than half-finishing an ambitious one. Pick something from Tier 1 first, then go do the hard one.

Tier 1 — public, no key needed

Nothing to sign up for, so you can go from idea to working agent in one sitting.

SourceWhat's in itA question to ask it
SEC EDGAREvery public company filing (10-Ks, 8-Ks, insider trades)"What has [company] said about AI risk across its last three 10-Ks, and what changed?"
GitHub REST APIRepos, issues, PRs, releases. Official OpenAPI description"What's the release cadence and open-issue trend for [repo] this year?"
openFDADrug adverse events, recalls, device data, labels"What adverse events are reported for [drug], and how has the pattern shifted since approval?"
Federal RegisterProposed and final US regulations, daily"What rules affecting [industry] were proposed in the last 90 days?"
USAspending.govFederal contracts and grants, who got paid what"Which vendors won the most [category] contracts last year?"
PubMed / NCBIBiomedical literature, searchable by almost anything"What's been published on [mechanism] in the last 18 months?"
Open-MeteoHistorical and forecast weather, worldwide"How unusual was last month's temperature in [city] vs the 10-year baseline?"
Wikipedia / WikidataStructured facts about basically everything"Build me a timeline of [topic] with dates and key figures."

Tier 2 — free API key, no OAuth flow

One signup, one key, one environment variable. No consent screens, no redirects. You generate a token in the service's settings and paste it in. This is where it starts being your data.

SourceWhat's in itA question to ask it
Stripe (test mode)Charges, customers, subscriptions. Secret key, plus it publishes an OpenAPI spec"What does churn look like by plan over the last six months?"
AirtableWhatever your team tracks in a base. Personal access token"Summarize this quarter's pipeline and flag records missing an owner."
NotionYour workspace docs and databases. Internal integration token"What decisions did we record last month with no follow-up?"
LinearIssues, projects, cycles. Personal API key, and it has an MCP server"What's slipping this cycle and which issues have gone quiet?"
AttioYour CRM records. API key"Which accounts went cold in the last 60 days, and what was the last touch?"
News API / GNewsHeadlines and article search. API key"What's the coverage arc on [company] this quarter?"
Alpha Vantage / FMPMarket data, fundamentals, earnings. Key in the query string"How have [ticker]'s margins moved against its stated guidance?"
ResendSending email, the Step 8 tool. API key(the delivery half of any of the above)
Use test mode and read-only keys while you're learning

Stripe has a test mode, use it. Most SaaS APIs let you scope a key to read-only. Do that first, and widen it deliberately once you trust what you built.

Tier 3 — OAuth, or your own infrastructure

Real setup, worth it when the payoff is real. This is the tier for "your own data" that a plain key won't reach:

  • Google Workspace (Gmail, Calendar, Drive, Sheets): OAuth or a service account. Your own private sheet needs one of those. Only a public sheet is readable with a plain key.
  • HubSpot / Salesforce: CRM behind an OAuth flow. (HubSpot private-app tokens are the lighter path if you own the account. Attio in Tier 2 is the quicker CRM to start with.)
  • Your company's internal API: the one that actually creates value. Everything above is practice for it.
  • Your own Postgres / Supabase: usually better as a tool than a connection, so you control the queries.

For your own database, resist wiring the agent to raw SQL. Write a tool that exposes the handful of queries you want, and gate anything that writes.

The best agents read two sources, not one

Tonight's most interesting behavior wasn't fetching trials, it was spotting the gap between two sources. You can't get that from one. Pairs worth stealing:

PairThe gap it finds
SEC EDGAR + News APIWhat the company filed vs what it said publicly
PubMed + ClinicalTrials.govTrials that finished and never published
GitHub + your issue trackerWhat engineering says is done vs what shipped
CRM + email/calendarAccounts marked "active" with no real contact in 60 days
Your data + ResendAny of the above, delivered on a schedule instead of asked for

That last row is the real destination: the trigger → work → output loop, with you out of the middle.

The prompt to start with

Generalized from the one you used tonight:

prompt
I want to set up a new connection to [SERVICE], and I'll provide the API link below. I want you to add this as a new connection in the agent that we have set up here.

[LINK TO THE API DOCS OR SPEC]

Use the OpenAPI 3.0 setup for connections.

Then give it a methodology, the part that makes it yours:

prompt
Turn this agent into a [ROLE] for [PURPOSE]. It should have a skill that specifically [WHAT IT SEARCHES] and [WHAT IT CROSS-REFERENCES].

Two lines worth adding to either prompt: "Verify the query patterns against the live API rather than assuming them" (this is what caught the invalid field names tonight), and "Don't add an approval gate for read-only operations, but do add one for anything that writes, sends, or spends."

Things that will trip you up

  • Rate limits. Long research runs hit them. Add a token if the service offers one.
  • Big responses. Some APIs return enormous records. Tell your agent to narrow the fields it requests, or it'll drown.
  • Pagination. Most APIs return page one and a token for the next. Make sure the spec captures that, or you'll silently get 10% of your data.
  • Invalid field names fail the whole request, not just the bad field. This is why verification matters.
  • Auth that expires. If your agent mysteriously stops finding anything, check the credential first.
  • Terms of service. Some APIs restrict automated access. Worth thirty seconds of reading.
If you're not sure what to pick

Pick SEC EDGAR. No signup, genuinely rich data, and "what changed in this company's story over three years" is a question people actually pay for. It's the closest analog to what you built tonight. Then connect something only your company has. That's the one that matters.


Quick reference

ActionCommand
Scaffold agent + web chat into current foldernpx eve@latest init . --channel-web-nextjs
Terminal chat REPL (setup / quick checks)npx eve dev
Set or check the model inside the REPL/model
Leave the REPL/exit
Run agent + web app togethernpm run dev
Open the chat UIhttp://localhost:3000

Key files

FileWhat it is
agent/agent.tsModel selection
agent/instructions.mdSystem prompt, the agent's identity and rules
agent/skills/…The research methodology, the valuable part
agent/connections/…Connection to an API
.env.localAI_GATEWAY_API_KEY and any tool keys you add

Tool names you'll see in the chat

ToolWhat it means
load_skillYour skill file was pulled in
connection_searchThe agent discovered which operations exist
clinicaltrials__listStudies<connection>__<operationId>, your operation being called

Have fun building, and bring the weird one to demos. Jeff.