The urlContext tool

Some providers ship retrieval as a first class tool. Gemini has google.tools.urlContext, which fetches a URL, extracts the content, and feeds it to the model inside the same call. No embedder, no vector store, no chunking code.

urlContext inside streamText

The provider fetches the URL and grounds the answer inside a single streamed call.

src/app/api/rag/route.ts
typescript
import { type NextRequest } from 'next/server';
import { google } from '@ai-sdk/google';
import { streamText, Tool } from 'ai';

export const maxDuration = 60;

export async function POST(req: NextRequest) {
  const { prompt: userInput } = await req.json();
  const remoteUrl = req.nextUrl.searchParams.get('url') || '';

  const prompt = `Given this url: ${'$'}{remoteUrl} and this user question: ${'$'}{userInput}, answer based on the URL content. If you cannot find the information, say so. Do not make up an answer.`;

  const result = streamText({
    model: google('gemini-3.1-flash-lite-preview'),
    prompt,
    tools: {
      url_context: google.tools.urlContext({}) as Tool<unknown, unknown>,
    },
  });

  return result.toUIMessageStreamResponse();
}

Notice the shape is nearly identical to the chat route. The only new thing is the tools object, which wires the provider's native urlContext into the same streamText call.

There are none in this route. Gemini handles the retrieval internally when you attach the urlContext tool. You pay a bit of extra tool-use overhead but skip the entire embed and vector search pipeline. That is the superpower of native tools when your data fits the tool.

Quiz: Quiz

Loading practice…