754 Commits

Author SHA1 Message Date
Ed Zynda 512aa735bf feat(app): move hook execution into App layer
Fire UserPromptSubmit in Run() before queuing, PreToolUse/PostToolUse in
executeStep() callbacks, and Stop hook in runPrompt()/RunOnce() after each
step. Emit HookBlockedEvent when a hook blocks a prompt or tool call.
2026-02-26 01:36:51 +03:00
Ed Zynda 591d7905d2 refactor(cmd): scope SetupCLI to non-interactive path only
SetupCLI() and its associated debug/CLI display logic now only run when
--prompt is set (non-interactive mode). Interactive mode uses the Bubble
Tea AppModel exclusively and never allocates a legacy CLI.

- Move SetupCLI call inside promptFlag != "" guard
- Remove cli parameter from runInteractiveModeBubbleTea (was unused _)
- Remove cli parameter from runNonInteractiveModeApp (no longer needed)
- Session history display remains guarded by cli != nil, so it correctly
  skips in interactive mode
2026-02-26 01:31:57 +03:00
Ed Zynda 3f2a0aaa92 refactor(cmd): route non-interactive mode through app.RunOnce
Replace the legacy runNonInteractiveMode path (which used runAgenticLoop
and the old CLI spinner/streaming display) with runNonInteractiveModeApp,
which delegates directly to appInstance.RunOnce(ctx, prompt, os.Stdout).

RunOnce never creates a tea.Program, so no intermediate spinner or
tool-call output is produced — satisfying both the normal and --quiet
non-interactive cases with the same codepath.

When --no-exit is set, runNonInteractiveModeApp hands off to the
interactive BubbleTea TUI via runInteractiveModeBubbleTea after the
single step completes.
2026-02-26 01:26:47 +03:00
Ed Zynda c7585b17b8 feat(ui): wire interactive path to unified Bubble Tea TUI
Replace the old SetupCLI/runInteractiveLoop flow with a single
tea.NewProgram(AppModel) + appInstance.SetProgram() call. NewAppModel
now constructs InputComponent and StreamComponent inline so the parent
model is fully wired on construction.
2026-02-26 01:24:24 +03:00
Ed Zynda 302b85ab31 feat(app): create App struct with queue, cancellation, and graceful shutdown
TAS-18: Implements internal/app/app.go with the App orchestrator that satisfies
the ui.AppController interface. Wires all 7 agent callbacks to program.Send()
events, handles interactive approval via ToolApprovalNeededEvent channel, and
drains the prompt queue sequentially in a single background goroutine.

Refactors runNormalMode() in cmd/root.go to construct app.New() after session
messages are loaded, defer appInstance.Close(), and wire ToolApprovalFunc per
mode (AutoApproveFunc for non-interactive, nil for interactive TUI path).
2026-02-26 01:19:20 +03:00
Ed Zynda 7216c86db2 feat(app): add MessageStore for thread-safe conversation history management
Wraps []fantasy.Message with Add, Replace, GetAll, Clear, and Len methods.
Bridges to session.Manager for best-effort on-disk persistence on every mutation.
2026-02-26 01:14:49 +03:00
Ed Zynda 8303ee1dc5 feat(ui): add ApprovalComponent as parent-managed Bubble Tea child model
Refactors tool approval from the standalone ToolApprovalInput (which called
tea.Quit) into ApprovalComponent that returns approvalResultMsg{Approved: bool}
via a tea.Cmd, letting AppModel own the program lifecycle. Wires the
ToolApprovalNeededEvent handler in model.go to construct and display the
component.
2026-02-26 01:12:44 +03:00
Ed Zynda 0cf4e60a78 feat(ui): add StreamComponent as Bubble Tea child model for stream region
Implements TAS-16: refactors the stream display into a self-contained
StreamComponent with a phase state machine (idle/spinner/streaming).
Reuses knightRiderFrames() for the KITT-style spinner, accumulates
streaming chunks, and renders tool call/result events inline.
Reset() clears all state between agent steps.
2026-02-26 01:10:48 +03:00
Ed Zynda a99f11a2f7 feat(ui): add InputComponent with parent-managed lifecycle and slash command routing
Replaces the standalone SlashCommandInput quit-on-submit pattern with a
proper child component (InputComponent) that returns submitMsg as a tea.Cmd.
Slash commands are executed against AppController (/clear, /clear-queue) or
return tea.Quit (/quit) — no os.Exit(). Also registers /clear-queue in the
slash command registry.
2026-02-26 01:08:17 +03:00
Ed Zynda dbf1dd52e1 feat(ui): implement graceful quit via /quit command and ctrl+c in AppModel
Handle /quit slash command (and aliases /q, /exit) in submitMsg handler by
returning tea.Quit before forwarding to the app layer. Add TODO comment in
cmd/root.go marking where defer appInstance.Close() belongs once app.App
exists (TAS-18).
2026-02-26 01:05:27 +03:00
Ed Zynda 6398b3e637 feat(ui): implement StepErrorEvent handling in AppModel
Render step errors above the BT region via tea.Println() using the
existing RenderErrorMessage() renderers, mirroring the StepCompleteEvent
pattern. Reset stream state and transition back to stateInput on error.
2026-02-26 01:02:34 +03:00
Ed Zynda be77e716cb feat(ui): add parent AppModel and TUI-internal event types
Introduce the root Bubble Tea model (AppModel) and the three TUI-internal
message types needed by the unified architecture spec (TAS-10).

