Background Agent
This cookbook builds a background agent that runs a "morning sweep" across your apps. It checks GitHub for PRs that need your review, finds unanswered emails in Gmail, and posts a summary to Slack. One script, three apps, zero human input.
Run it manually, put it on a cron, or deploy it. The agent does the rest.
Prerequisites
- Node.js 18+
- Composio API key
- OpenAI API key
Project setup
Create a new project and install dependencies:
mkdir composio-background-agent && cd composio-background-agent
npm init -y
npm install ai @ai-sdk/openai @composio/core @composio/vercel dotenv tsxAdd your API keys to a .env file:
COMPOSIO_API_KEY=your_composio_api_key
OPENAI_API_KEY=your_openai_api_keyInitializing the clients
Composio takes a VercelProvider so that tools come back as Vercel AI SDK tools with built-in execution. No manual tool-call loop needed.
const composio = new Composio({ provider: new VercelProvider() });
const userId = process.env.COMPOSIO_USER_ID ?? "default";
const model = openai("gpt-5.2");The sweep
The entire agent is one function. Create a session, get tools, and give the model a prompt describing what to do. generateText with stopWhen: stepCountIs(15) lets the model call as many tools as it needs, discovering available actions, authenticating with apps, and executing across GitHub, Gmail, and Slack, all in a single run.
async function sweep() {
const session = await composio.create(userId);
const tools = await session.tools();
const { text } = await generateText({
model,
tools,
stopWhen: stepCountIs(15),
prompt: `You are an autonomous background agent running a scheduled sweep.
Do the following, in order:
1. **GitHub**:Find pull requests where my review is requested.
List each PR with its title, repo, and link.
2. **Gmail**:Find emails from the last 24 hours that I haven't replied to.
List each with sender and subject.
3. **Slack**: Post a concise summary of your findings to the #morning-sweep channel.
Format it as a digest with sections for PRs and emails.
If nothing was found, say so.
If an app is not connected, skip it and note it in the summary.
Be concise and actionable.`,
});
console.log(text);
}
sweep();That's it. The agent figures out which tools to call, handles pagination, formats the results, and posts to Slack. Composio's meta-tools handle tool discovery and auth inline. If an app isn't connected, the agent skips it gracefully.
Complete script
import "dotenv/config";
import { openai } from "@ai-sdk/openai";
import { generateText, stepCountIs } from "ai";
import { Composio } from "@composio/core";
import { VercelProvider } from "@composio/vercel";
// #region setup
const composio = new Composio({ provider: new VercelProvider() });
const userId = process.env.COMPOSIO_USER_ID ?? "default";
const model = openai("gpt-5.2");
// #endregion setup
// #region sweep
async function sweep() {
const session = await composio.create(userId);
const tools = await session.tools();
const { text } = await generateText({
model,
tools,
stopWhen: stepCountIs(15),
prompt: `You are an autonomous background agent running a scheduled sweep.
Do the following, in order:
1. **GitHub**:Find pull requests where my review is requested.
List each PR with its title, repo, and link.
2. **Gmail**:Find emails from the last 24 hours that I haven't replied to.
List each with sender and subject.
3. **Slack**: Post a concise summary of your findings to the #morning-sweep channel.
Format it as a digest with sections for PRs and emails.
If nothing was found, say so.
If an app is not connected, skip it and note it in the summary.
Be concise and actionable.`,
});
console.log(text);
}
sweep();
// #endregion sweepRunning the sweep
npx tsx sweep.tsExample output:
### GitHub: PRs where your review is requested (3)
- fix: robust platform detection (ComposioHQ/composio)
https://github.com/ComposioHQ/composio/pull/2712
- docs: add retry to health check workflow (ComposioHQ/composio)
https://github.com/ComposioHQ/composio/pull/2711
- chore(deps): bump next (ComposioHQ/composio)
https://github.com/ComposioHQ/composio/pull/2473
### Gmail: Emails from last 24h you haven't replied to (1)
- Stephanie M. - CoreWeave - We'd love to chat!
### Slack: Digest posted to #morning-sweepIf an app isn't connected yet, the agent will return an authentication link in the output. Open it in your browser to complete OAuth, then run the sweep again.
Running on a schedule
The agent runs once and exits, which makes it perfect for cron jobs. Pick whichever scheduler you prefer.
crontab (every day at 8am)
crontab -e0 8 * * * cd /path/to/composio-background-agent && npx tsx sweep.ts >> sweep.log 2>&1GitHub Actions
name: Morning Sweep
on:
schedule:
- cron: '0 8 * * *' # 8am UTC daily
workflow_dispatch: # manual trigger
jobs:
sweep:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm install
- run: npx tsx sweep.ts
env:
COMPOSIO_API_KEY: ${{ secrets.COMPOSIO_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}Take it further
The prompt is the agent's brain. Change it to change what it does. Some ideas:
- Triage support tickets: scan Zendesk for unassigned tickets, categorize them, assign to the right team in Linear
- Daily standup prep: pull yesterday's commits from GitHub, completed tasks from Linear, and draft a standup summary
- Invoice follow-up: check QuickBooks for overdue invoices, draft follow-up emails in Gmail