Skip to main content

An intelligent agent for task automation and assistance

Project description

OnIt

OnIt — the AI is working on the given task and will deliver the results shortly.

OnIt is an intelligent agent framework for task automation and assistance. It is built on MCP (Model Context Protocol) for tool integration and supports the A2A (Agent-to-Agent) protocol for multi-agent communication. OnIt connects to LLMs via any OpenAI-compatible API (private vLLM servers or OpenRouter.ai) and orchestrates tasks through modular MCP servers.

Quick Guide

1. Install

pip install onit==0.1.2

Or from source:

git clone https://github.com/sibyl-oracles/onit.git
cd onit
pip install -e ".[all]" --upgrade

2. Configure

Set your LLM host and at least one API key:

# Option A: Private vLLM server
export ONIT_HOST=http://localhost:8000/v1

# Option B: OpenRouter.ai
export ONIT_HOST=https://openrouter.ai/api/v1
export OPENROUTER_API_KEY=sk-or-v1-your-key-here

Optional API keys for built-in tools:

export OLLAMA_API_KEY=your_key        # Web search. Best to enable this. Free rate limited.
export OPENWEATHER_API_KEY=your_key   # Weather data. Free.

Get your free API keys: Ollama | OpenWeatherMap

3. Run

onit

That's it. MCP servers start automatically, and you get an interactive terminal chat with tool access.

Other interfaces:

onit --web                          # Gradio web UI on port 9000
onit --gateway                      # Telegram bot gateway
onit --a2a                          # A2A server on port 9001
onit --client --task "your task"    # Send a task to an A2A server and print the answer

Configuration

All options can be set via CLI flags, environment variables, or a YAML config file:

onit --config configs/default.yaml

Example config (configs/default.yaml):

serving:
  host: https://openrouter.ai/api/v1
  host_key: sk-or-v1-your-key-here   # or set OPENROUTER_API_KEY env var
  model: google/gemini-2.5-pro
  think: true
  max_tokens: 262144

verbose: false
timeout: 600
# prompt_intro: "I am a helpful AI assistant. My name is OnIt."

web: false
web_port: 9000

mcp:
  servers:
    - name: PromptsMCPServer
      url: http://127.0.0.1:18200/sse
      enabled: true
    - name: ToolsMCPServer
      url: http://127.0.0.1:18201/sse
      enabled: true

The LLM provider is auto-detected from the host URL. If it contains openrouter.ai, the API key is read from host_key or OPENROUTER_API_KEY. All other hosts default to vLLM with no key required.

CLI Options

General:

Flag Description Default
--config Path to YAML configuration file configs/default.yaml
--host LLM serving host URL (overrides config and ONIT_HOST env var)
--model Model name (overrides serving.model in config)
--verbose Enable verbose logging false
--timeout Request timeout in seconds (-1 = none) 600
--template-path Path to custom prompt template YAML file
--prompt-intro Custom system prompt intro for the model "I am a helpful AI assistant. My name is OnIt."

Text UI:

Flag Description Default
--text-theme Text UI theme (white or dark) dark
--text-show-logs Show execution logs panel false

Web UI:

Flag Description Default
--web Launch Gradio web UI false
--web-port Gradio web UI port 9000

Telegram Gateway:

Flag Description Default
--gateway Run as a Telegram bot gateway (requires TELEGRAM_BOT_TOKEN env var) false

A2A (Agent-to-Agent):

Flag Description Default
--a2a Run as an A2A protocol server false
--a2a-port A2A server port 9001
--client, --a2a-client Client mode: send a task to a remote A2A server false
--a2a-host A2A server URL for client mode http://localhost:9001
--task, --a2a-task Task string for A2A loop or client mode
--file, --a2a-file File to upload to the A2A server with the task
--image, --a2a-image Image file to send for vision processing
--loop, --a2a-loop Enable A2A loop mode false
--period, --a2a-period Seconds between A2A loop iterations 10

MCP (Model Context Protocol):

Flag Description Default
--mcp-host Override the host/IP in all MCP server URLs (e.g. 192.168.1.100)
--mcp-sse URL of an external MCP tools server using SSE transport (can be repeated)

Features

Interactive Chat

Rich terminal UI with input history, theming, and execution logs. Press Enter or Ctrl+C to interrupt any running task.

Web UI

