# Build AI applications with Deno

## Minimal security boundary

An AI service commonly listens, reads one provider key, and contacts one API:

```bash
deno run \
  --allow-net=0.0.0.0:8000,api.example.com:443 \
  --allow-env=MODEL_API_KEY \
  --no-prompt main.ts
```

Model names, API paths, and SDK methods change quickly. Query the provider's current official docs before implementation; never guess a default model in shared code.

## Streaming proxy

```ts
Deno.serve(async (request) => {
  const upstream = await fetch("https://api.example.com/v1/responses", {
    method: "POST",
    headers: {
      authorization: `Bearer ${Deno.env.get("MODEL_API_KEY")}`,
      "content-type": "application/json",
    },
    body: await request.text(),
    signal: request.signal,
  });

  return new Response(upstream.body, {
    status: upstream.status,
    headers: { "content-type": upstream.headers.get("content-type") ?? "text/event-stream" },
  });
});
```

Production code must also limit body size, validate schema, set a timeout, map errors, and cancel upstream work when the client disconnects.

## Tool calls

- Map tool names to fixed functions; never interpolate model text into a shell.
- Validate parameters with a schema and show impact before authorization.
- Restrict file tools to a workspace and network tools to a host allowlist.
- Separate reads from writes; require humans for deletion, publishing, payment, and production changes.
- Log tool name, duration, result class, and request ID, but not secrets or full sensitive inputs.

## RAG and evaluation

Keep source URL, version, update time, and access labels on chunks. Retrieved context is not authorization. Maintain a fixed evaluation set for refusal, prompt injection, timeouts, provider 429/5xx responses, and data leakage.

Official entry points: [Deno AI](https://docs.deno.com/ai/) and the [Deno LLM tutorial](https://docs.deno.com/examples/llm_tutorial/).
