Miii is a privacy-first, local AI assistant that pairs fast streaming chat with pluggable skills, semantic tool routing, and optional live web search — all running on your own machine.
Traditional assistants ship every prompt to the cloud. Miii keeps your messages local while still giving you the flexibility of agentic tools, document-aware answers, and a modern UI.
- ⚡ Streamlined UX — browser chat backed by a local server and skills.
- 🔌 Composable intelligence — define JSON skills, chain LangGraph actions, and optionally pull live Tavily search results.
- 🧠 Document-aware context — Chroma-based RAG per conversation with Ollama embeddings.
- 📎 File attachments — attach text, code, or PDF files straight into the composer for one-off context.
- 🛠️ Developer-friendly — streaming NDJSON, model picker, slash commands, and a CLI that installs globally.
npm install
npm run devThe web UI launches at http://localhost:3000, and you can build your prompts, enable tools, and see streaming Markdown responses instantly.
curl -fsSL --proto '=https' --tlsv1.2 https://raw.githubusercontent.com/akshaymaru-61/miii/main/scripts/install.sh | bashAfter installation you can run miii web or miii help from any terminal. Add ~/.npm-global/bin (or wherever your npm global bin lives) to PATH if commands are missing.
User Input
│
▼
Next.js App Router
│
▼
/api/chat (streaming NDJSON)
│
▼
LangGraph Agent ────┬──► Ollama streaming (no tools)
│
└──► Agent loop when tools / web search active
│
├── Custom skills (`customTools/*.json` → LangChain)
└── Tavily web search (live results)
Response streams back to the React renderer.
Built with Next.js App Router, React 19, Tailwind CSS 4, LangGraph, and Ollama for the local models.
Miii uses LangGraph to decide when to run a tool (custom skill, web search) and when to stream directly from Ollama, giving you the best of both speed and flexibility.
Drop JSON tool definitions into customTools/ and the UI will treat them as LangChain tools. Extend lib/custom-tools.ts to hook in actual execution logic if you need real-world actions.
Example definition:
{
"name": "my_skill",
"description": "Explain how this skill works",
"createdAt": "2025-01-01T00:00:00.000Z"
}Add, edit, or delete tools via the slash menu (/tools) or the dedicated UI panels.
Flip on Tavily web search from the UI (or set TAVILY_API_KEY in env). Miii will pull live search snippets before composing an answer so you can stay current despite model cutoffs. Keys stay in the browser unless you share them server-side.
Attach text, code, or PDF files from the composer (the paperclip button). Contents are parsed client-side and sent inline with your next message, so you can drop in a snippet or document without a full RAG ingest. Attachment chips show file names, flag truncated files, and can be removed before sending.
Switch models on the fly via the picker in the browser. The composer supports / commands for clearing chats, managing tools, toggling web search, and more.
The browser client talks to the backend, persists conversations, and streams Markdown (GFM) token-by-token, including tables, code blocks, and lists.
| Variable | Meaning |
|---|---|
OLLAMA_BASE_URL |
Override Ollama server URL (defaults to local ollama serve). |
TAVILY_API_KEY |
Tavily key for server-side web search. Browser keys stay client-local. |
CHROMA_URL |
Chroma HTTP API (http://127.0.0.1:8000 by default). |
CHROMA_API_KEY, CHROMA_TENANT, CHROMA_DATABASE |
Optional Chroma defaults. |
OLLAMA_EMBED_MODEL |
Embedding model for RAG (defaults to nomic-embed-text). |
Store overrides in .env.local or configure through the web UI (Chroma and Tavily headers persist in browser local storage).
The repo bundles chromadb as a dependency. Start the Chroma service from the project root:
npm run chromaThis runs node_modules/.bin/chroma on port 8000. You can also use npx chroma run or point to a remote server with CHROMA_URL.
Send these from the composer for quick actions:
| Command | Action |
|---|---|
/clear |
Clear current conversation messages. |
/clear all |
Reset the browser to default chats. |
/tools |
Open Add Tool dialog (custom skills). |
/delete-tool |
Open Delete Tool dialog. |
/web |
Open Tavily key dialog. |
- Create or edit a JSON file under
customTools/withname,description, and metadata. - Update
lib/custom-tools.tsif the tool needs to call real code (e.g., shelling out, querying local data, etc.). - Navigate to the Tools menu in the UI or use
/toolsto activate it for the agent loop.
Custom skills behave like LangChain tools and can be combined with LangGraph reasoning for rich workflows.
We welcome contributors!
- Fork the repo and open a pull request against
main. - Run
npm run lintandnpm run test(if tests exist) before submitting. - Propose new features (new tools, UI improvements, docs updates) by opening an issue first if the scope is large.
- Help triage issues, answer questions, or write docs — every contribution is valuable.
| Path | Role |
|---|---|
app/api/chat |
Streaming chat backbone (Ollama + LangGraph). |
app/api/models |
Lists local Ollama models. |
app/api/ollama/pull |
Streams ollama pull progress. |
app/api/rag/collections |
List Chroma collections. |
app/api/rag/ingest |
Ingest text/files for RAG. |
app/api/custom-tools |
CRUD for JSON skills. |
lib/chat-graph.ts |
LangGraph agent setup. |
lib/chat-tools.ts |
Tool merging logic. |
lib/custom-tools.ts |
Tool definitions loader. |
lib/rag-chroma.ts |
Chroma client helpers. |
lib/tavily-tool.ts |
Tavily web search integration. |
lib/attachments.ts |
Parse attached text/code/PDF files for the composer. |
lib/messages.ts |
System prompts. |
lib/conversation-storage.ts |
Local storage helpers. |
customTools/ |
JSON skill definitions. |
components/chat/ |
Browser chat client. |
- Persistent skill workers (real execution logic behind custom tools).
- ChromaDB semantic skill retrieval (auto tool selection via embeddings).
- Document ingestion (PDFs, notes, and local files) through the UI.
- Multi-turn memory across conversations.
- Docker Compose for single-command bootstrapping.
- Ask questions in the repository discussions or open an issue with the
supportlabel. - Bring feature ideas and bug reports to GitHub — we track them in
Issues.
Miii is open source under the MIT License.
