Open source Python · Apache-2.0 · any LLM

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.

support_assistant.yaml
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]}
Live chat ● running
My parcel arrived broken
Sorry about that. What is your order number?
no idea, sorry
It's on your confirmation email, e.g. ORD-12345.
re-ask 2 of 2 · counted in code

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.

A dental booking bot described in two sentences, read back in plain words, then a test chat where an emergency is handed to a person

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.

A prompt-only bot
With keelchat
Skips a question, or moves on with an answer it couldn't use
Steps are code.A form isn't done until every field passes its check.
Asks the same thing forever, or gives up at random
Counting lives in code.Re-asks and budgets have limits; at the limit, a person takes over with the context.
Promises a refund, gives legal advice, leaks a phone number
Rules and guardrails.Plain-language rules where they fit; input and output checks on every reply.
Calls any tool with anything the model makes up
One tool gateway.An allow list per bot, timeouts, a circuit breaker; tool output is untrusted.
A prompt edit changes every live chat, unreviewed
A file you can review.Versioned with rollback; each conversation stays on its version.
"It seemed fine when I tried it"
Tested from the policy.Test sets generated from the YAML; a stronger model reviews trial chats and proposes fixes.

Use cases

Built for bots with a job to finish.

Each ships as an example you can run, read and change.

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.

my_caps/tools.py
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].

terminal
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

Adding a capability · Architecture · Every YAML key

Anthropic · OpenAI · Gemini · Bedrock · OllamaMCP tools in and outFastAPI HTTP API Web widget · WhatsApp · SMS · Slack · voiceRedis · Postgres · in-memoryEvals and an LLM judge

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.

terminal
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