Gradio-based browser interface with file upload, copy buttons, and real-time polling:

onit --web --web-port 9000

Supports optional Google OAuth2 authentication — see docs/WEB_AUTHENTICATION.md.

MCP Tool Integration

MCP servers are started automatically. Tools are auto-discovered and available to the agent.

Server Description
PromptsMCPServer Prompt templates for instruction generation
ToolsMCPServer Web search, bash commands, file operations, and document tools

Connect to additional external MCP servers:

onit --mcp-sse http://localhost:8080/sse --mcp-sse http://192.168.1.50:9090/sse

Telegram Gateway

Chat with OnIt remotely from the Telegram mobile app using a Telegram bot.

Setup:

  1. Create a bot with BotFather on Telegram (/newbot) and copy the token.
  2. Set the token and start the gateway:
export TELEGRAM_BOT_TOKEN=your-bot-token-here
onit --gateway
  1. Open Telegram, find your bot, and send a message. OnIt will respond using the full agent with all its tools.

You can also send photos — the bot will pass them to the LLM for vision processing (if your model supports it). The photo caption is used as the prompt (defaults to "Describe this image." if no caption is provided).

Install the gateway dependency separately if not using [all]:

pip install "onit[gateway]"

A2A Protocol

Run OnIt as an A2A server so other agents can send tasks:

onit --a2a --a2a-port 9001

The agent card is available at http://localhost:9001/.well-known/agent.json.

Send a task via CLI:

onit --client --a2a-host http://192.168.86.101:9001 --task "what is the weather in Manila"

Send a task via Python (A2A SDK):

from a2a.client import ClientFactory, create_text_message_object
from a2a.types import Role
import asyncio

async def main():
    client = await ClientFactory.connect("http://localhost:9001")
    message = create_text_message_object(role=Role.user, content="What is the weather?")
    async for event in client.send_message(message):
        print(event)

asyncio.run(main())

Send a task with an image (VLM):

# Server
onit --a2a --host <ONIT_HOST> --model Qwen/Qwen3-VL-8B-Instruct

# Client
onit --client --task "are the rambutans ripe?" --a2a-image assets/rambutan_calamansi.jpg

Send an image task via Python (A2A SDK):

import asyncio, base64, os, uuid
from a2a.client import ClientFactory
from a2a.types import FilePart, FileWithBytes, Message, Part, Role, TextPart

async def main():
    image_path = "assets/rambutan_calamansi.jpg"
    with open(image_path, "rb") as f:
        image_data = base64.b64encode(f.read()).decode("utf-8")

    message = Message(
        role=Role.user,
        message_id=str(uuid.uuid4()),
        parts=[
            Part(root=TextPart(text="Are the rambutans ripe enough to be eaten?")),
            Part(root=FilePart(file=FileWithBytes(
                bytes=image_data,
                mime_type="image/jpeg",
                name=os.path.basename(image_path),
            ))),
        ],
    )

    client = await ClientFactory.connect("http://localhost:9001")
    async for event in client.send_message(message):
        print(event)

asyncio.run(main())

Loop Mode

Repeat a task on a configurable timer (useful for monitoring):

onit --a2a-loop --task "Check the weather in Manila" --a2a-period 60

Custom Prompt Templates

Create a YAML file with an instruction_template field:

# my_template.yaml
instruction_template: |
  You are a research assistant. Think step by step.

  <task>
  {task}
  </task>

  Save all results to `{data_path}`.
  Session ID: {session_id}

Then use it:

onit --template-path my_template.yaml

See example templates in src/mcp/prompts/prompt_templates/.

Model Serving

Private vLLM

Serve models locally with vLLM:

CUDA_VISIBLE_DEVICES=0,1,2,3 vllm serve Qwen/Qwen3-30B-A3B-Instruct-2507 \
  --max-model-len 262144 --port 8000 \
  --enable-auto-tool-choice --tool-call-parser qwen3_xml \
  --reasoning-parser qwen3 --tensor-parallel-size 4 \
  --chat-template-content-format string
export ONIT_HOST=http://localhost:8000/v1
onit

OpenRouter.ai

OpenRouter gives access to models from OpenAI, Google, Meta, Anthropic, and others through a single API.

export OPENROUTER_API_KEY=sk-or-v1-your-key-here
export ONIT_HOST=https://openrouter.ai/api/v1
onit

