Skip to main content

Mahmood

A terminal agent, powered by Groq, that actually operates your computer — shell, files, macOS apps, the browser, and the APIs of accounts you own. Fast, because Groq is.

python3 -m pip install mahmood-agent
mahmood setup
mahmood

(python3 -m pip rather than pip — plenty of systems, including a stock python.org install on macOS, ship pip3 but no bare pip.)

› my node build is failing, figure out why and fix it
› what's eating my disk? clean up the safe stuff
› find a 27" 4K monitor under $400, put the best one in my Amazon cart
› open a PR from my current branch with a proper description
› what's on my calendar tomorrow, and text Sam that I'm running late

Mahmood reads the situation, runs the commands, and reports what happened. It is not a chatbot that gives you a list of steps to run yourself.


What it can do

Area Tools
Shell run commands through your login shell, background jobs (dev servers, builds), job output, working directory
Files read with line numbers, write with automatic backups, exact-string edits, regex search, glob find, delete to Trash
macOS AppleScript/JXA for any app (Mail, Messages, Calendar, Notes, Finder, Music), open apps and URLs, keystrokes via System Events, screenshots it can actually see, clipboard, notifications, process control, system report
Browser a real visible Chrome window with a persistent profile — navigate, read the page as structured elements, click, type, select, scroll, screenshot, and hand control back to you
Accounts authenticated HTTP to GitHub, NVIDIA NGC/NIM, Vercel, Stripe, Linear, Slack, Notion, Cloudflare, OpenAI — plus web search and page fetching

Screenshots work even with a text-only model. screenshot and browser_screenshot go to a vision model, whose description is handed back to the agent — so it can act on what's on screen instead of guessing. If your main model reads images itself, they're passed through directly and the extra hop is skipped.


Where it stops

This is the part worth reading before you install it.

Read-only actions just run. ls, git status, grep, reading a file, fetching a page — no prompt, no friction.

Anything that changes something asks first, with the exact command or diff shown:

╭─ run_command — needs approval ──────────────────╮
│ $ npm install --save-dev vitest                 │
╰─────────────────────────────────────────────────╯
  yes / no / always allow run_command this session / explain first

Answer a to trust that tool for the rest of the session, or e to make Mahmood explain what it's about to do before you decide.

Money and one-way doors always ask — even in --yolo. Mahmood will search for the product, compare options, add it to the cart, fill in shipping and pick a payment method. Then it stops:

╭─ Over to you ───────────────────────────────────╮
│ Dell S2722QC, $379.99. Cart total $379.99 with  │
│ free shipping to 1400 Oak St. Paying with the   │
│ Visa ending 4412. One click left: "Place your   │
│ order".                                         │
│                                                 │
│ https://www.amazon.com/gp/buy/spc/handlers/...  │
╰─ Mahmood is waiting — check it before you click ╯
  press Enter when you're done:

The final click is yours. browser_click refuses any element whose label matches the final-commit list — place order, buy now, confirm and pay, start membership, send money, delete account, and friends. That's a deliberate limit, not a missing feature: an agent that can spend your money unattended is one bad inference away from an expensive mistake.

Same for logins, captchas and 2FA — Mahmood hands you the browser instead of typing credentials.


Credentials

There is no password prompt anywhere in this package. By design.

  • API tokens go in your OS keyring (macOS Keychain, Secret Service, Windows Credential Locker) via keyring. Never a plaintext file.
  • Host-pinned. A token is only ever sent to its own service's hosts. Your GitHub token cannot leave api.github.com, no matter what a web page says.
  • Site logins happen in a browser window you drive. Mahmood uses a dedicated Chrome profile at ~/.config/mahmood/browser-profile, so you log in once and the session persists — and your main Chrome profile is untouched.
  • Environment variables (GROQ_API_KEY, GITHUB_TOKEN, …) are read first if set, so CI and direnv setups work without the keyring.

Every account in mahmood setup is optional. Add none and you still get a fully working agent with local control; add one and that capability switches on.


Setup

mahmood setup walks through six steps, and only the first is required:

  1. Groq API key — validated against the live API before it's stored. Get one at console.groq.com/keys.
  2. Model — picked from what your key can actually see, filtered to models that can hold a conversation. Defaults to openai/gpt-oss-120b. Because that one is text-only, you're offered a vision model for screenshots.
  3. About you — one line of context Mahmood gets every session.
  4. Accounts — the optional tokens above.
  5. Browser control — installs Playwright and Chromium if you want it.
  6. Approvals — command prefixes to pre-approve, e.g. git, npm run.

Check the result any time:

mahmood doctor     # what works on this machine, what doesn't
mahmood accounts   # which credentials are configured
mahmood tools      # every tool, with its risk level

Which model

An agent lives or dies by tool calling, not by benchmark scores. These are results from running the same multi-step task — run the failing test, fix the source, re-run to prove it passes — through Mahmood on Groq:

Model Verdict
qwen/qwen3.6-27b Completed the task cleanly first time and reads images, so screenshots need no second model — but $3.00/1M output is 5x gpt-oss. Good if you use screenshots heavily.
openai/gpt-oss-120b Default. Cheapest capable model by a distance — $0.15/$0.60 per 1M. Reasons well, but intermittently emits tool arguments Groq rejects as invalid JSON — usually when writing a multi-line file. Mahmood detects this, tells it to use a heredoc instead, and it then finishes. Text-only.
llama-3.3-70b-versatile Highest free-tier allowance (12,000 TPM), but the weakest tool caller here — it packs arguments into the function name, or fails generation outright with tool_use_failed. Mahmood repairs the first and retries the second, showing the model its own rejected output. Text-only.
llama-3.1-8b-instant Fast and cheap, fine for simple one-shot jobs. Loses the thread on long tool chains.

