Skip to content

Repository files navigation

TeaQL Agent Data Tools for Vercel AI SDK

Generated, typed, auditable business tools for AI SDK agents—without exposing raw SQL.

Don't give your AI agent unrestricted SQL. Give it a typed business language.

@teaql/ai-sdk converts an explicit allowlist of TeaQL business capabilities into native Vercel AI SDK tools. The model receives business operations and their schemas. A trusted TeaQL UserContext, database resources, authorization state, and internal errors remain on the server.

Why

Raw SQL agent TeaQL agent tools
Model guesses tables and joins Model selects named business capabilities
Broad database access Explicit capability allowlist
Untyped rows Schema-validated input and output
Authorization depends on prompts Trusted server-side context
Mutations are difficult to govern AI SDK approval plus TeaQL audit semantics
Database errors may leak Safe public errors and observable internal failures
Database-specific behavior TeaQL domain semantics can span seven runtimes

This package does not replace the AI SDK agent loop, model providers, UI, or streaming. It supplies the governed business-data layer beneath those features.

Install

npm install @teaql/ai-sdk @teaql/teaql ai zod

Node.js 22 or newer and AI SDK 7 are required by the initial release.

Define business capabilities

Capabilities are an explicit allowlist. The adapter intentionally does not expose every entity and CRUD operation automatically.

import { defineTeaQLCapability } from '@teaql/ai-sdk';
import { z } from 'zod';

const searchSchools = defineTeaQLCapability({
  name: 'searchSchools',
  description: 'Find schools by governed business criteria.',
  inputSchema: z.object({
    schoolType: z.enum(['PRIMARY', 'SECONDARY']),
    name: z.string().optional(),
  }),
  risk: 'read',
  execute: async ({ context, input }) =>
    Q.schools()
      .withSchoolType(input.schoolType)
      .withNameContaining(input.name)
      .comment('AI SDK tool: searchSchools')
      .purpose('Search schools requested by the authenticated user')
      .executeForList(context),
});

The exact generated Q API follows the selected TeaQL model and generator version; capability definitions are ordinary typed application code and compile against it.

Create native AI SDK tools

import { UserContext } from '@teaql/teaql';
import { ToolLoopAgent } from 'ai';
import { createTeaQLTools } from '@teaql/ai-sdk';

const context = new UserContext()
  .insertResource('dataService', dataService)
  .insertResource('authorization', authorization);

const agent = new ToolLoopAgent({
  model: 'openai/gpt-5.4',
  instructions: 'Use only the provided business tools. Never invent SQL.',
  tools: createTeaQLTools({
    context,
    capabilities: [searchSchools, updateSchoolContactPhone],
  }),
});

Create context on the server for each request or session. Never accept it from model output or a browser payload.

Govern writes

const updateSchoolContactPhone = defineTeaQLCapability({
  name: 'updateSchoolContactPhone',
  description: 'Update a school phone after explicit user approval.',
  inputSchema: z.object({
    schoolId: z.number().int().positive(),
    contactPhone: z.string(),
    auditReason: z.string().min(8),
  }),
  risk: 'write',
  needsApproval: true,
  execute: async ({ context, input }) => {
    const school = await Q.schools()
      .withId(input.schoolId)
      .comment('Load school for approved contact update')
      .purpose(input.auditReason)
      .executeForOne(context);

    return school
      .updateContactPhone(input.contactPhone)
      .auditAs(input.auditReason)
      .save(context);
  },
});

AI SDK approval controls whether the agent may execute the tool. TeaQL audit and runtime authorization still apply when execution begins. Approval is not a replacement for runtime security.

Observe execution without leaking internals

const tools = createTeaQLTools({
  context,
  capabilities,
  onEvent: event => telemetry.record(event),
  mapError: (_error, capability) =>
    `${capability.name} could not be completed. Review the request or contact support.`,
});

Lifecycle events contain capability name, risk, tool-call ID, timing, and the internal error on the server. Inputs are excluded by default because they may contain sensitive business data. The default model-visible error never includes the original database error.

Run the local demonstration

The repository includes a deterministic, no-API-key school-management demonstration. It uses an in-memory SQLite resource inside the trusted UserContext to show the security boundary, approval metadata, optimistic version change, audit record, and model-visible tools.

npm install
npm run example

The SQLite repository is deliberately small and handwritten so the example is self-contained. A generated TeaQL project replaces that repository implementation with its generated Q, entity, Save, and Runtime Module APIs; the AI SDK adapter remains unchanged.

See examples/school-agent.

Security model

  • Capabilities are deny-by-absence: only definitions passed to createTeaQLTools exist.
  • allow can narrow the registered capabilities for a particular user or agent.
  • context is captured by the server-side execute closure and is not part of inputSchema.
  • Tool risk is metadata for policy and telemetry; applications must still enforce authorization in the runtime.
  • Writes can request AI SDK approval, but must also use TeaQL audit and validation.
  • Internal failures are available to server telemetry and hidden from the model by default.
  • Capability names and duplicates are validated during startup.

Current scope

The initial release is a runtime adapter for explicit TypeScript capability definitions. Planned generator work will produce capability definitions, schemas, agent guidance, and conformance fixtures from a TeaQL model. MCP adapters can expose the same capability manifest to Java, Rust, TypeScript, Swift, Python, .NET, and Go runtimes.

Related projects

License

Apache-2.0

About

Generated, typed, auditable business tools for Vercel AI SDK agents

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages