# AGENTS.md

Package: `@amplitude/ai` v0.14.0

## Install

```bash
pnpm add @amplitude/ai
```

## MCP Server Setup

The SDK ships an MCP server for AI coding agents. It provides project scanning,
file validation, instrumentation, test generation, and the complete API reference.

### Cursor

Add to `.cursor/mcp.json` in your project root:
```json
{
  "mcpServers": {
    "amplitude-ai": {
      "command": "npx",
      "args": ["amplitude-ai", "mcp"]
    }
  }
}
```
Then point the agent at the instrumentation guide: `node_modules/@amplitude/ai/amplitude-ai.md`

### Claude Code

```bash
claude mcp add amplitude-ai -- npx amplitude-ai mcp
```
Then point the agent at the instrumentation guide: `node_modules/@amplitude/ai/amplitude-ai.md`

### OpenAI Codex CLI

Add to `~/.codex/config.toml`:
```toml
[mcp_servers.amplitude-ai]
command = "npx"
args = ["amplitude-ai", "mcp"]
```
Codex auto-reads this `AGENTS.md` file for context.

### Generic (any MCP-compatible agent)

```json
{ "amplitude-ai": { "command": "npx", "args": ["amplitude-ai", "mcp"] } }
```

## Decision Tree

- **Default: use `ai.agent(...).session(...)` with provider wrappers** — gives you every event type, per-user analytics, session enrichment, quality scoring.
- Already have a provider client: use `wrap()` to instrument it.
- Multiple agents collaborating: use `session.runAs(childAgent, fn)` for automatic identity propagation.
- Need tool telemetry: use `tool()`.
- Need span/observability: use `observe()`.
- Cannot modify call sites at all: use `patch()` for aggregate-only monitoring (no per-user analytics).
- Need agent-assistant guidance: run MCP prompt `instrument_app`.

## MCP Surface

Tools:
- `get_event_schema`
- `get_integration_pattern`
- `validate_setup`
- `suggest_instrumentation`
- `validate_file`
- `search_docs`
- `scan_project`
- `generate_verify_test`
- `instrument_file`

Resources:
- `amplitude-ai://event-schema`
- `amplitude-ai://integration-patterns`
- `amplitude-ai://instrument-guide`

Prompt:
- `instrument_app` — Short prompt; fetch `amplitude-ai://instrument-guide` (full amplitude-ai.md) before editing

## Canonical Patterns

- zero-code patching — `patch({ amplitudeAI: ai })`
- wrap-openai — `wrap(existingClient, ai)`
- bound-agent-session — `ai.agent('id').session({ userId }).run(fn)`
- multi-agent-runas — `s.runAs(childAgent, fn)`
- tool-decorator — `tool(fn, { name: 'tool_name' })`
- observe-spans — `observe(fn, { name: 'span-name' })`
- express-middleware — `createAmplitudeAIMiddleware({ amplitudeAI: ai, userIdResolver })`

## Gotchas

- `tool()` in Node requires explicit JSON schema for robust agent input shaping.
- Keep `AMPLITUDE_AI_API_KEY` available in runtime env for telemetry delivery.
- Use `MockAmplitudeAI` for deterministic tests.
- Call `ai.flush()` before returning from serverless handlers (Next.js, Lambda, Vercel).
- `session.run()` relies on `AsyncLocalStorage`; not available in Edge Runtime. **Cloudflare Workers:** do NOT import `AmplitudeAI`, `AIConfig`, or any runtime export from `@amplitude/ai` in Worker bundles — they pull in `node:async_hooks` / `node:module` which break Workers Builds. Use the SDK-free `FetchAmplitudeClient` pattern with direct `[Agent]` event construction (see "Edge Runtime / Cloudflare Workers" in amplitude-ai.md). Only `import type { ... } from '@amplitude/ai/types'` is safe.
- **User message text:** `trackUserMessage(content, opts?)` — put human-readable intent in `content`; large JSON / RAG / pipeline state in `opts.context` (preferred — maps to the registered `[Agent] Context` property, always queryable in charts), not as the only `content`, or session labels and segmentation show raw JSON. Avoid `opts.eventProperties` for custom dimensions on `[Agent]` events — unregistered properties may be silently dropped by schema enforcement.
- **Turns vs spans:** `[Agent] User Message` + `[Agent] AI Response` drive turn-level analytics; `observe()` / `trackSpan()` complement them — do not use spans alone for conversation metrics.
- **Gateways / custom `baseURL`:** use `trackAiMessage` with `usage` fields, the **real** routed model id, and `totalCostUsd` when genai-prices cannot resolve the model string (install `@pydantic/genai-prices` for automatic cost when supported).

## CLI

- `amplitude-ai` — Print instrumentation prompt for AI coding agents
- `amplitude-ai --print-guide` — Print the full amplitude-ai.md guide to stdout
- `amplitude-ai mcp` — Start the MCP server for AI coding agents
- `amplitude-ai doctor [--json]` — Validate environment, deps, and event pipeline
- `amplitude-ai status [--json]` — Show SDK version, installed providers, and env config

## Testing

- Run package tests: `pnpm --filter @amplitude/ai test`
- Run typecheck: `pnpm --filter @amplitude/ai test:typescript`
- Run docs freshness: `node scripts/generate-agent-docs.mjs --check`

## Examples

- `examples/zero-code.ts`
- `examples/wrap-openai.ts`
- `examples/multi-agent.ts`
- `examples/framework-integration.ts`
- `examples/real-openai.ts` (requires OPENAI_API_KEY)

## Instrumentation Guide

- `amplitude-ai.md` — **Start here.** Complete 4-phase instrumentation workflow + API reference. Paste into any coding agent.
- `llms-full.txt` — Extended API reference with MCP tools and patterns

## Event Schema (names)

- `[Agent] AI Response`
- `[Agent] Embedding`
- `[Agent] Evaluator Result`
- `[Agent] Score`
- `[Agent] Session End`
- `[Agent] Session Enrichment`
- `[Agent] Session Record`
- `[Agent] Span`
- `[Agent] Tool Call`
- `[Agent] Topic Classification`
- `[Agent] User Message`
