Commit Graph

188 Commits

Author SHA1 Message Date
Michal
0427d7dc1a fix: correct architecture diagram in README
Some checks failed
CI / lint (push) Has been cancelled
CI / typecheck (push) Has been cancelled
CI / test (push) Has been cancelled
CI / build (push) Has been cancelled
CI / package (push) Has been cancelled
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>
2026-02-27 17:12:29 +00:00
Michal
69867bd47a feat: mcpctl v0.0.1 — first public release
Some checks are pending
CI / lint (push) Waiting to run
CI / typecheck (push) Waiting to run
CI / test (push) Waiting to run
CI / build (push) Blocked by required conditions
CI / package (push) Blocked by required conditions
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>
2026-02-27 17:05:05 +00:00
Michal
414a8d3774 fix: stub react-devtools-core for bun compile
Ink statically imports react-devtools-core (only used when DEV=true).
With --external, bun compile leaves a runtime require that fails in the
standalone binary. Instead, provide a no-op stub that bun bundles inline.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 00:06:31 +00:00
59f0c06b91 Merge pull request 'feat: interactive MCP console (mcpctl console)' (#46) from feat/mcp-console into main 2026-02-25 23:57:41 +00:00
Michal
a59d2237b9 feat: interactive MCP console (mcpctl console <project>)
Ink-based TUI that shows exactly what an LLM sees through MCP.
Browse tools/resources/prompts, execute them, and see raw JSON-RPC
traffic in a protocol log. Supports gated session flow with
begin_session, raw JSON-RPC input, and session reconnect.

- McpSession class wrapping HTTP transport with typed methods
- 12 React/Ink components (header, protocol-log, menu, tool/resource/prompt views, etc.)
- 21 unit tests for McpSession against a mock MCP server
- Fish + Bash completions with project name argument
- bun compile with --external react-devtools-core

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 23:56:23 +00:00
Michal
d4aa677bfc fix: bootstrap system user before system project (FK constraint)
The system project needs a valid ownerId that references an existing user.
Create a system@mcpctl.local user via upsert before creating the project.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 23:27:59 +00:00
Michal
d712d718db fix: add gated field to project repository create type signature
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 23:24:17 +00:00
b54307e7df Merge pull request 'feat: gated project experience & prompt intelligence' (#45) from feat/gated-prompt-intelligence into main 2026-02-25 23:23:08 +00:00
Michal
ecc9c48597 feat: gated project experience & prompt intelligence
Implements the full gated session flow and prompt intelligence system:

- Prisma schema: add gated, priority, summary, chapters, linkTarget fields
- Session gate: state machine (gated → begin_session → ungated) with LLM-powered
  tool selection based on prompt index
- Tag matcher: intelligent prompt-to-tool matching with project/server/action tags
- LLM selector: tiered provider selection (fast for gating, heavy for complex tasks)
- Link resolver: cross-project MCP resource references (project/server:uri format)
- Prompt summary service: LLM-generated summaries and chapter extraction
- System project bootstrap: ensures default project exists on startup
- Structural link health checks: enrichWithLinkStatus on prompt GET endpoints
- CLI: create prompt --priority/--link, create project --gated/--no-gated,
  describe project shows prompts section, get prompts shows PRI/LINK/STATUS
- Apply/edit: priority, linkTarget, gated fields supported
- Shell completions: fish updated with new flags
- 1,253 tests passing across all packages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 23:22:42 +00:00
3782bcf9d7 Merge pull request 'fix: per-provider health checks in status display' (#44) from fix/per-provider-health-check into main 2026-02-25 02:25:28 +00:00
Michal
50ffa115ca fix: per-provider health checks in /llm/providers and status display
The /llm/providers endpoint now runs isAvailable() on each provider in
parallel and returns health status per provider. The status command shows
✓/✗ per provider based on actual availability, not just the fast tier.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 02:25:06 +00:00
1c81cb3548 Merge pull request 'feat: tiered LLM providers (fast/heavy)' (#43) from feat/tiered-llm-providers into main 2026-02-25 02:16:29 +00:00
Michal
d2be0d7198 feat: tiered LLM providers (fast/heavy) with multi-provider config
Adds tier-based LLM routing so fast local models (vLLM, Ollama) handle
structured tasks while cloud models (Gemini, Anthropic) are reserved for
heavy reasoning. Single-provider configs continue to work via fallback.

- Tier type + ProviderRegistry with assignTier/getProvider/fallback chain
- Multi-provider config format: { providers: [{ name, type, tier, ... }] }
- NamedProvider wrapper for multiple instances of same provider type
- Setup wizard: Simple (legacy) / Advanced (fast+heavy tiers) modes
- Status display: tiered view with /llm/providers endpoint
- Call sites use getProvider('fast') instead of getActive()
- Full backward compatibility with existing single-provider configs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 02:16:08 +00:00
Michal
7b5a658d9b fix: cache LLM health check result for 10 minutes
Avoids burning tokens on every `mcpctl status` call. The /llm/health
endpoint now caches successful results for 10min, errors for 1min.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 01:39:15 +00:00
Michal
637bf3d112 fix: warmup ACP subprocess eagerly to avoid 30s cold-start on status
The pool refactor made ACP client creation lazy, causing the first
/llm/health call to spawn + initialize + prompt Gemini in one request
(30s+). Now warmup() eagerly starts the subprocess on mcplocal boot.
Also fetch models in parallel with LLM health check.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 01:37:30 +00:00
5099ee1f88 Merge pull request 'feat: per-project LLM models, ACP session pool, smart pagination tests' (#42) from feat/per-project-llm-pagination-tests into main 2026-02-25 01:29:56 +00:00
Michal
61a07024e9 feat: per-project LLM models, ACP session pool, smart pagination tests
- ACP session pool with per-model subprocesses and 8h idle eviction
- Per-project LLM config: local override → mcpd recommendation → global default
- Model override support in ResponsePaginator
- /llm/models endpoint + available models in mcpctl status
- Remove --llm-provider/--llm-model from create project (use edit/apply)
- 8 new smart pagination integration tests (e2e flow)
- 260 mcplocal tests, 330 CLI tests passing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 01:29:38 +00:00
d2dedf74e5 Merge pull request 'feat: completions update, create promptrequest, LLM flag rename, ACP content fix' (#41) from feat/completions-llm-flags-promptrequest into main 2026-02-25 00:21:51 +00:00
Michal
de95dd287f feat: completions update, create promptrequest, LLM flag rename, ACP content fix
- Add prompts/promptrequests to shell completions (fish + bash)
- Add approve, setup, prompt, promptrequest commands to completions
- Add `create promptrequest` CLI command (POST /projects/:name/promptrequests)
- Rename --proxy-mode-llm-provider/model to --llm-provider/model
- Fix ACP client: handle single-object content format from real Gemini
- Add tests for single-object content and agent_thought_chunk filtering

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 00:21:31 +00:00
Michal
cd12782797 fix: LLM health check via mcplocal instead of spawning gemini directly
Status command now queries mcplocal's /llm/health endpoint instead of
spawning the gemini binary. This uses the persistent ACP connection
(fast) and works for any configured provider, not just gemini-cli.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 00:03:25 +00:00
f3b2e2c1c5 Merge pull request 'feat: persistent Gemini ACP provider + status spinner' (#40) from feat/gemini-acp-provider into main 2026-02-24 23:52:31 +00:00
Michal
ce19427ec6 feat: persistent Gemini ACP provider + status spinner
Replace per-call gemini CLI spawning (~10s cold start each time) with
persistent ACP (Agent Client Protocol) subprocess. First call absorbs
the cold start, subsequent calls are near-instant over JSON-RPC stdio.

- Add AcpClient: manages persistent gemini --experimental-acp subprocess
  with lazy init, auto-restart on crash/timeout, NDJSON framing
- Add GeminiAcpProvider: LlmProvider wrapper with serial queue for
  concurrent calls, same interface as GeminiCliProvider
- Add dispose() to LlmProvider interface + disposeAll() to registry
- Wire provider disposal into mcplocal shutdown handler
- Add status command spinner with progressive output and color-coded
  LLM health check results (green checkmark/red cross)
- 25 new tests (17 ACP client + 8 provider)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 23:52:04 +00:00
Michal
36cd0bbec4 feat: auto-detect gemini binary path, LLM health check in status
- Setup wizard auto-detects gemini binary via `which`, saves full path
  so systemd service can find it without user PATH
- `mcpctl status` tests LLM provider health (gemini: quick prompt test,
  ollama: health check, API providers: key stored confirmation)
- Shows error details inline: "gemini-cli / gemini-2.5-flash (not authenticated)"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 23:24:31 +00:00
Michal
3ff39ff1ee fix: exactOptionalPropertyTypes and ResponsePaginator type errors
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 23:15:15 +00:00
4439e85852 Merge pull request 'feat: LLM provider configuration, secret store, and setup wizard' (#39) from feat/llm-config-and-secrets into main 2026-02-24 22:48:39 +00:00
Michal
5bc39c988c feat: LLM provider configuration, secret store, and setup wizard
Add secure credential storage (GNOME Keyring + file fallback),
LLM provider config in ~/.mcpctl/config.json, interactive setup
wizard (mcpctl config setup), and wire configured provider into
mcplocal for smart pagination summaries.

- Secret store: SecretStore interface, GnomeKeyringStore, FileSecretStore
- Config schema: LlmConfigSchema with provider/model/url/binaryPath
- Setup wizard: arrow-key provider/model selection, dynamic model fetch
- Provider factory: creates ProviderRegistry from config + secrets
- Status: shows LLM line with hint when not configured
- 572 tests passing across all packages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 22:48:17 +00:00
d6e4951a69 Merge pull request 'feat: smart response pagination for large MCP tool results' (#38) from feat/response-pagination into main 2026-02-24 21:40:53 +00:00
Michal
b7d54a4af6 feat: smart response pagination for large MCP tool results
Intercepts oversized tool responses (>80K chars), caches them, and returns
a page index. LLM can fetch specific pages via _resultId/_page params.
Supports LLM-generated smart summaries with simple fallback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 21:40:33 +00:00
Michal
c6fab132aa fix: auto-read user credentials for mcpd auth
mcplocal now reads ~/.mcpctl/credentials automatically when
MCPLOCAL_MCPD_TOKEN env var is not set, matching CLI behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 19:14:56 +00:00
cdfdfa87cc Merge pull request 'fix: STDIO transport stdout flush and MCP notification handling' (#37) from fix/stdio-flush-and-notifications into main 2026-02-24 19:10:03 +00:00
Michal
6df56b21d3 fix: STDIO transport stdout flush and MCP notification handling
- Wait for stdout.write callback before process.exit in STDIO transport
  to prevent truncation of large responses (e.g. grafana tools/list)
- Handle MCP notification methods (notifications/initialized, etc.) in
  router instead of returning "Method not found" error
- Use -p shorthand in config claude output

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 19:09:47 +00:00
316f122605 Merge pull request 'feat: prompt resources, proxy transport fix, enriched descriptions' (#36) from feat/prompt-resources-and-proxy-transport into main 2026-02-24 14:53:24 +00:00
Michal
b025ade2b0 feat: add prompt resources, fix MCP proxy transport, enrich tool descriptions
- Fix MCP proxy to support SSE and STDIO transports (not just HTTP POST)
- Enrich tool descriptions with server context for LLM clarity
- Add Prompt and PromptRequest resources with two-resource RBAC model
- Add propose_prompt MCP tool for LLM to create pending prompt requests
- Add prompt resources visible in MCP resources/list (approved + session's pending)
- Add project-level prompt/instructions in MCP initialize response
- Add ServiceAccount subject type for RBAC (SA identity from X-Service-Account header)
- Add CLI commands: create prompt, get prompts/promptrequests, approve promptrequest
- Add prompts to apply config schema
- 956 tests passing across all packages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 14:53:00 +00:00
Michal
fdafe87a77 fix: handle SSE responses in MCP bridge and add Commander-level tests
The bridge now parses SSE text/event-stream responses (extracting data:
lines) in addition to plain JSON. Also sends correct Accept header
per MCP streamable HTTP spec. Added tests for SSE handling and
command option parsing (-p/--project).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 10:17:45 +00:00
Michal
eb49ede732 fix: mcp command accepts --project directly for Claude spawned processes
The mcp subcommand now has its own -p/--project option with
passThroughOptions(), so `mcpctl mcp --project NAME` works when Claude
spawns the process. Updated config claude to generate
args: ['mcp', '--project', project] and added Commander-level tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 10:14:16 +00:00
f2495f644b Merge pull request 'feat: add mcpctl mcp STDIO bridge, rework config claude' (#35) from feat/mcp-stdio-bridge into main 2026-02-24 00:52:21 +00:00
Michal
b241b3d91c feat: add mcpctl mcp STDIO bridge, rework config claude
- New `mcpctl mcp -p PROJECT` command: STDIO-to-StreamableHTTP bridge
  that reads JSON-RPC from stdin and forwards to mcplocal project endpoint
- Rework `config claude` to write mcpctl mcp entry instead of fetching
  server configs from API (no secrets in .mcp.json)
- Keep `config claude-generate` as backward-compat alias
- Fix discovery.ts auth token not being forwarded to mcpd (RBAC bypass)
- Update fish/bash completions for new commands
- 10 new MCP bridge tests, updated claude tests, fixed project-discovery test

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 00:52:05 +00:00
6118835190 Merge pull request 'fix: don't send Content-Type on bodyless DELETE, include full server data in project queries' (#34) from fix/delete-content-type-and-project-servers into main 2026-02-23 19:55:35 +00:00
Michal
40e9de9327 fix: don't send Content-Type on bodyless DELETE, include full server data in project queries
- Only set Content-Type: application/json when request body is present (fixes
  Fastify rejecting empty DELETE with "Body cannot be empty" 400 error)
- Changed PROJECT_INCLUDE to return full server objects instead of just {id, name}
  so project server listings show transport, package, image columns

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 19:54:34 +00:00
d1c6e4451b Merge pull request 'fix: prevent attach/detach-server from repeating server arg on tab' (#33) from fix/completion-no-repeat-server-arg into main 2026-02-23 19:36:53 +00:00
Michal
d00973dc54 fix: prevent attach/detach-server from repeating server arg on tab
Added __mcpctl_needs_server_arg guard in fish and position check in
bash so completions stop after one server name is selected.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 19:36:45 +00:00
413dd783cd Merge pull request 'fix: instance completions use server.name, smart attach/detach' (#32) from fix/completion-instances-attach-detach into main 2026-02-23 19:32:34 +00:00
Michal
41f70bb178 fix: instance completions use server.name, smart attach/detach
- Instances have no name field — use server.name for completions
- attach-server: show only servers NOT in the project
- detach-server: show only servers IN the project
- Add helper functions for project-aware server completion
- 5 new tests covering all three fixes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 19:32:18 +00:00
4f1811d6f2 Merge pull request 'fix: use .[][].name in jq for wrapped JSON response' (#31) from fix/completion-jq-wrapped-json into main 2026-02-23 19:27:02 +00:00
Michal
0a641491a4 fix: use .[][].name in jq for wrapped JSON response
API returns { "resources": [...] } not bare arrays, so .[].name
produced no output. Use .[][].name to unwrap the outer object first.
Also auto-load .env in pr.sh.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 19:26:47 +00:00
8d296b6b7c Merge pull request 'fix: use jq for completion name extraction to avoid nested matches' (#30) from fix/completion-nested-names into main 2026-02-23 19:23:48 +00:00
Michal
dbab2f733d fix: use jq for completion name extraction to avoid nested matches
The regex "name":\s*"..." on JSON matched nested server names inside
project objects, mixing resource types in completions. Switch to
jq -r '.[].name' for proper top-level extraction. Add jq as RPM
dependency. Add pr.sh for PR creation via Gitea API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 19:23:21 +00:00
940b7714a3 Merge pull request 'feat: erase stale fish completions and add completion tests' (#29) from feat/completions-stale-erase-and-tests into main 2026-02-23 19:17:00 +00:00
Michal
84947580ff feat: erase stale fish completions and add completion tests
Fish completions are additive — sourcing a new file doesn't remove old
rules. Add `complete -c mcpctl -e` at the top to clear stale entries.
Also add 12 structural tests to prevent completion regressions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 19:16:36 +00:00
eb9034b8bb Merge pull request 'feat: context-aware completions with dynamic resource names' (#28) from feat/completions-project-scope-dynamic into main 2026-02-23 19:08:45 +00:00