Browse available models at openrouter.ai/models and use the model ID (e.g. google/gemini-2.5-pro, meta-llama/llama-4-maverick, openai/gpt-4.1).

Design Philosophy

  • Portable — Minimal dependencies. Deployable from embedded devices to GPU servers.
  • Modular — Clear separation of AI logic, tasks, and UIs. Easily extendable with new MCP servers.
  • Scalable — From a single tool to complex multi-server setups.
  • Redundant — Multiple ways to solve a problem. Let the AI decide the optimal path.
  • Configurable — Edit a YAML file and you are good to go.
  • Responsive — Safety routines can interrupt running tasks at any time.

Architecture

┌─────────────────────────────────────────────────────┐
│                       onit CLI                      │
│                  (argparse + YAML config)           │
└────────────────────────┬────────────────────────────┘
                         │
                         ▼
┌─────────────────────────────────────────────────────┐
│                     OnIt (src/onit.py)              │
│                                                     │
│  ┌─────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐  │
│  │ ChatUI  │ │ WebChatUI│ │ Telegram │ │ A2A      │  │
│  │(terminal│ │ (Gradio) │ │ Gateway  │ │ Server   │  │
│  └────┬────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘  │
│       └─────────┬─┘            │             │       │
│                 ▼                 ▼                 │
│          client_to_agent()  /  process_task()       │
│                 │                                   │
│                 ▼                                   │
│        MCP Prompt Engineering (FastMCP)             │
│                 │                                   │
│                 ▼                                   │
│         chat() ◄──── Tool Registry                  │
│    (vLLM / OpenRouter)  (auto-discovered)           │
└─────────────────────────────────────────────────────┘
                         │
            ┌────────────┼────────────┐
            ▼            ▼            ▼
     ┌───────────┐ ┌──────────┐ ┌──────────┐
     │  Prompts  │ │  Tools   │ │ External │  ...
     │ MCP Server│ │MCP Server│ │MCP (SSE) │
     └───────────┘ └──────────┘ └──────────┘

Project Structure

onit/
├── configs/
│   └── default.yaml            # Agent configuration
├── pyproject.toml              # Package configuration
├── src/
│   ├── cli.py                  # CLI entry point
│   ├── onit.py                 # Core agent class
│   ├── lib/
│   │   ├── text.py             # Text utilities
│   │   └── tools.py            # MCP tool discovery
│   ├── mcp/
│   │   ├── prompts/            # Prompt engineering (FastMCP)
│   │   └── servers/            # MCP servers (tools, web, bash, filesystem)
│   ├── model/
│   │   └── serving/
│   │       └── chat.py         # LLM interface (vLLM + OpenRouter)
│   ├── ui/
│   │   ├── text.py             # Rich terminal UI
│   │   ├── web.py              # Gradio web UI
│   │   └── telegram.py         # Telegram bot gateway
│   └── test/                   # Test suite (pytest)

Documentation

License

Apache License 2.0. See LICENSE for details.

Project details


Download files

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

Source Distribution

onit-0.1.2.tar.gz (111.9 kB view details)

Uploaded Source

Built Distribution

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

onit-0.1.2-py3-none-any.whl (132.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: onit-0.1.2.tar.gz
  • Upload date:
  • Size: 111.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for onit-0.1.2.tar.gz
Algorithm Hash digest
SHA256 59faed21a5495b679861f662fc812e5c6bb50c69faa862cd7b6e01f64ffdc363
MD5 1f2d6ba020d8b09dc4cf338f9abc2a10
BLAKE2b-256 8e6914ecc2e557a22d7250d4f59147b837f213b1eacd294006bdc4da27357c04

See more details on using hashes here.

Provenance

The following attestation bundles were made for onit-0.1.2.tar.gz:

Publisher: publish.yml on sibyl-oracles/onit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

  • Download URL: onit-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 132.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for onit-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 3a3610819cce429d13cbe72606259e94a8fd7950e52bd7e0b414cfd7fed9b687
MD5 3f1f3208858b93e1fdeddda4b2c26e75
BLAKE2b-256 173d50c37b7442ff17dc5b0ed797d105cb7b5d947c7028f8ca6c9886d490d8d6

See more details on using hashes here.

Provenance

The following attestation bundles were made for onit-0.1.2-py3-none-any.whl:

Publisher: publish.yml on sibyl-oracles/onit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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