Skip to main content

🐙 Omni Coder

An AI coding agent that plans, edits, and tests code by driving Qwen Coder (or any OpenAI-compatible model) through a scoped set of file and shell tools, with human approval on every write, edit, or shell command.

📦 Install

pip install omni-coder
ollama pull qwen3-coder:30b   # example: pulling the default model via Ollama

▶️ Usage

omni "Add type hints to utils.py, then run the test suite" \
    --project-root ./myrepo

Equivalent: python -m omni "..." --project-root ./myrepo.

Omit the task string to enter an interactive session instead:

omni --project-root ./myrepo

Run omni --help for the full option list.

✨ Features

  • Structured intent parsing — the raw task is classified (bug fix, feature, refactor, risk level, target files) before any action is taken, and high-risk tasks force human approval even under --auto-approve.
  • Session persistence — every message is saved to SQLite as the run happens. Resume a previous run by id or a name you gave it (--resume), browse saved sessions (--list-sessions), or delete one (--delete-session).
  • Interactive mode — drop into a REPL that keeps the model connection and tool session alive across turns. Ctrl-C during a running turn cancels just that turn instead of killing the session — you land back at the prompt and can keep going. Type / for a completion menu of every command, including /model (switch models) and /server:prompt (run an MCP prompt template).
  • Automatic context compaction — once the running conversation exceeds --context-char-budget (default 200k chars), older messages are replaced with an LLM-written summary instead of growing forever or being silently dropped. Trigger it manually anytime with /compact.
  • Human-in-the-loop approval — every write, edit, or shell command shows a diff or command preview before you confirm (diffs render with line numbers and red/green highlighting), unless explicitly marked safe or run with --auto-approve.
  • Retry and recovery — transient model failures retry with backoff; malformed tool-call output is caught and reported back to the model instead of crashing the run.
  • Codebase exploration tools — regex content search with glob filtering, pattern-based file discovery, directory listing, and a full git toolset (status/log/diff/show/branch/fetch read-only; add/commit/ pull/push approval-gated), all skipping noise directories (.git, node_modules, build output).
  • Persistent project memory — the agent can save durable notes (a save_memory tool call) to a per-project agent_memory.md, auto-loaded into the system prompt at the start of every new session.
  • Extensible via custom MCP servers — point at any MCP server, local (stdio) or remote (SSE / Streamable HTTP), and its tools merge into the model's toolset automatically, no code changes required. Register one permanently (--add-mcp-server, available on every future run) or add one per run (--mcp-server/--mcp-config). One server failing to connect doesn't take down the session — check /mcp for live ✅/❌ status per server, and --mcp-log-path for their stderr output.
  • Deferred tool loading + semantic search_tools — register a custom MCP server with --defer and its tools stay out of the model's context until a synthesized search_tools tool loads matching ones on demand, ranked by on-device embeddings (nomic-local, default) or a remote OpenAI-compatible embedding model, with automatic keyword-match fallback.
  • MCP resources — readable context a server publishes by URI (coding standards, API schemas, records). Browse them with /resources and read one with /resources <uri>; the model gets matching read-only list_resources/read_resource tools automatically whenever a connected server publishes any, so you can just say "read the coding standards resource, then fix utils.py to match".

🏗️ Architecture

Tools are served over the Model Context Protocol (MCP), not called in-process — the agent is an MCP client that talks to a tool server over stdio:

+-----------------------------+
|          CLI / REPL         |
+-----------------------------+
               |
               v
+-----------------------------+
|          Agent loop         |
|  parse intent, call model,  |
|  approve, execute, persist  |
+-----------------------------+
               |
               v
+-----------------------------+
|          MCP client         |
|  built-in + custom servers  |
|  merged into one tool list. |
| "defer"-registered servers  |
| hold tools back for on-     |
| demand search_tools lookup  |
+-----------------------------+
               |
 stdio / SSE / streamable-http
               v
+-----------------------------+
|        MCP server(s)        |
+-----------------------------+
               |
               v
