Chatbots that follow your rules.
Describe a customer-facing bot in plain English and get one short YAML file. keelchat runs it with the steps, limits, guardrails and handoff enforced in code, not left to a prompt.
agent: support-assistant charter: > Help customers with orders and returns. Out of scope: legal advice. tools: [knowledge_search] flow: - greet_consent - form_fill: fields: - name: order_number ask: What is your order number? expect: An order number guardrails: {output: [pii, no_legal_advice]} handoff: {when: [user_request, max_reasks]}
How it works
From a sentence to a running bot in minutes.
No prompt engineering. You say what the bot is for; keelchat writes a file you can read, and the runtime does exactly what the file says.
Describe it
"Book dental appointments; hand emergencies to a person." A model writes the YAML and the build checks it.
Try it, change it
Chat with your bot in the browser. Ask for changes in plain words: "also ask for an email".
Run it yourself
Clone the repo, run ./setup.sh, and serve it on your site, WhatsApp, SMS, Slack or the phone.
Why keelchat
A prompt works in a demo. Production needs rules.
When a bot has a job to finish, a prompt-only bot is asked to remember the steps, count its own attempts and know when to stop. It does, most of the time. keelchat moves those decisions into code and leaves the model to read and phrase.
Use cases
Built for bots with a job to finish.
Each ships as an example you can run, read and change.
Support triage
Consent, the order number and what went wrong, answers from your help docs, a person when needed.
support_assistant.yaml
Bookings
Service, day and contact details, with open slots from your calendar through a Python tool.
booking_assistant.yaml
Applications and intake
Search, pick, a validated form, and a submit that runs only when the user confirms.
hiring_agent.yaml
Surveys
A 0-10 score and open questions as a conversation; scores computed in code, results over time.
customer_feedback.yaml
Questions about data
Answers from your tables with SQL and checked statistics, not guesses.
sales_analyst.yaml
Concierge
No fixed steps: it picks read-only tools each turn, within a budget counted in code.
concierge.yaml
For developers
YAML says what it does. Python adds what it can reach.
Tools, steps, guardrails and channels plug into one registry, so a new tool shows up in the schema, the console and the tests without wiring.
from keelchat import tool @tool("slot_search", timeout_s=3.0, retries=1) async def slot_search(service: str, day: str = "") -> dict[str, list[str]]: """Open appointment slots for a service, optionally on one day.""" return {"slots": await my_booking_api.free_slots(service, day)}
Type hints become the schema; the docstring is what the model reads. Allow it with tools: [slot_search].
uv run keelchat new package my_caps # tool, step, guardrail, test uv run keelchat build my_bot.yaml # validate and compile uv run keelchat evals generate my_bot.yaml uv run keelchat serve --port 8000 # API + console
Who it's for
One file the whole team can read.
Support and ops teams
Describe the bot in plain English, read back what it will do, ask for changes the same way. No YAML needed.
Developers
Add a tool, step, guardrail or channel as one decorated Python function, or connect an MCP server. Run many bots on one runtime.
Reviewers
Read one file per bot, see why each reply was chosen, and check the audit log, outcomes and model cost.
Not the right tool for a free-form assistant, multi-agent research workflows, or if you need stable APIs today: keelchat is alpha. How it compares with Parlant, Rasa, LangGraph and Botpress.
Get started
Run it on your machine in three commands.
Needs macOS, Linux or WSL and one model key; setup.sh installs the rest. Or run it all in Docker with
scripts/local.sh up.
git clone https://github.com/pnrajan/keelchat && cd keelchat ./setup.sh # installs what's missing, asks for your key scripts/try.sh # the console, with a sample bot