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.

pip install mahmood-agent
mahmood setup
mahmood
› 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 qwen/qwen3.6-27b. If you choose a text-only model, 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 Default. Completed the task cleanly first time, and reads images, so screenshots need no second model.
openai/gpt-oss-120b 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 Sometimes packs the arguments into the function name, which the API rejects. Mahmood repairs that shape when it can. 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

pip install 'mahmood-agent[browser]'
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 = "qwen/qwen3.6-27b"
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

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mahmood_agent-0.1.2.tar.gz (47.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mahmood_agent-0.1.2-py3-none-any.whl (56.4 kB view details)

Uploaded Python 3

File details

Details for the file mahmood_agent-0.1.2.tar.gz.

File metadata

  • Download URL: mahmood_agent-0.1.2.tar.gz
  • Upload date:
  • Size: 47.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for mahmood_agent-0.1.2.tar.gz
Algorithm Hash digest
SHA256 3f18c2ec3cd28e1ff8cc93b8df2fedd0833b0c35cb05ca4d929e33c200e5a2cd
MD5 f54ad13bcc86487fef803e7296e92638
BLAKE2b-256 d56c743930ac3970d2e4bd3935d090de738764a6b384173e9f1bb36d27a89961

See more details on using hashes here.

File details

Details for the file mahmood_agent-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: mahmood_agent-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 56.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for mahmood_agent-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 ad17e0b09dc9234f1d2f689f2ace0d9a31e5a80fa0062dd14f2648c10847ec2f
MD5 77f3196ff75210fff9d661e8dff6eec4
BLAKE2b-256 6fc6c4c5b007a6d638e192361b8027604331af94274c49b5d71cca64c3fb5a06

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page