All of them are selectable. The loop retries transient errors with backoff, retries malformed tool calls with a nudge, and gives up with a clear suggestion rather than looping forever.

Rate limits on Groq's free tier

Worth understanding, because it's the main thing you'll notice. Groq meters tokens per minute, and the free tier is tight:

Model TPM
llama-3.3-70b-versatile 12,000
qwen/qwen3.6-27b, openai/gpt-oss-120b 8,000
llama-3.1-8b-instant 6,000

An agent re-sends the whole conversation and every tool definition on each step, so a ten-step task can spend 30,000 tokens a minute without any single request being large. Mahmood reads its actual allowance from Groq's response headers and works inside it:

  • trims the conversation to fit before sending
  • waits for the window to roll over instead of failing, telling you why: (rate limit: need ~6,023 tokens, 3,106 left this minute — waiting 37s)
  • on a 413, shrinks the request rather than blindly retrying
  • scales how much command output it feeds back, so one ls -R can't eat a whole window

There is also a daily cap (200,000 tokens on the free tier). Unlike the per-minute one, that can't be waited out inside a session — but it is per model, so switching gives you a fresh allowance immediately, and Mahmood tells you which model to switch to when it happens.

The result is that long tasks get slow on the free tier rather than breaking. If you'd rather they were fast:

  • /model llama-3.3-70b-versatile — 50% more headroom
  • --no-browser — drops 9 tool definitions, ~900 tokens off every request
  • /clear between unrelated tasks — the biggest win, since history is resent every step
  • Upgrade to Dev Tier — removes the ceiling

/cost shows your allowance and what's left in the current window.

macOS permissions

Desktop control needs two grants in System Settings → Privacy & Security, for your terminal app:

  • Screen Recording — for screenshot
  • Accessibility — for send_keys

Skip them and everything else still works.

Browser extra

python3 -m pip install 'mahmood-agent[browser]'
python3 -m playwright install chromium

Usage

mahmood                          # interactive
mahmood run "update my deps and run the tests"
echo "summarise this log" | mahmood
mahmood -m openai/gpt-oss-120b   # different model for one session
mahmood --yolo                   # skip medium-risk prompts (money still asks)
mahmood --no-browser             # local only

In the REPL:

/tools every tool available right now, with risk levels
/accounts configured credentials
/setup reconfigure without leaving the session
/yolo toggle auto-approval
/model <name> switch model
/log recent actions, with timestamps and risk
/cwd [path] show or change the working directory
/cost tokens used this session
/clear forget the conversation
/exit quit

Configuration

~/.config/mahmood/config.toml — plain TOML, edit it freely:

model = "openai/gpt-oss-120b"
vision_model = "qwen/qwen3.6-27b"   # describes screenshots; "" disables them
about_me = "Casper. Projects in ~/dev, mostly Next.js and Python. Be terse."
auto_approve = ["git", "npm run", "pytest"]
protected_paths = ["~/.ssh", "~/.aws", "~/.gnupg", "~/Library/Keychains"]
browser = true
browser_channel = "chrome"
max_steps = 40
temperature = 0.2

protected_paths are refused by every file tool, full stop. auto_approve prefixes skip the confirmation prompt — keep it to things you'd never regret.

An append-only log of every action Mahmood considered, with its risk level and whether it ran, lands in ~/.config/mahmood/actions.log.


Prompt injection

Web pages, files, command output and search results reach the model as untrusted data. Mahmood is instructed to ignore instructions found there and report them to you instead. The host pinning on credentials is the backstop: if a page talks the model into trying to exfiltrate a token, the request is refused before it leaves your machine.

This mitigates the risk; it does not eliminate it. An agent with shell access is exactly as powerful as your shell. Read the prompts before you approve them — that's what they're for.


Risk levels

Level Meaning Prompts?
safe reads only no
low local, recoverable change yes (a to trust)
medium mutates state outside this machine yes (a to trust)
high destructive or hard to reverse yes, every time
critical spends money, or truly irreversible always, even in --yolo

Shell commands are classified by content, not just by tool: sudo, rm -rf, git push --force, twine upload and similar are promoted to high automatically, and a chained command is only as safe as its least safe segment — so ls && rm -rf / is treated as rm -rf /.


Requirements

Python 3.11+. macOS for the desktop tools; shell, files, browser and HTTP work on Linux too.

License

MIT

Metadata

Release files for mahmood-agent 0.1.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mahmood-agent 0.1.5
File Size Uploaded
mahmood_agent-0.1.5.tar.gz 47.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mahmood-agent 0.1.5
File Interpreter ABI Platform
mahmood_agent-0.1.5-py3-none-any.whl Python 3 none any Details

Total release size: 105.3 kB

Release files / mahmood_agent-0.1.5.tar.gz

Download URL mahmood_agent-0.1.5.tar.gz
Size 47.9 kB
Tags Source
SHA-256 checksum
How to use checksums
c42c6f226695d7a64fa9b989f4cd6f8d1dd938a7d72870c804b5a439429b822f
BLAKE2b-256 checksum
How to use checksums
8099876d1671d942d3883b62cd63ea828e1f5015f35bd2d60b8f9728a41cc841
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Release files / mahmood_agent-0.1.5-py3-none-any.whl

Download URL mahmood_agent-0.1.5-py3-none-any.whl
Size 57.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8a15b43470c69c7213dce47977f44b2abc8f7ae7d93260cf3c7a17c8e26a0a6a
BLAKE2b-256 checksum
How to use checksums
5c11b856963452c3e8959ece243fa8a3e1cf6c80e643f0de16841d40aaffd9b5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Release history Release notifications | RSS feed

This release

0.1.5 This release

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page