{"_id":"@agentmail/convex","_rev":"5-b1b32d0201808b3f3aa40f1bda98b457","name":"@agentmail/convex","dist-tags":{"latest":"0.1.0"},"versions":{"0.0.1":{"name":"@agentmail/convex","version":"0.0.1","keywords":["convex","component","agentmail","email","ai-agents"],"license":"Apache-2.0","_id":"@agentmail/convex@0.0.1","maintainers":[{"name":"tanishq-atm","email":"tanishq@agentmail.cc"},{"name":"josephmaregn","email":"joseph@agentmail.cc"},{"name":"harry0915","email":"harry@agentmail.cc"},{"name":"agentmail-admin","email":"admin+npm@agentmail.cc"}],"homepage":"https://github.com/agentmail-to/convex#readme","bugs":{"url":"https://github.com/agentmail-to/convex/issues"},"dist":{"shasum":"fcecfaff90a1b38e4e782d9f0a0e41a08dd37f6e","tarball":"https://registry.npmjs.org/@agentmail/convex/-/convex-0.0.1.tgz","fileCount":69,"integrity":"sha512-PSkjJZKTBVhDLQt+uiGrDQom3Bg6vzZmn4qAX2wp3WmOKkizyOcq50CgcXiLmmNQXhxd9Y3370qidlUOuYsqYg==","signatures":[{"sig":"MEYCIQCM8pNHvlU3qzsCravR0Oi8JqUUim13VdWPLRgeKkaH6AIhAOM7HK2sGc2Sk7RRlEeg2GY6kREJuddUMJ6qNNXecsnr","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":197966},"type":"module","types":"./dist/client/index.d.ts","module":"./dist/client/index.js","exports":{".":{"types":"./dist/client/index.d.ts","default":"./dist/client/index.js"},"./test":"./src/test.ts","./package.json":"./package.json","./convex.config":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./convex.config.js":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./_generated/component.js":{"types":"./dist/component/_generated/component.d.ts"}},"gitHead":"5fd151a9bd074afcd42f15731d613ca0243fc8d8","scripts":{"dev":"convex dev --start 'npm run dev:build'","lint":"eslint .","test":"vitest run","build":"tsc --project ./tsconfig.build.json && node ./scripts/copy-generated-dts.mjs","clean":"rm -rf dist *.tsbuildinfo","smoke":"tsx scripts/smoke.ts","predev":"convex init && npm run build:codegen","release":"npm version patch && npm publish && git push --follow-tags","dev:build":"chokidar 'tsconfig*.json' 'src/**/*.ts' -i '**/*.test.ts' -c 'npm run build:codegen' --initial","typecheck":"tsc --noEmit && tsc -p example/convex","smoke:send":"tsx scripts/smoke.ts --send","test:watch":"vitest --clearScreen false","build:clean":"rm -rf dist *.tsbuildinfo && npm run build:codegen","dev:frontend":"cd example && vite --clearScreen false","test:codegen":"vitest run src/**/*.codegen.test.ts","build:codegen":"npx convex codegen --component-dir ./src/component && npm run build","prepublishOnly":"npm whoami"},"_npmUser":{"name":"josephmaregn","email":"joseph@agentmail.cc"},"repository":{"url":"git+https://github.com/agentmail-to/convex.git","type":"git"},"_npmVersion":"11.6.2","description":"A Convex component for AgentMail.","directories":{},"_nodeVersion":"23.11.0","dependencies":{"svix":"^1.70.0","@convex-dev/workpool":"^0.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","convex":"^1.35.0","vitest":"^4.0.0","typescript":"~5.9.0","@types/node":"^24.0.0","convex-test":"^0.0.51","chokidar-cli":"^3.0.0","convex-helpers":"^0.1.106","@edge-runtime/vm":"^5.0.0"},"peerDependencies":{"convex":"^1.24.8","convex-helpers":"^0.1.106"},"_npmOperationalInternal":{"tmp":"tmp/convex_0.0.1_1778466411812_0.30550699422513006","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"@agentmail/convex","version":"0.1.0","keywords":["convex","component","agentmail","email","ai-agents"],"license":"Apache-2.0","_id":"@agentmail/convex@0.1.0","maintainers":[{"name":"tanishq-atm","email":"tanishq@agentmail.cc"},{"name":"josephmaregn","email":"joseph@agentmail.cc"},{"name":"harry0915","email":"harry@agentmail.cc"},{"name":"agentmail-admin","email":"admin+npm@agentmail.cc"}],"homepage":"https://github.com/agentmail-to/convex#readme","bugs":{"url":"https://github.com/agentmail-to/convex/issues"},"dist":{"shasum":"3b83eeea945b3137523082a8044dfe010559d12a","tarball":"https://registry.npmjs.org/@agentmail/convex/-/convex-0.1.0.tgz","fileCount":69,"integrity":"sha512-pqfIBX/XObWqC9M3sqh0Jy8KGOtQzpC0plZok3mJye0ZmEOuo5BZbG6diihjeIzBOEQblnagO9C+IX6+uQNfvg==","signatures":[{"sig":"MEUCIEFToh4v26iUvLAmV8QCBfsL9bbFV383qWOYZuNPU0enAiEA6V9w4WzuY4lrgnEXXUb9ynd36qo0iml8N4d0uq88Qp8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":199455},"type":"module","types":"./dist/client/index.d.ts","module":"./dist/client/index.js","exports":{".":{"types":"./dist/client/index.d.ts","default":"./dist/client/index.js"},"./test":"./src/test.ts","./package.json":"./package.json","./convex.config":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./convex.config.js":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./_generated/component.js":{"types":"./dist/component/_generated/component.d.ts"}},"gitHead":"40644fc9b9f8479bb2e3502aa9b1200091a60539","scripts":{"dev":"convex dev --start 'npm run dev:build'","lint":"eslint .","test":"vitest run","build":"tsc --project ./tsconfig.build.json && node ./scripts/copy-generated-dts.mjs","clean":"rm -rf dist *.tsbuildinfo","smoke":"tsx scripts/smoke.ts","predev":"convex init && npm run build:codegen","release":"npm version patch && npm publish && git push --follow-tags","dev:build":"chokidar 'tsconfig*.json' 'src/**/*.ts' -i '**/*.test.ts' -c 'npm run build:codegen' --initial","typecheck":"tsc --noEmit && tsc -p example/convex","smoke:send":"tsx scripts/smoke.ts --send","test:watch":"vitest --clearScreen false","build:clean":"rm -rf dist *.tsbuildinfo && npm run build:codegen","dev:frontend":"cd example && vite --clearScreen false","test:codegen":"vitest run src/**/*.codegen.test.ts","build:codegen":"npx convex codegen --component-dir ./src/component && npm run build","prepublishOnly":"npm whoami"},"_npmUser":{"name":"josephmaregn","email":"joseph@agentmail.cc"},"repository":{"url":"git+https://github.com/agentmail-to/convex.git","type":"git"},"_npmVersion":"11.6.2","description":"A Convex component for AgentMail.","directories":{},"_nodeVersion":"23.11.0","dependencies":{"svix":"^1.70.0","@convex-dev/workpool":"^0.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","convex":"^1.35.0","vitest":"^4.0.0","typescript":"~5.9.0","@types/node":"^24.0.0","convex-test":"^0.0.51","chokidar-cli":"^3.0.0","convex-helpers":"^0.1.106","@edge-runtime/vm":"^5.0.0"},"peerDependencies":{"convex":"^1.24.8","convex-helpers":"^0.1.106"},"_npmOperationalInternal":{"tmp":"tmp/convex_0.1.0_1778475710144_0.9808066140876557","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2026-05-11T02:26:51.717Z","modified":"2026-08-21T21:42:29.283Z","0.0.1":"2026-05-11T02:26:51.950Z","0.1.0":"2026-05-11T05:01:50.303Z"},"bugs":{"url":"https://github.com/agentmail-to/convex/issues"},"license":"Apache-2.0","homepage":"https://github.com/agentmail-to/convex#readme","keywords":["convex","component","agentmail","email","ai-agents"],"repository":{"url":"git+https://github.com/agentmail-to/convex.git","type":"git"},"description":"A Convex component for AgentMail.","maintainers":[{"email":"tanishq@agentmail.cc","name":"tanishq-atm"},{"email":"sanjith@agentmail.cc","name":"sanjith_sambath"},{"email":"krishav@agentmail.cc","name":"krishavg"},{"email":"joseph@agentmail.cc","name":"josephmaregn"},{"email":"harry@agentmail.cc","name":"harry0915"},{"email":"shabs@agentmail.cc","name":"shabs_agentmail"},{"email":"admin+npm@agentmail.cc","name":"agentmail-admin"}],"readme":"# @agentmail/convex\n\nA [Convex](https://convex.dev) component for [AgentMail](https://agentmail.to).\n\nAgentMail is a **stateful email inbox for AI agents** — every message your agent sends or receives is persisted as part of a thread, with labels, full bodies, and history. This component brings that inbox state into your Convex database so your agents and your UI both see it live.\n\nIt's the difference between \"I built on Resend and rebuilt my own thread/label/draft store on top\" and \"the inbox already exists; I just `useQuery` it.\"\n\n## What you get\n\n- **Threads as first-class state.** Every inbound message persists with its `thread_id`, `in_reply_to`, and `references` in your Convex DB. Subscribe to `listInboundMessages({ threadId })` and watch the thread update reactively.\n- **Full message bodies.** Text, HTML, extracted text/HTML, attachments metadata — not just headers or previews.\n- **Labels.** Tag conversations on send (`labels: [\"urgent\", \"support-agent\"]`) and query threads by label via `listThreads({ labels })`.\n- **Durable sending.** `sendMessage`/`replyToMessage`/`forwardMessage` enqueue from a mutation; a workpool action talks to AgentMail with bounded retries. Lifecycle (`pending → sent → delivered/bounced/...`) is itself a reactive query.\n- **Idempotent webhook ingest.** Svix-verified, deduped by `event_id`, callbacks dispatched via a separate workpool so a slow user handler can't block inbound mail.\n- **Reactive UI.** `useQuery` over inbox state — new mail, status changes, thread updates — without polling.\n- **Isolated component.** Its own tables (`inboxes`, `inboundMessages`, `outboundMessages`, `events`), sandboxed from your app's data.\n\n## Install\n\n```bash\nnpm install @agentmail/convex\n```\n\nWire it into your Convex app:\n\n```ts\n// convex/convex.config.ts\nimport { defineApp } from \"convex/server\";\nimport agentmail from \"@agentmail/convex/convex.config\";\n\nconst app = defineApp();\napp.use(agentmail);\nexport default app;\n```\n\nSet credentials on your Convex deployment (kept out of mutation args so they don't appear in function logs):\n\n```bash\nnpx convex env set AGENTMAIL_API_KEY your_api_key\nnpx convex env set AGENTMAIL_WEBHOOK_SECRET whsec_...\n# Optional: EU residency\nnpx convex env set AGENTMAIL_BASE_URL https://api.agentmail.eu/v0\n```\n\n## Query threads and messages\n\nThe most reactive part of the API. Subscribe from React; new mail appears the instant AgentMail's webhook fires.\n\n```ts\n// convex/email.ts\nimport { query } from \"./_generated/server\";\nimport { components } from \"./_generated/api\";\nimport { v } from \"convex/values\";\n\nexport const listThread = query({\n  args: { threadId: v.string() },\n  handler: (ctx, { threadId }) =>\n    ctx.runQuery(components.agentmail.lib.listInboundMessages, { threadId }),\n});\n\nexport const listInbox = query({\n  args: { inboxId: v.string() },\n  handler: (ctx, { inboxId }) =>\n    ctx.runQuery(components.agentmail.lib.listInboundMessages, { inboxId }),\n});\n```\n\n```tsx\n// React\nconst messages = useQuery(api.email.listThread, { threadId });\n```\n\nFor thread metadata (last message, participants, label set) from AgentMail's remote API:\n\n```ts\nimport { AgentMail } from \"@agentmail/convex\";\nconst agentmail = new AgentMail(components.agentmail);\n\nawait agentmail.listThreads(ctx, inboxId, { labels: [\"urgent\"] });\nawait agentmail.getThread(ctx, inboxId, threadId);\nawait agentmail.getMessage(ctx, inboxId, messageId);\n```\n\n## Send mail (with labels)\n\n```ts\nimport { mutation } from \"./_generated/server\";\nimport { components } from \"./_generated/api\";\nimport { AgentMail } from \"@agentmail/convex\";\nimport { v } from \"convex/values\";\n\nconst agentmail = new AgentMail(components.agentmail);\n\nexport const sendHello = mutation({\n  args: { inboxId: v.string(), to: v.string() },\n  handler: async (ctx, args) => {\n    return await agentmail.sendMessage(ctx, args.inboxId, {\n      to: args.to,\n      subject: \"Hello from my Convex agent\",\n      text: \"Hi! This was sent from a Convex mutation.\",\n      labels: [\"support-agent\", \"auto-reply\"],\n    });\n  },\n});\n```\n\nThe return value is an `OutboundId`. Subscribe to it for live delivery status:\n\n```ts\nconst status = useQuery(api.email.sendStatus, { outboundId });\n// → { status: \"sent\" | \"delivered\" | \"bounced\" | ..., agentmailMessageId, threadId, errorMessage }\n```\n\n## Receive mail\n\nMount the webhook handler in `convex/http.ts`:\n\n```ts\nimport { httpRouter } from \"convex/server\";\nimport { httpAction } from \"./_generated/server\";\nimport { components } from \"./_generated/api\";\nimport { AgentMail } from \"@agentmail/convex\";\n\nconst agentmail = new AgentMail(components.agentmail);\nconst http = httpRouter();\n\nhttp.route({\n  path: \"/agentmail/webhook\",\n  method: \"POST\",\n  handler: httpAction(async (ctx, req) => agentmail.handleWebhook(ctx, req)),\n});\n\nexport default http;\n```\n\nRegister the webhook URL with AgentMail (`https://your-deployment.convex.site/agentmail/webhook`) and copy the secret into `AGENTMAIL_WEBHOOK_SECRET`.\n\n## React to inbound mail (your agent runs here)\n\n```ts\nimport { internalMutation } from \"./_generated/server\";\nimport { components, internal } from \"./_generated/api\";\nimport { AgentMail } from \"@agentmail/convex\";\nimport { v } from \"convex/values\";\n\nconst agentmail = new AgentMail(components.agentmail, {\n  onMessageReceived: internal.email.onMessageReceived,\n});\n\nexport const onMessageReceived = internalMutation({\n  args: { message: v.any(), thread: v.any(), eventId: v.string() },\n  handler: async (ctx, args) => {\n    // Your LLM agent runs here.\n    await ctx.scheduler.runAfter(0, internal.email.autoReply, {\n      inboxId: args.message.inbox_id,\n      messageId: args.message.message_id,\n      threadId: args.message.thread_id,\n      text: args.message.text ?? \"\",\n    });\n  },\n});\n```\n\nThe `thread` argument carries everything AgentMail knows about the thread at the moment the message landed — labels, participants, message count — so your agent can decide what to do without a follow-up round-trip.\n\n## Configuration\n\n`new AgentMail(component, options?)` accepts an options object. Credentials are read from the Convex deployment's env vars and **not** accepted here, so they never appear in function logs.\n\n| Option              | Env var (component-side)   | Default                          |\n| ------------------- | -------------------------- | -------------------------------- |\n| —                   | `AGENTMAIL_API_KEY`        | _required_                       |\n| —                   | `AGENTMAIL_BASE_URL`       | `https://api.agentmail.to/v0`    |\n| `webhookSecret`     | `AGENTMAIL_WEBHOOK_SECRET` | _required for webhook handler_   |\n| `retryAttempts`     | —                          | `5`                              |\n| `initialBackoffMs`  | —                          | `30000`                          |\n| `onMessageReceived` | —                          | none                             |\n| `onEvent`           | —                          | none (fires on every event type) |\n\nFor EU residency, set `AGENTMAIL_BASE_URL=https://api.agentmail.eu/v0`.\n\n## License\n\nApache-2.0\n","readmeFilename":"README.md"}