The closing stage. mcpd now hosts the Stage 5 SPA, the Docker image
bundles the build artifact, a smoke test exercises the personality
HTTP surface end-to-end, and the user-facing docs spell out the
mental model.
mcpd:
- Add @fastify/static dep.
- New routes/web-ui.ts: registers /ui/* against a static bundle. Looks
for the bundle at $MCPD_WEB_ROOT, then /usr/share/mcpd/web (the
Docker image path), then a dev-tree fallback. Logs and skips
cleanly if missing — API-only deploys keep working.
- SPA fallback: any /ui/<path> that doesn't match a file falls through
to index.html so direct hits to react-router URLs work.
- /ui/* falls through to `kind: skip` in mapUrlToPermission, so the
static assets are served unauthenticated. Each API call from the
SPA still carries the bearer token.
Deploy:
- Dockerfile.mcpd builds the @mcpctl/web bundle in the same builder
stage and copies dist/ to /usr/share/mcpd/web in the runtime image.
Smoke (personality.smoke.test.ts):
- Live mcpd flow: create secret/llm/agent/personality, attach an
agent-direct prompt, verify the binding listing, reject double-
attach (409) + foreign-agent prompt (400), set defaultPersonality
by name, detach + delete cleanup.
Docs:
- New docs/personalities.md: VLAN-on-ethernet model, system-block
ordering table, three prompt scopes, CLI walkthrough, web UI
walkthrough, full API surface, RBAC notes.
- agents.md and chat.md cross-link.
- README's Agents section gains a Personalities subsection.
Test count after Stage 6:
mcpd: 801/801 cli: 430/430
web: 7/7 db: 58/62 (4 pre-existing)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes the agents feature.
Smoke tests (run via `pnpm test:smoke` against a live mcpd at
$MCPD_URL, default https://mcpctl.ad.itaz.eu):
* tests/smoke/agent.smoke.test.ts — full CRUD round-trip:
create secret + Llm + agent with sampling defaults; `get agents`
surfaces it; `get agent foo -o yaml | apply -f` round-trips
identically; create + list a thread via the HTTP API; agent delete
leaves Llm + secret intact (Restrict + SetNull as designed). Self-
skips with a warning when /healthz is unreachable.
* tests/smoke/agent-chat.smoke.test.ts — gated on
MCPCTL_SMOKE_LLM_URL + MCPCTL_SMOKE_LLM_KEY. Provisions secret +
Llm + agent against a real upstream, runs `mcpctl chat -m … --no-
stream` (asserts a reply lands), then runs the streaming default
(asserts text on stdout + `(thread: …)` on stderr). The fast path
for verifying the in-cluster qwen3-thinking deployment:
MCPCTL_SMOKE_LLM_URL=http://litellm.nvidia-nim.svc.cluster.local:4000/v1 \
MCPCTL_SMOKE_LLM_MODEL=qwen3-thinking \
MCPCTL_SMOKE_LLM_KEY=$(pulumi config get --stack homelab \
secrets:litellmMcpctlGatewayToken) \
pnpm test:smoke
Docs:
* README.md — new "Agents" section under Resources with the
qwen3-thinking quickstart and links to docs/agents.md and
docs/chat.md. Adds llm + agent rows to the resources table.
* docs/agents.md (new) — full reference: data model, chat-parameter
table, HTTP API, RBAC mapping, tool-use loop semantics, yaml
round-trip shorthand, the kubernetes-deployment wiring recipe,
and a troubleshooting section (namespace collision, llm-in-use,
pending-row recovery, Anthropic-tool limitation).
* docs/chat.md (new) — user-facing `mcpctl chat` walkthrough:
modes, per-call flags, slash-commands, threads, and a
troubleshooting section.
* CLAUDE.md — adds a "Resource types" cheatsheet with one-line
pointers to each, including the new `agent` row that links to
the docs.
All suites still green: mcpd 759/759, mcplocal 715/715, cli 430/430.
Smoke tests typecheck and self-skip when no live mcpd is reachable.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Gitea's auto-generated .repo file contains internal IPs. Use a manual
repo file with the public mysources.co.uk baseurl instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrite the Plugin System section to make the extends/inheritance
mechanism clear — show that default extends gate + content-pipeline,
explain hook inheritance and conflict resolution rules.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Section 4 now uses --from-template instead of manual --docker-image
- Declarative YAML example uses fromTemplate + envFrom secretRef
- Backup section updated to git-based commands (was old JSON bundle)
- Consistent server naming (my-grafana from template, not bare grafana)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Rewrite README Content Pipeline section as Plugin System section
documenting built-in plugins (default, gate, content-pipeline),
plugin hooks, and the relationship between gating and proxyModel
- Update all README examples to use --proxy-model instead of --gated
- Add unit tests: proxyModel normalization in JSON/YAML output (4 tests),
Plugin Config section in describe output (2 tests)
- Add smoke tests: yaml/json output shows resolved proxyModel without
gated field, round-trip compatibility (4 tests)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add warmup() to LlmProvider interface for eager subprocess startup
- ManagedVllmProvider.warmup() starts vLLM in background on project load
- ProviderRegistry.warmupAll() triggers all managed providers
- NamedProvider proxies warmup() to inner provider
- paginate stage generates LLM-powered descriptive page titles when
available, cached by content hash, falls back to generic "Page N"
- project-mcp-endpoint calls warmupAll() on router creation so vLLM
is loading while the session initializes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
MCP server containers are managed by and proxied through mcpd,
not directly accessible. Updated diagram to show containers
nested inside mcpd boundary with explanation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comprehensive MCP server management with kubectl-style CLI.
Key features in this release:
- Declarative YAML apply/get round-trip with project cloning support
- Gated sessions with prompt intelligence for Claude
- Interactive MCP console with traffic inspector
- Persistent STDIO connections for containerized servers
- RBAC with name-scoped bindings
- Shell completions (fish + bash) auto-generated
- Rate-limit retry with exponential backoff in apply
- Project-scoped prompt management
- Credential scrubbing from git history
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>