Chat directly with a Project (no Agent needed): its Prompts become the system context, its MCP-server tools are callable, its llmProvider/llmModel drive the LLM, and (opt-in) the model can read secret values. History is saved inside the project, attributed per user, resumable, and deletable (RBAC-permitting) — "use it like Claude, scoped to the project". Backend (reuses the agent-chat orchestrator): - ChatThread is now agent-XOR-project (schema + migration + CHECK constraint); new listThreadsByProject / deleteThread on the repo. - ChatService: prepareProjectContext (project prompt + Prompts by priority, llm from llmProvider with llmModel override, project tools), shared runChatLoop/runChatStreamLoop, project thread CRUD with owner enforcement (404-not-403 on foreign threads), admin-override delete. - Gated get_secret virtual tool: offered only with --allow-secrets AND the caller's view:secrets; resolves via SecretService, never routes to a server. - routes/project-chat.ts (chat SSE+non-stream, threads create/list/delete); RBAC run:projects:<name>. CLI: - `mcpctl chat --project <name>` (+ --allow-secrets), one-shot/REPL/resume. - REPL /threads, /resume <id>, /delete <id>; project-aware header + /tools. - `mcpctl get threads --project <name>`, `mcpctl delete thread <id> --project`. - completions regenerated (--project completes project names). Tests: 8 new project-chat unit tests; full mcpd (945) + CLI (508) green; schema validated against Postgres. Docs: docs/chat.md "Project chat" section. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
6.1 KiB
mcpctl chat
Open an interactive chat session with an Agent, or send a single message
in one shot. See agents.md for what an Agent is and how to
create one.
Modes
mcpctl chat <agent> # interactive REPL, new thread
mcpctl chat <agent> --thread <id> # interactive REPL, resume thread
mcpctl chat <agent> -m "hi" # one-shot, prints reply, no REPL
mcpctl chat <agent> -m "hi" --no-stream # one-shot, single JSON response (no SSE)
Streaming is on by default. Text deltas land on stdout as they arrive; tool calls and tool results print to stderr in dim brackets so the chat output stays clean.
Project chat
Chat directly with a project — no Agent needed. The session sees the
project's Prompts as system context, can call every tool from the project's
attached MCP servers, and uses the project's own LLM (llmProvider, with
llmModel as an optional served-model override).
mcpctl chat --project sre # REPL scoped to project "sre"
mcpctl chat --project sre -m "what alerts fired overnight?"
mcpctl chat --project sre --thread <id> # resume a past conversation
- Prompts + tools come from the project and stay current — anything you add to the project later shows up automatically in the next turn.
- LLM: set it once with
mcpctl patch project sre llmProvider=<llm-name>(and optionallyllmModel=<served-model>). Chat errors clearly if unset. - History is saved inside the project, attributed to you. List and resume:
Delete one you own (admins with
mcpctl get threads --project sre # your threads for this project mcpctl chat --project sre --thread <id>delete:projectscan delete anyone's):mcpctl delete thread <id> --project sre
Reading secrets (--allow-secrets)
By default the model cannot read secret values — it only benefits from them
indirectly (the project's tools run authenticated). Opt in with
--allow-secrets to expose a get_secret tool the model can call:
mcpctl chat --project sre --allow-secrets
This is gated: it requires the flag and your view:secrets permission,
and it is off by default. Secret values the model reads land in the chat
context and thread history, so use it deliberately.
RBAC: project chat and its threads route through run:projects:<name>.
Per-call flags
All optional. They override the agent's defaultParams for this session
only — use the in-REPL /save slash-command to persist the current set
back to the agent.
--system <text> # replace agent.systemPrompt for this session
--system-file <path> # read --system text from a file
--system-append <text> # append to the agent system block (after project Prompts)
--personality <name> # apply a personality overlay for this turn
# (additive — see docs/personalities.md)
--temperature <n> # 0..2
--top-p <n> # 0..1
--top-k <n> # integer; Anthropic-only, OpenAI ignores
--max-tokens <n> # cap on assistant tokens
--seed <n> # reproducibility (provider-dependent)
--stop <text> # stop sequence (repeatable, up to 4)
--allow-tool <name> # repeat to allowlist project MCP tools
--extra <key=value> # provider-specific knob (repeatable)
--no-stream # disable SSE; single JSON response
--extra is the LiteLLM-style escape hatch: pass anything the underlying
adapter understands. Numeric values are auto-parsed (--extra repetition_penalty=1.1); strings stay strings.
In-REPL slash-commands
/set KEY VALUE adjust an override for the rest of the session
(temperature, top-p, top-k, max-tokens, seed, stop,
or any provider-specific knob — unknown keys go
into `extra`)
/system <text> set systemAppend for this turn onward (empty = clear)
/tools list MCP servers the agent can call as tools
/clear start a fresh thread (same agent)
/save PATCH agent.defaultParams = current overrides
(systemOverride / systemAppend are NOT persisted)
/quit, /exit leave the REPL (Ctrl-D works too)
Threads
Threads persist server-side. To resume:
mcpctl get threads --agent reviewer
mcpctl chat reviewer --thread <id>
A mcpctl get thread <id> reads the message log:
mcpctl get thread c0abc… -o yaml
Examples
Quick gut-check on a deploy:
$ mcpctl chat reviewer -m "is fulldeploy.sh safe to run on the current branch?"
Yes — I checked: tests are green on commit 727e7d6 and there's no
in-flight migration. The k8s context is worker0-k8s0 (production); confirm
that's intended before running.
(thread: cm9k…)
Resuming with overrides:
$ mcpctl chat deployer --thread cm9k… --temperature 0.0 --max-tokens 256
> walk me through what changed since the last deploy
…
Pinning sampling defaults to the agent:
$ mcpctl chat deployer --temperature 0.0 --max-tokens 8000
> /save
(saved current overrides as agent.defaultParams)
> /quit
Troubleshooting
-
No agents appear in
tools/list— check the agent has a project attach (mcpctl describe agent <name>). The mcplocal plugin only exposes agents on their attached project's session. -
Tool calls fail with
Project not found— the agent has no project attach. Either attach it (mcpctl edit agent <name>and set the project field), or expect text-only chat. -
Anthropic agents can't call tools — known limitation; the Anthropic adapter doesn't translate OpenAI tool format yet. Use LiteLLM or a direct OpenAI-compatible provider for tool-using agents until the translator ships.
-
mcpctl chat <agent>returns 404 — the agent name doesn't resolve.mcpctl get agentsto confirm spelling. -
REPL feels stuck — agent tool calls can take minutes (e.g. running a Grafana query). Watch stderr for
[tool_call: …]/[tool_result: …]brackets; those tell you the loop is alive.