aw-agents
AI Agents for Agentic Workflows - Easily deploy AI agents to multiple chatbot platforms (Claude, ChatGPT, and more).
Overview
aw-agents provides a unified framework for building AI agents and deploying them to different chatbot platforms with minimal boilerplate. Write your agent once, deploy everywhere.
Key Features
- 🎯 Write Once, Deploy Everywhere: Single agent implementation works with Claude, ChatGPT, and future platforms
- 🔌 Pluggable Adapters: MCP for Claude, OpenAPI for ChatGPT
- 📦 Batteries Included: Built-in download agent with smart features
- 🛠️ Easy to Extend: Simple base class for creating new agents
- 🎨 Clean Architecture: Separation of agent logic and platform adapters
- 🚀 Run as Script: Each agent can run directly as a server with built-in setup instructions
Documentation
- 📚 Quick Usage Guide - Simplest way to run agents
- 📖 This README - Comprehensive documentation
- 💻 Examples - Code examples
Installation
# From source (recommended for development)
git clone https://github.com/thorwhalen/aw_agents.git
cd aw_agents
pip install -e .
# With Claude Desktop support (MCP)
pip install -e .[mcp]
# With ChatGPT Custom GPT support (FastAPI)
pip install -e .[api]
# With all features
pip install -e .[all]
# For development
pip install -e .[dev]
Verify Installation
# Test the installation
python -c "from aw_agents.agents.download import DownloadAgent; agent = DownloadAgent(); print('✓ Installation successful!')"
Quick Start
Easiest Way: Run Agent as Server
Each agent can be run directly as a server with built-in instructions:
# For Claude Desktop (MCP server)
python -m aw_agents.agents.download.agent --mcp
# For ChatGPT (FastAPI server)
python -m aw_agents.agents.download.agent --api
# With ngrok for remote access
python -m aw_agents.agents.download.agent --api --server-url https://your-ngrok-url.ngrok.io
The agent will print:
- ✅ Configuration snippets (copy-paste ready)
- 📍 Exact file locations for configs
- 📋 Step-by-step setup instructions
- 🚀 Everything you need to get started
- 🌐 Proper OpenAPI schema with server URLs (fixes ChatGPT import issues)
Using the Download Agent
The package includes a smart download agent out of the box:
from aw_agents.agents.download import DownloadAgent
agent = DownloadAgent()
# Get available tools
tools = agent.get_tools()
print([t['name'] for t in tools])
# ['download_content', 'download_multiple', 'list_downloads']
# Execute a tool
result = agent.execute_tool('download_content', {
'url': 'https://arxiv.org/pdf/2103.00020.pdf',
'context': 'Important ML Paper'
})
print(result['data']['path']) # ~/Downloads/Important_ML_Paper.pdf
Deploy to Claude Desktop (MCP)
Quick Start - Run the agent directly:
# The agent will automatically configure Claude Desktop for you!
python -m aw_agents.agents.download.agent --mcp
# Or run directly:
python aw_agents/agents/download/agent.py --mcp
The agent will:
- Automatically add itself to your Claude Desktop config
- Start the MCP server
- Give you step-by-step instructions
- You just need to restart Claude Desktop!
Managing Claude Desktop Configuration:
The agent uses claude_desktop_config() from the aw package to automatically manage your Claude Desktop configuration:
from aw.util import claude_desktop_config
# View all configured MCP servers
mcp = claude_desktop_config()
list(mcp) # ['download', 'other_server', ...]
# Add a new server manually
mcp['my_agent'] = {
'command': 'python',
'args': ['/path/to/my_agent.py']
}
# Remove a server
del mcp['old_server']
# View a server's config
print(mcp['download'])
Manual Setup (Alternative):
If you prefer to create your own script and manage configuration manually:
Step 1: Create MCP Server Script
from aw_agents.agents.download import DownloadAgent
from aw_agents.adapters import MCPAdapter
agent = DownloadAgent()
adapter = MCPAdapter(agent, "download-agent")
# This starts an MCP server for Claude Desktop
if __name__ == "__main__":
adapter.run_sync()
Save this as mcp_download.py or use the deployment script:
python scripts/deploy_mcp.py DownloadAgent --output mcp_download.py
Step 2: Configure Claude Desktop
Using claude_desktop_config():
from aw.util import claude_desktop_config
mcp = claude_desktop_config()
mcp['download'] = {
'command': 'python',
'args': ['/absolute/path/to/mcp_download.py']
}
Or manually edit the config file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
Important: Use absolute paths, not ~/ or relative paths.
Step 3: Restart Claude Desktop
Completely quit and restart Claude Desktop.
Step 4: Test It
Ask Claude:
Download this paper for me: https://arxiv.org/pdf/2103.00020.pdf
Context: "Attention is All You Need"
Troubleshooting:
- Check logs:
~/Library/Logs/Claude/(macOS) - Verify Python path in config
- Ensure dependencies are installed in the correct Python environment
Deploy to ChatGPT Custom GPT (FastAPI)
Quick Start - Run the agent directly:
# The agent will print setup instructions for you
python -m aw_agents.agents.download.agent --api
# Or specify a custom port:
python aw_agents/agents/download/agent.py --api --port 8080
The agent will:
- Start the FastAPI server
- Print the server URLs (API, docs, OpenAPI schema)
- Show you exactly how to configure ChatGPT Custom GPT
- Provide ngrok instructions for remote access
Manual Setup (Alternative):
Step 1: Create and Start API Server
from aw_agents.agents.download import DownloadAgent
from aw_agents.adapters import OpenAPIAdapter
agent = DownloadAgent()
adapter = OpenAPIAdapter(agent, title="Download Agent API")
# This starts a FastAPI server
if __name__ == "__main__":
adapter.run(port=8000)
Save this as api_download.py or use the deployment script:
python scripts/deploy_api.py DownloadAgent --output api_download.py
python api_download.py # Start the server
The server will be available at http://localhost:8000
Step 2: Create Custom GPT
- Go to https://chat.openai.com/gpts/editor
- Click "Create a GPT"
- Name it (e.g., "Download Assistant")
- Add instructions:
You help users download files from URLs. Use the download_content action when users provide URLs. Always ask for context to generate good filenames. You can download multiple files at once and list previously downloaded files.
Step 3: Add Actions
- In the GPT editor, go to "Configure" → "Actions"
- Click "Create new action"
- Import schema from:
http://localhost:8000/openapi.json - Click "Add Action"
Step 4: Test Your GPT
Ask your Custom GPT:
Download this dataset: https://github.com/user/repo/blob/main/data.csv
Context: "Sales Data Q4"
Important Notes:
- Local Testing: ChatGPT servers can't access
localhostfrom OpenAI's infrastructure - For Remote Access:
- Use ngrok:
ngrok http 8000(provides a public URL) - Deploy to cloud service (AWS, GCP, Azure, Heroku)
- Use local network IP if on the same network
- Use ngrok:
Production Deployment:
- Deploy to cloud service with HTTPS
- Add authentication (API keys, OAuth)
- Update Custom GPT actions with public URL
Architecture
aw_agents/
├── base.py # AgentBase, ToolExecutionResult
├── adapters/
│ ├── mcp.py # MCPAdapter for Claude
│ └── openapi.py # OpenAPIAdapter for ChatGPT
└── download/ # Download agent implementation
├── agent.py # DownloadAgent (AgentBase subclass)
└── download_core.py # Core download logic
Creating Your Own Agent
from aw_agents.base import AgentBase, ToolExecutionResult, create_json_schema
class MyAgent(AgentBase):
"""My custom agent."""
def get_tools(self):
return [
{
'name': 'my_tool',
'description': 'Does something useful',
'parameters': create_json_schema(
properties={
'input': {
'type': 'string',
'description': 'Input text'
}
},
required=['input']
)
}
]
def execute_tool(self, name, arguments):
if name == 'my_tool':
# Your logic here
result = self._process(arguments['input'])
return ToolExecutionResult.success_result(
data={'output': result},
message="Processed successfully"
).to_dict()
return ToolExecutionResult.error_result(
message=f"Unknown tool: {name}"
).to_dict()
def _process(self, input_text):
# Your implementation
return input_text.upper()
Then deploy it:
# For Claude
from aw_agents.adapters import MCPAdapter
adapter = MCPAdapter(MyAgent(), "my-agent")
adapter.run_sync()
# For ChatGPT
from aw_agents.adapters import OpenAPIAdapter
adapter = OpenAPIAdapter(MyAgent())
adapter.run(port=8001)
Included Agents
Download Agent
Smart content downloader with:
- Landing page detection: Automatically finds actual download links
- Context-aware file naming: Uses conversation context for meaningful filenames
- Special handling for:
- GitHub (converts blob URLs to raw)
- HuggingFace (handles dataset downloads)
- Kaggle datasets
- Academic papers (arXiv, etc.)
- Support for: PDFs, datasets, CSV, JSON, and more
Tools:
download_content- Download a single URL with smart handlingdownload_multiple- Download multiple URLs at oncelist_downloads- List downloaded files
Examples:
from aw_agents.agents.download import DownloadAgent
agent = DownloadAgent()
# Download with context-aware naming
result = agent.execute_tool('download_content', {
'url': 'https://github.com/user/repo/blob/main/data.csv',
'context': 'Dataset for analysis'
})
# Automatically converts to raw.githubusercontent.com
# Saves as: Dataset_for_analysis.csv
# Download multiple files
result = agent.execute_tool('download_multiple', {
'urls': [
'https://arxiv.org/pdf/2103.00020.pdf',
'https://arxiv.org/pdf/1706.03762.pdf'
],
'contexts': [
'Attention Paper',
'Transformer Original'
]
})
# List downloaded PDFs
result = agent.execute_tool('list_downloads', {
'pattern': '*.pdf'
})
Smart Features:
-
Intelligent Extension Detection:
# Priority-based routing handles edge cases correctly agent.execute_tool('download_content', { 'url': 'https://arxiv.org/pdf/2103.00020.pdf', 'context': 'ML Paper' }) # Result: ML_Paper.pdf ✓ (not .html despite Content-Type header) # Explicit extension override agent.execute_tool('download_content', { 'url': 'https://example.com/ambiguous_file', 'context': 'Data', 'explicit_extension': 'csv' }) # Result: Data.csv
-
Landing Page Detection:
# Input: Landing page URL agent.execute_tool('download_content', { 'url': 'https://papers.nips.cc/paper/2017/hash/xxx-Abstract.html' }) # Agent detects HTML, finds PDF link, downloads PDF, warns about redirect
-
GitHub URL Handling:
# Input: GitHub blob URL 'https://github.com/user/repo/blob/main/data.csv' # Converts to: 'https://raw.githubusercontent.com/user/repo/main/data.csv'
-
Context-Aware Naming:
# Without context: # Filename: 2103.00020.pdf # With context: agent.execute_tool('download_content', { 'url': 'https://arxiv.org/pdf/2103.00020.pdf', 'context': 'Attention is All You Need - Transformer Paper' }) # Filename: Attention_is_All_You_Need_Transformer_Paper.pdf
Customizing Extension Detection
The download agent uses configurable routing from the aw.routing module:
from aw.routing import ExtensionRouter
from aw_agents.agents.download import DownloadEngine
# Inspect default mappings
router = ExtensionRouter()
print(router.content_type_map)
print(router.priority_extensions)
# Customize mappings
router.content_type_map['text/x-log'] = '.log'
# Add custom detection strategy
def detect_special(ctx):
if 'special' in ctx.url:
return '.special'
return None
custom_router = router.with_prepended_strategy(detect_special)
# Use in agent
engine = DownloadEngine(extension_router=custom_router)
See EXTENSION_ROUTING_SUMMARY.md for details.
Integration Guides
Claude Desktop Integration
Easiest Way - Automatic Configuration:
# Run the agent - it will automatically configure Claude Desktop!
python -m aw_agents.agents.download.agent --mcp
The agent automatically adds itself to your Claude Desktop config. Just restart Claude Desktop and you're done!
Alternative - Manual Configuration:
-
Create MCP server script:
python scripts/deploy_mcp.py DownloadAgent --output ~/mcp_download.py
-
Add to Claude Desktop config using
claude_desktop_config():from aw.util import claude_desktop_config mcp = claude_desktop_config() mcp['download'] = { 'command': 'python', 'args': ['/absolute/path/to/mcp_download.py'] }
-
Restart Claude Desktop
Managing Servers:
from aw.util import claude_desktop_config
mcp = claude_desktop_config()
# List all servers
list(mcp) # ['download', 'other_server', ...]
# View a server's config
print(mcp['download'])
# Remove a server
del mcp['old_server']
Config file locations:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
Usage Examples in Claude:
Download this paper: https://arxiv.org/pdf/2103.00020.pdf
Context: "Attention is All You Need paper"
I need these papers:
1. https://arxiv.org/pdf/2103.00020.pdf - "Attention Paper"
2. https://arxiv.org/pdf/1706.03762.pdf - "Transformer Original"
Show me what PDFs I've downloaded
ChatGPT Custom GPT Integration
-
Create API server script:
python scripts/deploy_api.py DownloadAgent --output ~/api_download.py python ~/api_download.py
-
Create Custom GPT at https://chat.openai.com/gpts/editor
-
Add actions using schema from:
http://localhost:8000/openapi.json -
For remote access, deploy to cloud or use ngrok:
ngrok http 8000
Usage Examples in ChatGPT:
Download this dataset: https://github.com/user/repo/blob/main/data.csv
Context: "Sales Data Q4 2024"
Can you download these research papers for me?
[List of URLs with contexts]
Troubleshooting
Installation Issues
Problem: Module not found errors
Solution:
# Update pip and reinstall
pip install --upgrade pip
pip uninstall aw-agents
pip install -e .[all]
Problem: Missing dependencies
Solution:
# Install specific feature sets
pip install -e .[mcp] # For Claude
pip install -e .[api] # For ChatGPT
pip install -e .[all] # Everything
Claude Desktop Issues
Problem: Claude doesn't see the download tools
Solution:
- Verify config file location (see paths above)
- Use absolute path in config (not
~/or./) - Check logs:
~/Library/Logs/Claude/(macOS) - Restart Claude Desktop completely (Quit, not just close window)
- Verify Python environment:
which python
Problem: "Module not found" when Claude tries to use agent
Solution:
# Install in the Python environment Claude uses
which python # Check which Python Claude is using
# Use that Python to install dependencies
/path/to/python -m pip install mcp requests beautifulsoup4 graze
ChatGPT Custom GPT Issues
Problem: Actions can't connect to localhost
Solution:
- ChatGPT servers can't access
localhostfrom OpenAI's infrastructure - Options:
- For testing: Use ngrok to expose local server
ngrok http 8000 # Use the ngrok URL in your Custom GPT actions
- For production: Deploy to cloud service (AWS, GCP, Azure, Heroku)
- Same network: Use your local IP address
- For testing: Use ngrok to expose local server
Problem: Schema import fails
Solution:
- Ensure server is running:
curl http://localhost:8000/openapi.json - Check for CORS issues (FastAPI handles this by default)
- Try manual schema paste instead of URL import
General Issues
Problem: Downloads failing
Solution:
- Check internet connection
- Verify URL is accessible:
curl -I [URL] - Some sites may block automated downloads
- Check download directory permissions
Problem: Import errors in Python
Solution:
# Verify installation
python -c "from aw_agents.agents.download import DownloadAgent; print('✓ Success')"
# Reinstall if needed
pip install -e .[all]
Development
Running Tests
pytest
Code Quality
# Format code
black aw_agents tests
# Lint
ruff aw_agents tests
# Type check
mypy aw_agents
Adding a New Agent
-
Create a new directory in
aw_agents/:aw_agents/myagent/ ├── __init__.py ├── agent.py └── core.py (if needed) -
Implement
AgentBaseinagent.py -
Add to
aw_agents/__init__.py:from aw_agents.myagent import MyAgent __all__.append('MyAgent')
-
Create tests in
tests/test_myagent.py -
Update documentation
Roadmap
- Additional built-in agents (research, data prep, etc.)
- Support for more platforms (Slack, Discord, etc.)
- Agent composition and chaining
- Persistent state management
- Authentication and authorization
- Web UI for agent management
- CLI tools for deployment
Contributing
Contributions welcome! Please:
- Fork the repo
- Create a feature branch
- Add tests for new features
- Ensure all tests pass
- Submit a pull request
License
MIT License - see LICENSE file for details
Credits
Built with:
- dol - Storage abstractions
- graze - Download and caching
- MCP - Model Context Protocol
- FastAPI - Modern web framework
Part of the thorwhalen ecosystem.
Metadata
Release files for aw_agents 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| aw_agents-0.1.3.tar.gz | 43.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| aw_agents-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 73.9 kB
Release files / aw_agents-0.1.3.tar.gz
| Download URL | aw_agents-0.1.3.tar.gz |
|---|---|
| Size | 43.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3f470232a642ccb223b95083ed023f7ff26a44d7b397170be92072ee59c08770
|
|
BLAKE2b-256 checksum How to use checksums |
6785e7ee8c9658b8d5201f23aecf7dc4e919219d1105724d23dc3cc4eb06816c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / aw_agents-0.1.3-py3-none-any.whl
| Download URL | aw_agents-0.1.3-py3-none-any.whl |
|---|---|
| Size | 30.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c790d5dca6d6b7717d7db0dfa0e7d703b17cdf8314eaaf2c19503a0913b34ce5
|
|
BLAKE2b-256 checksum How to use checksums |
6f41021306b834fd24d7985fdf77866110f137978dd4a1d5193068f9c6860345
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|