+-----------------------------+
|            Tools            |
|    read / write / edit /    |
|        search / shell       |
+-----------------------------+

Because tools are exposed over MCP, any MCP-compatible client — Claude Desktop, another agent framework, a different model entirely — can reach the exact same toolset, approval-preview logic, and path scoping. The reverse also holds: any additional MCP server — local (stdio) or remote (SSE / Streamable HTTP) — can be plugged into this agent, and its tools merge into the same list the model already sees —

omni --add-mcp-server "weather=python -m weather_mcp_server"     # local, stdio
omni --add-mcp-server "weather=https://example.com/mcp/sse"      # remote, SSE
omni "what's the forecast?"   # picked up automatically, every run from here on

Registrations are saved under the mcpServers key of ~/.omni-coder/omni-coder-settings.json, leaving any other key in that file untouched.

A value after name= starting with http:///https:// is treated as a remote server (SSE by default, append ,streamable_http for that transport instead); anything else is a local command spawned over stdio — it doesn't need to be -m-invokable, a standalone script's absolute path works too (e.g. "myserver=python C:/absolute/path/to/mcp_server.py").

Authenticated remote servers take a bearer token via a ,bearer=<token> suffix, which becomes an Authorization: Bearer header:

export DOCS_TOKEN="sk-..."
omni --add-mcp-server 'docs=https://example.com/mcp/sse,bearer=$DOCS_TOKEN'

Prefer that $VAR form over a literal token — headers and env values (both in the settings file and in --mcp-config JSON) are resolved from the environment at connect time, so only the variable name is written to disk, never the secret. Use single quotes so your shell doesn't expand the variable before this agent sees it. An unset variable is reported as a clear error instead of being sent as a literal $VAR.

Append ,defer (or pass --defer with --add-mcp-server) to keep a server's tools out of the model's default tool list — it discovers them on demand via search_tools, ranked semantically by default (pip install "omni-coder[local-embeddings]" for on-device embeddings, or point --embedding-model at a remote one instead; --embedding-model "" falls back to plain keyword matching). See the full README for details.

⚙️ Configuration

Point at any OpenAI-compatible host with --llm-host or the LLM_HOST env var. If it sits behind an authenticated proxy, set LLM_API_KEY as an environment variable rather than a CLI flag so the key doesn't end up in shell history. Seeing repeated retries in the terminal? That's usually a client-side timeout, not a dead server — raise it with --llm-timeout <seconds> (default 300).

🔗 Links

Source, full documentation, and issue tracker: https://github.com/HarryChen1995/omni-coder

📄 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

omni_coder-0.5.27.tar.gz (68.8 kB view details)

Uploaded Source

Built Distribution

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

omni_coder-0.5.27-py3-none-any.whl (60.8 kB view details)

Uploaded Python 3

File details

Details for the file omni_coder-0.5.27.tar.gz.

File metadata

  • Download URL: omni_coder-0.5.27.tar.gz
  • Upload date:
  • Size: 68.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for omni_coder-0.5.27.tar.gz
Algorithm Hash digest
SHA256 20dbfed4d1cfc8564f978a375ac64751695de90e130c617102975a716e486ea2
MD5 360986e7da2df8bb3b2d7274519f4c6e
BLAKE2b-256 4e041b01ee44ac6fdfee18215cc349846a53d3903ff7f51a675799538228ec61

See more details on using hashes here.

File details

Details for the file omni_coder-0.5.27-py3-none-any.whl.

File metadata

  • Download URL: omni_coder-0.5.27-py3-none-any.whl
  • Upload date:
  • Size: 60.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for omni_coder-0.5.27-py3-none-any.whl
Algorithm Hash digest
SHA256 fc118829cfbb9038387ce408bceaba5b236c0042cde8eac5af594f4bc0cc1824
MD5 d14c2183209a1c51abe957b9cadaef25
BLAKE2b-256 3759025af3051ed48f6e0740a802610b7d7f87cbfdf5f6fb818348a49b49a48a

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