- internal/ui/events.go: submitMsg, approvalResultMsg, cancelTimerExpiredMsg
- internal/ui/model.go: AppModel with full stateInput/stateWorking/stateApproval
  state machine, AppController interface for dependency inversion, child
  component interfaces as stubs (TAS-15/16/17), double-tap ESC cancel with 2s
  timer, routing of all 13 app-layer events, tea.Println on StepCompleteEvent,
  stacked View() with separator and queue badge, WindowSizeMsg propagation.
2026-02-26 00:57:59 +03:00
Ed Zynda b23b8db3d6 feat(app): add event types for app-to-TUI communication
Define all 13 event structs in internal/app/events.go that the app layer
sends to the TUI via program.Send(), including streaming, tool call, approval,
spinner, queue, and error events.
2026-02-26 00:50:30 +03:00
Ed Zynda d4b393c95d spec: unified Bubble Tea architecture with single-program child model pattern
Replace micro-program pattern (3 separate tea.NewProgram calls) with a
single persistent program using child model composition. Introduces thick
app layer for agent orchestration, message queueing, and double-tap ESC
cancellation.
2026-02-26 00:46:46 +03:00
Ed Zynda b96fe071ba feat: replace spinner with KITT-style red scanning animation
Drop the points spinner and message label in favor of a Knight Rider
scanner that bounces a red glow across 8 small squares. Frames are
pre-rendered with a 3-level intensity trail (#FF0000, #990000, #440000)
at 14 FPS.
2026-02-26 00:12:25 +03:00
Ed Zynda 676a6b0e63 fix: replace manual ANSI escape sequences with Bubble Tea program for streaming display
Streaming text was flickering because displayContainer() used raw escape
sequences (\033[%dF) to move the cursor and fmt.Println to repaint on
every token. This bypassed Bubble Tea's synchronized output, cursor
hiding, and atomic flush.

Replace the manual approach with a dedicated tea.Program that runs for
the lifetime of each streaming response. BT's renderer now handles all
in-place updates flicker-free. One-shot messages (user, tool, system,
error) continue to use simple fmt.Println since they are never redrawn.
2026-02-26 00:07:27 +03:00
Ed Zynda 443410018c fix: prevent null 'required' in MCP tool schemas breaking OpenAI API
OpenAI strictly validates JSON Schema and rejects 'required': null (expects
an array). When MCP tools had no required fields, the nil []string serialized
as null. Initialize required as []string{} and sanitize nested schemas
recursively to remove null/invalid required fields from MCP server responses.
2026-02-25 22:51:56 +03:00
Ed Zynda 71bdc768be feat: replace catwalk with models.dev, auto-route openai-compatible providers, fix all lint issues
Replace catwalk dependency with direct models.dev integration (97 providers,
3039 models vs catwalk's 22/679). Auto-route @ai-sdk/openai-compatible
providers through fantasy's openaicompat using the api URL from models.dev,
eliminating the need for --provider-url. Add --all flag to 'mcphost models'
to show all providers vs just fantasy-compatible ones.

Fix all 74 golangci-lint issues: errcheck (53), staticcheck SA4006 (24),
SA9003 (2), ST1005 (5), ineffassign (3). Restructure styles.go color
handling into a colorScheme struct to eliminate SA4006 false positives
from new(x) syntax.
2026-02-25 22:51:45 +03:00
Ed Zynda ccef91e69c feat: add 'mcphost models' command to list available models per provider 2026-02-25 22:13:02 +03:00
Ed Zynda 29a46f6f98 feat: advisory model validation, update-models command, and vercel provider
- Make model validation advisory: unknown models pass through to the
  provider API with a stderr warning instead of blocking. Catwalk
  metadata is used for cost tracking and suggestions when available.
- Add LookupModel() as the primary registry API (returns nil for
  unknown models, no error).
- Add 'mcphost update-models' subcommand to refresh the model database
  from a catwalk server (defaults to https://catwalk.charm.sh), a local
  file, or reset to the embedded version. Supports ETag caching.
- Add disk cache layer at ~/.local/share/mcphost/providers.json;
  registry loads cached data first, falls back to embedded.
- Add vercel provider support via fantasy.
- Add io.Closer plumbing to ProviderResult and Agent.Close() for
  providers that hold resources.
2026-02-25 22:09:24 +03:00
Ed Zynda 72fa1ff029 chore: remove dead code and unused token counter package
- Delete dead ESC listener code and bubbletea/time imports from agent
- Remove internal/tokens/ package (empty stubs and trivial estimator)
- Inline token estimation into usage_tracker as unexported helper
- Remove unused EstimateAndUpdateUsageFromText dead method
- Remove 9 unsupported provider env var entries from registry
2026-02-25 20:35:19 +03:00
Ed Zynda e62ce679fe feat: change model notation from provider:model to provider/model
Switch the --model / -m flag format from colon-separated (provider:model)
to slash-separated (provider/model), e.g. anthropic/claude-sonnet-4-5-20250929
or ollama/qwen3:8b. The slash separator is cleaner since model names can
contain colons (ollama tags, bedrock ARNs).

Add centralized ParseModelString() in internal/models/providers.go that all
callers now use. The old colon format is still accepted with a deprecation
warning to stderr for backward compatibility.

Update default model to claude-sonnet-4-5-20250929.
2026-02-25 18:41:49 +03:00
Ed Zynda be9162637b chore: upgrade all dependencies to latest versions 2026-02-25 18:20:08 +03:00
Ed Zynda 0703dd1602 fix: eliminate escape sequence leak from spinner tea.Program instances
Each spinner created a new tea.NewProgram which sent DECRQM queries for
synchronized output mode 2026. When the program exited and restored
cooked terminal mode, the terminal's DECRPM response leaked as visible
^[[?2026;2$y characters. Replace Bubble Tea spinner with a simple
goroutine animation loop writing directly to stderr via lipgloss.
2026-02-25 18:17:25 +03:00
Ed Zynda ce32cea7ee feat: upgrade charmbracelet libs to v2 (bubbletea, lipgloss, bubbles)
Migrate from github.com/charmbracelet/* v1 to charm.land/* v2 vanity imports.

Key changes:
- bubbletea: View() returns tea.View, KeyMsg -> KeyPressMsg, msg.String() matching
- lipgloss: AdaptiveColor replaced with cached dark-bg detection helper
- bubbles/textarea: Styles()/SetStyles() pattern, KeyMap.InsertNewline override
- bubbles/progress: SetWidth(), WithDefaultBlend(), typed Update return
- Input: enter always submits, ctrl+j/alt+enter insert newlines
- User message newlines preserved through glamour via \n -> \n\n conversion
- glamour stays at v1 (no v2 exists)
2026-02-25 17:07:09 +03:00
Ed Zynda d24d49854f Merge branch 'main' of github.com:mark3labs/mcphost 2026-02-25 16:24:33 +03:00
Ed Zynda bf2f44190d btca 2026-02-25 16:24:28 +03:00
Ramiz Polic 191dcea159 chore: update packages to resolve security issues (#154)
Signed-off-by: Ramiz Polic <rpolic@cisco.com>
2026-02-15 19:56:44 +03:00
Ed Zynda a77aab3d90 fix: upgrade sonic to v1.15.0 for Go 1.26 compatibility
Fixes build error with Go 1.26rc1/rc2 caused by undefined GoMapIterator
in sonic v1.14.1.

Closes #152
2026-02-02 11:09:51 +03:00
Shane McDonald c4aa911e3a feat: add Google Vertex AI support for Claude models (#146)
Add support for using Claude models via Google Cloud Vertex AI through
the `google-vertex-anthropic` provider. This enables users who have
Claude access through their Google Cloud account to use mcphost with
Vertex AI authentication.

Changes:
- Add `google-vertex-anthropic` provider case and createVertexAnthropicProvider()
- Support multiple env var names for project/region to match eino-claude:
  - Project: ANTHROPIC_VERTEX_PROJECT_ID, GOOGLE_CLOUD_PROJECT, GCLOUD_PROJECT
  - Region: CLOUD_ML_REGION (defaults to "global" if not set)
- Upgrade eino from v0.5.11 to v0.7.11 (required by eino-claude v0.1.12)
- Migrate schema API from OpenAPI v3 to JSON Schema (eino v0.7.11 change)

Usage:
  # Authenticate with Google Cloud
  gcloud auth application-default login

  # Set required environment variables
  export ANTHROPIC_VERTEX_PROJECT_ID="your-project-id"
  export CLOUD_ML_REGION="us-east5"  # or use default "global"

  # Run mcphost
  mcphost --model google-vertex-anthropic:claude-sonnet-4@20250514

Reference: https://docs.anthropic.com/en/docs/claude-code/google-vertex-ai

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 13:01:18 +03:00
Ed Zynda 7ece291d9a fix anthropic api issue 2026-01-09 17:39:30 +03:00
Ed Zynda f9485cbe59 new models 2026-01-09 17:30:59 +03:00
Ed Zynda c284a20dab upgrade deps 2026-01-09 17:25:53 +03:00
Cory LaNou 1b3a8c171a fix: convert JSON Schema draft-07 exclusive bounds to draft-04 format (#147)
* fix: convert JSON Schema draft-07 exclusive bounds to draft-04 format

Chrome DevTools MCP and other MCP servers use JSON Schema draft-07 where
exclusiveMinimum/exclusiveMaximum are numeric values representing the
actual bounds. However, kin-openapi (OpenAPI 3.0) expects these fields
as booleans that modify the minimum/maximum values (draft-04 format).

This fix recursively processes input schemas to convert:
- exclusiveMinimum: N → minimum: N, exclusiveMinimum: true
- exclusiveMaximum: N → maximum: N, exclusiveMaximum: true

Handles nested schemas in properties, items, additionalProperties,
and schema composition keywords (allOf, anyOf, oneOf, not).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: add table-driven tests for JSON Schema draft conversion

Adds comprehensive tests for convertExclusiveBoundsToBoolean():
- Simple exclusiveMinimum/exclusiveMaximum conversion
- Both bounds together
- Already boolean values (draft-04 style, unchanged)
- No exclusive bounds (unchanged)
- Nested properties
- Array items
- allOf composition
- additionalProperties
- Real-world Chrome DevTools MCP schema example
- Invalid JSON handling (returns unchanged)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 16:03:16 +03:00
Ed Zynda 4891f87038 skip unless running locally 2025-12-09 21:27:48 +03:00
Darragh O'Reilly f240b9a8c1 Bump github.com/cloudwego/eino to fix panic (#142)
Fixes panic when using some MCP servers that were auto-generated
from OpenAPI specs. Fixes #141
2025-12-09 18:28:52 +03:00
Darragh O'Reilly cab31935f1 Feat: Add option to require approval before tool execution (#140)
Adds a new CLI option, `--approve-tool-run` (or via config setting),
that when enabled, prompts the user to approve a tool's execution
before it runs.

This option is disabled by default to maintain existing behavior.
2025-12-09 18:28:41 +03:00
Ed Zynda d3cae7c016 remove stale key 2025-12-05 10:25:49 +03:00
Ed Zynda 8c1f548eac update deps 2025-11-14 17:06:07 +03:00
Ed Zynda 63704f55b5 godoc 2025-11-12 16:48:46 +03:00
Ed Zynda d3281a2f01 format 2025-10-16 16:36:12 +03:00
Ed Zynda 1b7cc2ef6e update models 2025-10-16 16:35:52 +03:00
Ed Zynda d56335e807 fix: suppress health check logging to debug output only (#135)
Replace fmt.Printf calls in connection pool health check routines with debug logger calls. Health check messages are now only displayed when the --debug flag is enabled, providing a cleaner terminal output during normal operation while maintaining diagnostic information for troubleshooting.
2025-10-16 16:33:41 +03:00
Ed Zynda 13acf44131 add AGENTS.md 2025-10-16 16:26:19 +03:00
Ed Zynda dec5f08f80 update mcp-go 2025-10-07 10:35:31 +03:00
Ed Zynda 81ec644cb9 Update deps 2025-09-03 15:45:02 +03:00
Ed Zynda f778379dea feat: Add SDK package for programmatic MCPHost usage (#129)
* feat: add SDK package for programmatic MCPHost usage

- Export InitConfig and LoadConfigWithEnvSubstitution from cmd package
- Create sdk package with MCPHost type for programmatic access
- Add Options struct for configuration overrides
- Implement Prompt and PromptWithCallbacks methods
- Add session management (load, save, clear)
- Create type helpers for Message and ToolCall
- Add comprehensive SDK documentation in README
- Include basic and scripting examples
- Add unit tests for SDK functionality

The SDK reuses all existing internal packages and maintains identical
behavior to the CLI, including config loading, environment variables,
and defaults.

* docs: add SDK section to main README with link to detailed documentation

* fix tests

* update CI
2025-09-02 15:42:37 +03:00
Ed Zynda 4709716f5e Let viper handle precedence 2025-09-02 15:10:03 +03:00
Rui Chen 433bdece70 fix --version output (#128)
Signed-off-by: Rui Chen <rui@chenrui.dev>
2025-09-02 13:53:37 +03:00
Ed Zynda cc1ab91e64 Update mcp-go 2025-09-02 13:46:31 +03:00