From zero to a working AI executive assistant. Follow each step in order. Total time: ~15 minutes.
Dedicated server that runs 24/7. Your agent is always on — scheduled jobs, workers, and Slack bot run even when your laptop is closed.
Cost: ~$9/mo (Hetzner) + AI engine subscription
Run on your own computer. Free hosting, but cron jobs and workers stop when your machine sleeps.
Cost: AI engine subscription only
Skip to Part 2 if using your local machine.
Go to hetzner.com/cloud and create an account. Add a payment method.
Hetzner offers the best price/performance ratio for this use case. A CPX21 (3 vCPU, 4GB RAM) at ~$9/month is more than enough.
In the Hetzner console, go to Security > SSH Keys and add your public key.
If you don't have an SSH key yet:
ssh-keygen -t ed25519 -C "your-email@example.com"
cat ~/.ssh/id_ed25519.pubIn the Hetzner console:
SSH in as root and run the security hardening script:
ssh root@YOUR_SERVER_IP
# Download and run hardening script
curl -sL https://raw.githubusercontent.com/madewell-ai/agent-setup/main/vm-setup/harden.sh -o harden.sh
chmod +x harden.sh
./harden.sh maiaThis will:
ssh maia@YOUR_SERVER_IPLog in as your non-root user and run the install script:
curl -sL https://raw.githubusercontent.com/madewell-ai/agent-setup/main/vm-setup/install-stack.sh -o install-stack.sh
chmod +x install-stack.sh
./install-stack.shThe script will ask which AI engine to install. See the pricing page if you're not sure which to choose.
# For Claude Code:
claude auth
# Opens browser — follow the auth flow
# For Codex CLI:
codex auth
# Enter your API keygit clone https://github.com/madewell-ai/agent-setup.git ~/agent-setup
cd ~/agent-setup
nano config.jsonEdit config.json with your details:
{
"assistant": {
"name": "Jarvis", ← Your agent's name
"role": "AI Executive Assistant"
},
"user": {
"name": "Your Name", ← Your name
"timezone": "America/New_York",
"location": "New York, NY"
},
"engine": "claude-code" ← or "codex"
}This is the key step. You paste a prompt into your AI engine, and it configures the entire system — hooks, memory, cron, everything.
# Claude Code:
claude -p "$(cat ~/agent-setup/setup-prompts/claude-code-setup.md)"
# Codex CLI:
codex "$(cat ~/agent-setup/setup-prompts/codex-setup.md)"The agent will read the instructions, set up all the hooks and scripts, create the memory system, install cron jobs, and report back what it did.
You can also copy the setup prompt from the Setup Prompt page.
Go to api.slack.com/apps and click Create New App > From a manifest.
Select your workspace, then paste the app manifest:
{
"_metadata": {
"major_version": 2,
"minor_version": 1
},
"display_information": {
"name": "My Agent",
"description": "AI Assistant — Powered by Claude Code",
"background_color": "#1a1a2e"
},
"features": {
"app_home": {
"home_tab_enabled": false,
"messages_tab_enabled": true,
"messages_tab_read_only_enabled": false
},
"bot_user": {
"display_name": "My Agent",
"always_online": true
},
"slash_commands": [
{
"command": "/workers",
"description": "List active and recent background workers",
"should_escape": false
},
{
"command": "/spawn",
"description": "Spawn a background worker in this channel's workdir",
"usage_hint": "<prompt>",
"should_escape": false
},
{
"command": "/context",
"description": "Show this channel's workdir and context",
"should_escape": false
},
{
"command": "/clear",
"description": "Clear conversation history for this channel",
"should_escape": false
},
{
"command": "/restart",
"description": "Restart the Slack bot",
"should_escape": false
}
]
},
"oauth_config": {
"scopes": {
"bot": [
"app_mentions:read",
"channels:history",
"channels:join",
"channels:manage",
"channels:read",
"chat:write",
"chat:write.public",
"commands",
"groups:history",
"groups:read",
"im:history",
"im:read",
"im:write",
"mpim:history",
"mpim:read",
"users:read",
"files:read",
"files:write"
]
}
},
"settings": {
"event_subscriptions": {
"bot_events": [
"app_mention",
"message.channels",
"message.groups",
"message.im",
"message.mpim"
]
},
"interactivity": {
"is_enabled": false
},
"org_deploy_enabled": false,
"socket_mode_enabled": true,
"token_rotation_enabled": false
}
}Update the display_name and name to your agent's name, then create the app.
You need two tokens:
cd ~/agent-setup/shared/slack-bot
cp .env.example .env
nano .env
# Add your SLACK_BOT_TOKEN and SLACK_APP_TOKEN
npm install
node bot.js # Test it firstSend a DM to your bot in Slack. If it responds, it's working!
Set it up as a systemd service so it runs 24/7:
# Copy and edit the service file
cp ~/agent-setup/shared/slack-bot/agent-slack.service ~/.config/systemd/user/
nano ~/.config/systemd/user/agent-slack.service
# Update paths if your username isn't 'maia'
# Enable and start
systemctl --user daemon-reload
systemctl --user enable --now agent-slack
# Verify
systemctl --user status agent-slackYour AI assistant is live. Message it in Slack, set up cron jobs for automated tasks, and let it learn your preferences over time.
Spawn long-running tasks that work in the background while you do other things. The heartbeat monitor checks them every 15 minutes and notifies you when they finish.
# From Slack:
/spawn Research the latest trends in AI agents and summarize findings
# From the command line:
~/.agent/scripts/spawn-worker.sh "Research AI trends" "Research the latest..." ~/Create skill files to give your agent domain-specific knowledge. Skills are markdown files that the agent reads when you invoke them with a slash command.
# Create a skill at ~/.claude/skills/my-skill.md
# Then reference it in your CLAUDE.md under the Skills section:
# - /my-skill — description of what it doesConfigure different Slack channels with their own workdirs and system prompts. Each channel can target a specific project or area.
// In config.json under slack.channels:
"dev-myproject": {
"workdir": "~/myproject",
"system_prompt": "You are working on MyProject. Always work in a feature branch."
}Manage scheduled tasks with the cron CLI. Morning summaries, inbox triage, memory consolidation — your agent works while you sleep.
# List all jobs:
~/.agent/cron/manage.sh list
# Enable the morning summary:
~/.agent/cron/manage.sh enable morning-summary
~/.agent/cron/manage.sh install
# Add a custom job:
~/.agent/cron/manage.sh add my-job "My Job" "0 9 * * 1-5" "America/New_York" "Do something useful" "~" trueYour agent automatically detects when you correct it and queues those corrections for review. Over time, corrections become persistent memories so the agent doesn't repeat the same mistakes. Review pending feedback anytime:
python3 ~/.agent/scripts/process-feedback.py