A cross-platform AI research agent that lives inside Slack and Linear. Tag it with a question and it will search the web via SerpApi, synthesize the results with an LLM, and reply with a cited answer — all without leaving your workspace.
- Slack Integration: Mention the bot in any channel and get a researched, cited answer in-thread
- Linear Agent: Assign the bot to an issue or @mention it — it responds with agent activities
- Multi-Engine Search: Automatically routes to Google, Google Scholar, or YouTube based on query content
- LLM Synthesis: Summarizes raw search results into concise answers with source citations
- Async Architecture: FastAPI + async handlers keep both platforms responsive under their timeout constraints
- A developer mentions the bot in Slack or assigns it to a Linear issue.
- The agent calls SerpApi to fetch live, structured search results.
- An LLM synthesizes the results into a concise, cited answer.
- The answer is posted back as a threaded Slack message or a Linear agent activity.
# Clone and install
git clone <repo-url> && cd serpapi-research-agent
uv sync
# Configure environment
cp .env.example .env
# Edit .env with your API keys (see below)
# Run the server
uv run uvicorn serpapi_research_agent.main:app --reload --port 3000
# In another terminal, expose via ngrok
ngrok http 3000Get your SerpApi key: serpapi.com/manage-api-key
| Variable | Description |
|---|---|
SERPAPI_API_KEY |
Your SerpApi API key |
OPENAI_API_KEY |
Your OpenAI API key |
SLACK_BOT_TOKEN |
Slack bot token (xoxb-...) |
SLACK_SIGNING_SECRET |
Slack app signing secret |
LINEAR_API_KEY |
Linear OAuth access token |
LINEAR_WEBHOOK_SECRET |
Linear webhook signing secret |
Optional:
| Variable | Default | Description |
|---|---|---|
OPENAI_MODEL |
gpt-5.4 |
OpenAI model to use for synthesis |
SEARCH_RESULTS_COUNT |
5 |
Number of search results to fetch |
No App Directory submission required — single-workspace installs work immediately.
- Go to api.slack.com/apps → Create New App → From scratch.
- Select your development workspace.
- OAuth & Permissions → add bot scopes:
app_mentions:read,chat:write. - Install to Workspace and copy the Bot User OAuth Token.
- Event Subscriptions → enable, set Request URL to
https://<ngrok-url>/slack/events. - Subscribe to the
app_mentionbot event. - Copy the Signing Secret from the Basic Information page.
- Add both values to your
.env.
Testing: Invite the bot to a channel (/invite @YourBot), then mention it:
@YourBot What is the best Python async web framework?
No publishing required — agents can be built and tested for free in your own workspace.
- Go to linear.app/settings/api/applications/new.
- Name your app (this is how it appears as a workspace member).
- Enable Webhooks and check Agent session events.
- Set the webhook URL to
https://<ngrok-url>/linear/webhooks. - Authentication — pick one:
- OAuth flow: Build the authorize URL with
actor=appand scopesread,write,app:assignable,app:mentionable. Visit it as a workspace admin, approve, and exchange the code for an access token. - Client credentials (simplest for dev): Enable client credentials on the app config page, then:
curl -X POST https://api.linear.app/oauth/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=client_credentials&client_id=YOUR_ID&client_secret=YOUR_SECRET&scope=read,write,app:assignable,app:mentionable"
- OAuth flow: Build the authorize URL with
- Copy the access token and webhook signing secret into your
.env.
Testing: Create a Linear issue and assign the agent as a delegate, or @mention it in a comment. It will respond with research results directly in the issue.
src/serpapi_research_agent/
main.py # FastAPI app, lifespan, route mounting
config.py # Environment config via pydantic-settings
research/
engine.py # SerpApi search + LLM synthesis pipeline
prompts.py # System prompts for the LLM
integrations/
slack.py # Slack Bolt async app + event handlers
linear.py # Linear webhook handler + background tasks
linear_client.py # Async Linear GraphQL API wrapper
- Slack "url_verification failed": Your server isn't running or ngrok isn't forwarding. Check both terminals.
- Linear agent "unresponsive": The webhook URL is wrong or the server didn't respond in time. Check the ngrok request log.
- No search results: Verify your
SERPAPI_API_KEYis valid at serpapi.com/dashboard. - ngrok URL changed: If you restart ngrok, update the URL in both Slack Event Subscriptions and the Linear app webhook settings.
- Fork the repository
- Create your feature branch:
git checkout -b feature/amazing-feature - Install dependencies:
uv sync - Make your changes
- Commit changes:
git commit -m 'Add amazing feature' - Push to branch:
git push origin feature/amazing-feature - Open a Pull Request
MIT License - see LICENSE file for details.