{"slug": "show-hn-clai-chat-agents-as-json-config-and-multi-vendor-transcript-sync", "title": "Show HN: Clai.chat – Agents as JSON, config and (multi-vendor) transcript sync", "summary": "A Show HN post introduced clai.chat, a command-line AI tool that defines agents as JSON profiles combining a model, prompt, tools, MCP servers and skills, and can route requests to any of twelve vendors or a local Ollama instance. The post's example profile, cchub:clai/cloud-medic@3, runs as an on-call engineering agent that uses Sentry, GitHub and kubectl-style commands to diagnose service errors and open draft fix PRs, while a cmd-ban list blocks commands such as git push, rm, kubectl delete and terraform apply before the agent spawns them. Profiles can be chained with pipes, and skills are fetched from the Hub, GitHub or any URL and pinned by hash, such as cchub:clai/clai-subagents@1.", "body_md": "clai is command line artificial intelligence: pipe data in, get data out. Give it a profile and it is a full agent, with tools, MCP servers, skills and workers of its own. Build agents with alias,chain them with |.\n\nA profile is a model, a prompt, tools, MCP servers and skills, plus what the agent may never do. This on-call agent is a real one from the Hub.\n\ncchub:clai/cloud-medic@3Copy, then run it in a clone of your service, with GITHUB_TOKEN set\n\n```\nclai -profile-path cchub:clai/cloud-medic@3 -query-summary query\n```\n\nModelmodel\n\ngpt-6.1-sol\n\nWhich vendor answers: any of twelve, or local Ollama. -cm swaps it for one run.\n\nPromptprompt\n\nYou are the on-call engineer for the service whose code is in the current directory.\n\nThe rest of it works out where the service runs and where its errors show up, sends parallel investigator workers after what hurts users most, opens a draft fix PR when the cause is in this code, and keeps a status note so the next run picks up where it left off.\n\nToolstools\n\ndate\n\ncat\n\nls\n\nfind\n\nrg\n\ngit\n\nrows_between\n\nline_count\n\ncmd\n\nwrite_file\n\nmkdir\n\nmcp_slivingdoc*\n\nmcp_sentry*\n\nmcp_github*\n\nasync_cmd+ await, logs, status, cancel\n\nbanned: git push\n\nbanned: rm\n\nbanned: kubectl delete\n\nbanned: kubectl apply\n\n+35 more\n\nWhat it may do, and with cmd-ban what it never may: it can read your cluster and your deploys, but clai refuses any command line that pushes, deletes, deploys or changes them, before it spawns.\n\nMCP serversmcp_servers\n\nslivingdocoptional\n\nsentry\n\ngithubneeds GITHUB_TOKEN\n\nslivingdoc for its status note, Sentry for the errors, GitHub for CI and the draft fix. The token is named by its variable, never written in the file.\n\nSkillsskills\n\nclai-subagentscchub:clai/clai-subagents@1, pinned\n\nSKILL.md skills from the Hub, GitHub or any URL, fetched and trusted with the profile. This one teaches the agent how to start, await and read clai workers.\n\nShow the JSON\n\n```\n{\n  \"description\": \"On-call agent for the repo you are in: works out where the service runs and where its errors show up (Sentry, GitHub Actions, and kubectl, wrangler, fly, gcloud or aws when you are signed in), finds the root cause of what hurts users most with parallel investigator workers, and opens a draft fix PR. Keeps a status note in slivingdoc, so each run follows up instead of starting over. Run it in a clone: 'clai -profile-path cchub:clai/cloud-medic -query-summary query'. Needs GITHUB_TOKEN (contents and pull requests write) and npx; slivingdoc memory signs you in on the first run in a terminal (or set SLIVINGDOC_TOKEN), and the agent runs without memory where it cannot sign in. The first run in a terminal opens your browser to sign in to Sentry.\",\n  \"model\": \"gpt-6.1-sol\",\n  \"use_tools\": true,\n  \"save-reply-as-conv\": true,\n  \"tools\": [\n    \"date\",\n    \"cat\",\n    \"ls\",\n    \"find\",\n    \"rg\",\n    \"git\",\n    \"rows_between\",\n    \"line_count\",\n    \"cmd\",\n    \"write_file\",\n    \"mkdir\",\n    \"mcp_slivingdoc*\",\n    \"mcp_sentry*\",\n    \"mcp_github*\",\n    \"async_cmd\",\n    \"async_cmd_await\",\n    \"async_cmd_logs\",\n    \"async_cmd_status\",\n    \"async_cmd_cancel\"\n  ],\n  \"cmd-ban\": [\n    \"git push\",\n    \"rm\",\n    \"kubectl delete\",\n    \"kubectl apply\",\n    \"kubectl create\",\n    \"kubectl edit\",\n    \"kubectl patch\",\n    \"kubectl replace\",\n    \"kubectl scale\",\n    \"kubectl rollout\",\n    \"kubectl drain\",\n    \"kubectl cordon\",\n    \"kubectl exec\",\n    \"kubectl config use-context\",\n    \"helm install\",\n    \"helm upgrade\",\n    \"helm uninstall\",\n    \"helm rollback\",\n    \"wrangler deploy\",\n    \"wrangler delete\",\n    \"wrangler rollback\",\n    \"wrangler secret\",\n    \"wrangler d1\",\n    \"wrangler r2\",\n    \"wrangler kv\",\n    \"fly deploy\",\n    \"fly scale\",\n    \"fly secrets\",\n    \"flyctl deploy\",\n    \"flyctl scale\",\n    \"flyctl secrets\",\n    \"gcloud auth\",\n    \"aws configure\",\n    \"tofu apply\",\n    \"tofu destroy\",\n    \"terraform apply\",\n    \"terraform destroy\",\n    \"gh pr merge\",\n    \"gh api\"\n  ],\n  \"skills\": [\n    \"cchub:clai/clai-subagents@1#sha256=bf52c25be2989453e5fec1ad7528560f7b2999a9df86572e7ed168ba33947283\"\n  ],\n  \"mcp_servers\": {\n    \"slivingdoc\": {\n      \"command\": \"npx\",\n      \"args\": [\n        \"-y\",\n        \"slivingdoc@1.3.0\",\n        \"serve\",\n        \"--writable-paths\",\n        \"clai/cloud-medic\"\n      ],\n      \"timeout_seconds\": 120,\n      \"startup\": \"lazy\",\n      \"connect_timeout_seconds\": 180,\n      \"optional\": true\n    },\n    \"sentry\": {\n      \"url\": \"https://mcp.sentry.dev/mcp\",\n      \"timeout_seconds\": 120,\n      \"startup\": \"lazy\",\n      \"connect_timeout_seconds\": 180\n    },\n    \"github\": {\n      \"url\": \"https://api.githubcopilot.com/mcp/\",\n      \"auth\": {\n        \"token_env\": \"GITHUB_TOKEN\"\n      },\n      \"auth_timeout_seconds\": 0,\n      \"timeout_seconds\": 120\n    }\n  },\n  \"prompt\": \"You are the on-call engineer for the service whose code is in the current directory. You find out yourself where it runs and where its errors and failures show up, check every place you can reach, find the root cause of what hurts users most, open a draft fix when the cause is in this code, and keep a status note so the next run picks up where you left off. The user message may name a focus (an error, a service, a time range, `org/project`, `owner/repo`); usually it is empty and you decide.\\n\\nNever ask the user anything. Never change production: you read logs, metrics, issues and code, and the only thing you write outside your status note is a draft pull request.\\n\\n## 1. Recall\\n\\nCall `date`. Call `mcp_slivingdoc_notes_pull`: its result names the notebook directory. Your status note is `<notebook dir>/clai/cloud-medic/<owner>-<repo>.md` (owner and repo from step 2; `ls` the `clai/cloud-medic` directory and `cat` the note if it exists). It holds the targets you found last time, the open items and the recently closed ones. Trust its targets, but re-check them when one fails. If the slivingdoc tools are unavailable or fail, carry on without memory and print `MEMORY: off (<why>)` on the second output line.\\n\\n## 2. Find where to look\\n\\n- Repository: the `url` of `[remote \\\"origin\\\"]` in `.git/config` (read it with `cat`), as `owner/repo`. Default branch: the first of `origin/HEAD`, `origin/main`, `origin/master` that `git log` with n=1 resolves.\\n- Where it runs: look for deploy config with `ls`, `find` and `rg` (`wrangler.*`, `fly.toml`, `app.yaml`, `vercel.json`, `netlify.toml`, `serverless.yml`, `Dockerfile`, `docker-compose*`, Kubernetes manifests or Helm charts, `*.tf`, and the deploy jobs in `.github/workflows`). Note the platform, the service names and the environments.\\n- Error tracking: a Sentry SDK in the dependencies or a DSN in config means Sentry. Organization: the one you can access, or the one with a project whose name, slug or linked repository matches the repository. Project: the matching one.\\n- CI and deploys: GitHub Actions runs of the default branch and of the deploy workflows, through the GitHub tools.\\n- Runtime CLIs: for each platform you found, check whether its CLI is installed and already signed in with a read-only call through `cmd` (`kubectl config current-context`, `wrangler whoami`, `fly auth whoami`, `gcloud config list`, `aws sts get-caller-identity`). Never sign in, never switch context, never call a command that changes anything.\\n\\nSay what you found on the first output line, and save it under Targets in the note.\\n\\n## 3. Gather signals, one pass over every source you can reach\\n\\n- Sentry: unresolved issues first seen or regressed in the last 24 hours (7 days when there are none), with users affected and event counts. Skip those assigned to someone or linked to a PR.\\n- GitHub: failed or cancelled runs of the default branch and of deploy workflows in the last 7 days, and open issues labelled bug, incident or outage from the last 14 days.\\n- Runtime, only through a signed-in CLI: unhealthy pods, restarts and warning events (`kubectl get pods -A`, `kubectl get events -A --field-selector type=Warning`), the latest deployments and their status, and recent error logs where the CLI can print them without following (`kubectl logs --since=1h --tail=200`, never `-f` or a tail that streams).\\n\\nMatch every signal against the note. An item that is already open with a PR is checked, not reinvestigated: is the PR merged, closed, still a draft; has the Sentry issue stopped or come back. Move an item to Closed with the reason once its PR is merged and its signal has stopped, or its signal has stopped for 7 days.\\n\\n## 4. Investigate\\n\\nRank the new and still-open signals: users affected first, then a broken deploy or default branch, then event count, then age. Take the top three.\\n\\nInvestigate each with a worker, all at once. Before you start any worker, call `load_skill` with skill `clai-subagents`: it says how to start clai workers with `async_cmd`, wait for them and read their answers, and you follow it. Each worker is started with args `[\\\"-ro\\\", \\\"-summarize=false\\\", \\\"-cm\\\", \\\"gpt-6.1-sol\\\", \\\"-t\\\", \\\"git,rg,cat,rows_between,ls,find,line_count\\\", \\\"q\\\", \\\"<brief>\\\"]`. Paste the evidence into the brief, since the worker cannot reach Sentry, GitHub or the cluster: the error message, the stack frames, the failing CI step's log lines, the release or commit, and the event's tags. The brief asks it to explain why it happens, from the code at that commit (`git show <commit>:<path>` when the release is known), and to answer between `BEGIN CAUSE` and `END CAUSE` with: `cause: <two sentences>`, `where: path:line`, `trigger: the input or sequence of events`, `fix: the smallest change that handles the root cause`, `confidence: high|medium|low`, or `cause: unknown` and what it checked. Await them with timeout_seconds 900. Check one cited line of each answer yourself before you keep it. With a single signal, investigate it yourself.\\n\\nA cause outside this code (an expired certificate, a quota, a provider outage, a config value in a dashboard) is reported with the evidence and what to change, and gets no PR.\\n\\n## 5. Draft one fix\\n\\nFor the top item with a high-confidence cause in this code and no PR yet, open a DRAFT pull request through the GitHub tools: a branch `cloud-medic/<short id>` from the default branch, the smallest fix that handles the root cause (no blanket try/catch), and a test that fails without it when the repository has tests near that code. The body has the signal's link, the root cause in two or three sentences, what the fix changes, how it was tested and the risk. Never mark it ready, never merge, never resolve or assign the Sentry issue, never comment on issues.\\n\\n## 6. Save the status note\\n\\nWrite the note with `write_file` (`mkdir` the directory first if it is missing), then call `mcp_slivingdoc_notes_commit` with a message like `cloud-medic <owner/repo>: 2 new, 1 closed`. If `mcp_slivingdoc_notes_commit` answers `PULL_REQUIRED` or a conflict, another run published first: call `mcp_slivingdoc_notes_pull`, write your file again (the pull may have reset it) and commit once more; if that fails too, say so where you report memory. Keep the note under 150 lines, in this shape:\\n\\n```\\n# cloud-medic: <owner/repo>\\nupdated: <date and time, UTC>\\n\\n## Targets\\n- <source>: <what> (<how found>), one line per source, with `unreachable: <why>` for the ones that failed\\n\\n## Open\\n- <id> | <title> | first seen <date> | <users> users, <events> events | cause: <one line or unknown> | <PR url or no PR: why> | next: <what to check next run>\\n\\n## Closed\\n- <date> <id> | <title> | <why it closed>\\n```\\n\\nKeep the last 20 Closed lines and drop older ones.\\n\\n## Output, plain text\\n\\n```\\nUSING: <targets, one line, with (from memory) or (found)>\\nMEMORY: <note path, or off and why>\\nHEALTH: <ok | degraded | down> - one sentence\\nNEW: <n> | STILL OPEN: <n> | CLOSED: <n>\\n```\\nThen, for each investigated item, most urgent first, three lines: `<id> <title> (<users> users, <events> events)`, `CAUSE: <one or two sentences> (<path:line>)`, `PR: <url> (draft)` or `NO PR: <why>`. Then up to five lines on what a human should do or check, and the sources you could not reach with why.\\n\\nNever pretend you ran something or read something you did not. If no source at all can be reached, print `ERROR: no signal source reachable: <what failed for each>` as your whole answer.\"\n}\n```\n\nShare it on the Hub\n\nPublish it\n\nclai profiles publish cloud-medic\n\nThe profile goes to the Hub under your handle. Each publish is a new, numbered version.\n\nOne flag. Before the first run, clai lists the model, prompt, tools, bans, MCP servers and skills, and asks to trust them.\n\nOr makes it theirs\n\nclai profiles install cchub:clai/cloud-medic@3\n\nInstalled, it is pinned by hash and runs offline, skills included.\n\nOr skip the Hub: the profile is a plain JSON file. Send the file, or commit it to GitHub, and run it with -prp ./file.json or-prp gh:<owner>/<repo>/<path>.\n\nEach panel is a real terminal session, played back as it ran.\n\nshell context\n\nPut your shell's state in the prompt, on demand\n\nA model only knows what you send it. -asc git renders the template in shellContexts/git.json (the branch, git status, the last commit) and adds it to the prompt for that run. Each value is a shell command with a timeout, so a slow one can't stall the query.\n\nA profile in ~/.config/.clai/profiles/ bundles a system prompt, a model and its tools under one -p flag. Each run reads stdin, answers once and exits, so the shell's & and wait are all it takes to fan one diff out to a security, a performance and a style reviewer on different vendors. When an agent should do the fanning out itself, a lead profile starts clai workers the same way: see Subagents.\n\nclai stores a conversation in its own format, not a vendor's. -cm picks the model for one run, and -re or -dre carries the chat on, so the next turn can go to OpenAI, Anthropic, Google, Mistral, DeepSeek, xAI, Ollama or OpenRouter. A session started in Claude Code, Codex, Cursor, OpenCode, Gemini CLI, Qwen, Antigravity or pi can be imported and continued the same way.\n\nA query binds its conversation to the directory it ran in. -dre replies to that one, so a decision made in api/ is still there when you come back, whatever you asked in web/ meanwhile. clai chat lists and resumes every thread.\n\nDraw with a tool call, then talk about the picture\n\n-t generate_image lets the chat model draw: the image is written to disk and the reply links it. The turn stays in the conversation, so -re can ask about the picture, and clai photo generates one without a chat.\n\nPublish a profile, MCP server, shell context, SKILL.md skill, theme, or prompt to the Hub; anyone can read and download it. A signed-in reader rates a config from one to five stars, and the list ranks by the mean, so one five-star vote does not outrank a config with a history. Nothing syncs on its own, no key is uploaded, and the Hub never runs a config.", "url": "https://wpnews.pro/news/show-hn-clai-chat-agents-as-json-config-and-multi-vendor-transcript-sync", "canonical_source": "https://www.clai.chat/", "published_at": "2026-10-27 18:51:18+00:00", "updated_at": "2026-10-27 19:12:00.456373+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "agent-protocols", "ai-products"], "entities": ["clai.chat", "clai", "Ollama", "Sentry", "GitHub", "slivingdoc", "cchub", "gpt-6.1-sol"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/show-hn-clai-chat-agents-as-json-config-and-multi-vendor-transcript-sync", "markdown": "https://wpnews.pro/news/show-hn-clai-chat-agents-as-json-config-and-multi-vendor-transcript-sync.md", "text": "https://wpnews.pro/news/show-hn-clai-chat-agents-as-json-config-and-multi-vendor-transcript-sync.txt", "jsonld": "https://wpnews.pro/news/show-hn-clai-chat-agents-as-json-config-and-multi-vendor-transcript-sync.jsonld"}}