mirror of
https://github.com/mark3labs/kit.git
synced 2026-06-13 19:20:06 +00:00
rename: fork mcphost to kit (github.com/mark3labs/kit)
Rename the entire project from mcphost to kit, including: - Go module path and all import paths - SDK type MCPHost -> Kit, file renames mcphost.go -> kit.go - CLI command name, usage strings, UI labels (KIT in literature) - Config paths (.mcphost -> .kit), env prefix (MCPHOST_ -> KIT_) - Data/credential/hooks directory paths - Remove legacy .mcp config fallbacks - Session metadata field (mcphost_version -> kit_version) - MCP client identity name - Build output, goreleaser binary name - All documentation, examples, scripts, and test files
This commit is contained in:
+1
-2
@@ -1,9 +1,8 @@
|
||||
.aider*
|
||||
.env
|
||||
aidocs/
|
||||
.mcp.json
|
||||
*.log
|
||||
mcphost
|
||||
kit
|
||||
.idea
|
||||
test/
|
||||
build/
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ builds:
|
||||
ignore:
|
||||
- goos: windows
|
||||
goarch: arm64
|
||||
binary: mcphost
|
||||
binary: kit
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}}
|
||||
|
||||
|
||||
@@ -17,10 +17,10 @@ Keep this managed block so 'openspec update' can refresh the instructions.
|
||||
|
||||
<!-- OPENSPEC:END -->
|
||||
|
||||
# MCPHost Agent Guidelines
|
||||
# KIT Agent Guidelines
|
||||
|
||||
## Build/Test Commands
|
||||
- **Build**: `go build -o output/mcphost`
|
||||
- **Build**: `go build -o output/kit`
|
||||
- **Test all**: `go test -race ./...`
|
||||
- **Test single**: `go test -race ./cmd -run TestScriptExecution`
|
||||
- **Lint**: `go vet ./...`
|
||||
@@ -38,4 +38,4 @@ Keep this managed block so 'openspec update' can refresh the instructions.
|
||||
## Architecture
|
||||
- Multi-provider LLM support via `llm.Provider` interface
|
||||
- MCP client-server for tool integration
|
||||
- Builtin servers: bash, fetch, todo, fs
|
||||
- Builtin servers: bash, fetch, todo, fs
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# MCPHost 🤖
|
||||
# KIT 🤖
|
||||
|
||||
A CLI host application that enables Large Language Models (LLMs) to interact with external tools through the Model Context Protocol (MCP). Currently supports Claude, OpenAI, Google Gemini, and Ollama models.
|
||||
|
||||
@@ -40,8 +40,8 @@ Discuss the Project on [Discord](https://discord.gg/RqSS2NQVsY)
|
||||
|
||||
## Overview 🌟
|
||||
|
||||
MCPHost acts as a host in the MCP client-server architecture, where:
|
||||
- **Hosts** (like MCPHost) are LLM applications that manage connections and interactions
|
||||
KIT acts as a host in the MCP client-server architecture, where:
|
||||
- **Hosts** (like KIT) are LLM applications that manage connections and interactions
|
||||
- **Clients** maintain 1:1 connections with MCP servers
|
||||
- **Servers** provide context, tools, and capabilities to the LLMs
|
||||
|
||||
@@ -117,19 +117,19 @@ export GOOGLE_API_KEY='your-api-key'
|
||||
5. Self-Signed Certificates (TLS):
|
||||
If your provider uses self-signed certificates (e.g., local Ollama with HTTPS), you can skip certificate verification:
|
||||
```bash
|
||||
mcphost --provider-url https://192.168.1.100:443 --tls-skip-verify
|
||||
kit --provider-url https://192.168.1.100:443 --tls-skip-verify
|
||||
```
|
||||
⚠️ **WARNING**: Only use `--tls-skip-verify` for development or when connecting to trusted servers with self-signed certificates. This disables TLS certificate verification and is insecure for production use.
|
||||
|
||||
## Installation 📦
|
||||
|
||||
```bash
|
||||
go install github.com/mark3labs/mcphost@latest
|
||||
go install github.com/mark3labs/kit@latest
|
||||
```
|
||||
|
||||
## SDK Usage 🛠️
|
||||
|
||||
MCPHost also provides a Go SDK for programmatic access without spawning OS processes. The SDK maintains identical behavior to the CLI, including configuration loading, environment variables, and defaults.
|
||||
KIT also provides a Go SDK for programmatic access without spawning OS processes. The SDK maintains identical behavior to the CLI, including configuration loading, environment variables, and defaults.
|
||||
|
||||
### Quick Example
|
||||
|
||||
@@ -139,13 +139,13 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/mark3labs/mcphost/sdk"
|
||||
"github.com/mark3labs/kit/sdk"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
|
||||
// Create MCPHost instance with default configuration
|
||||
// Create Kit instance with default configuration
|
||||
host, err := sdk.New(ctx, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -176,19 +176,18 @@ For detailed SDK documentation, examples, and API reference, see the [SDK README
|
||||
## Configuration ⚙️
|
||||
|
||||
### MCP Servers
|
||||
MCPHost will automatically create a configuration file in your home directory if it doesn't exist. It looks for config files in this order:
|
||||
- `.mcphost.yml` or `.mcphost.json` (preferred)
|
||||
- `.mcp.yml` or `.mcp.json` (backwards compatibility)
|
||||
KIT will automatically create a configuration file in your home directory if it doesn't exist. It looks for config files in this order:
|
||||
- `.kit.yml` or `.kit.json`
|
||||
|
||||
**Config file locations by OS:**
|
||||
- **Linux/macOS**: `~/.mcphost.yml`, `~/.mcphost.json`, `~/.mcp.yml`, `~/.mcp.json`
|
||||
- **Windows**: `%USERPROFILE%\.mcphost.yml`, `%USERPROFILE%\.mcphost.json`, `%USERPROFILE%\.mcp.yml`, `%USERPROFILE%\.mcp.json`
|
||||
- **Linux/macOS**: `~/.kit.yml`, `~/.kit.json`
|
||||
- **Windows**: `%USERPROFILE%\.kit.yml`, `%USERPROFILE%\.kit.json`
|
||||
|
||||
You can also specify a custom location using the `--config` flag.
|
||||
|
||||
### Environment Variable Substitution
|
||||
|
||||
MCPHost supports environment variable substitution in both config files and script frontmatter using the syntax:
|
||||
KIT supports environment variable substitution in both config files and script frontmatter using the syntax:
|
||||
- **`${env://VAR}`** - Required environment variable (fails if not set)
|
||||
- **`${env://VAR:-default}`** - Optional environment variable with default value
|
||||
|
||||
@@ -218,13 +217,13 @@ export OPENAI_API_KEY="your_openai_key"
|
||||
export DEBUG="true"
|
||||
export MODEL="openai/gpt-4"
|
||||
|
||||
# Run mcphost
|
||||
mcphost
|
||||
# Run kit
|
||||
kit
|
||||
```
|
||||
|
||||
### Simplified Configuration Schema
|
||||
|
||||
MCPHost now supports a simplified configuration schema with three server types:
|
||||
KIT now supports a simplified configuration schema with three server types:
|
||||
|
||||
#### Local Servers
|
||||
For local MCP servers that run commands on your machine:
|
||||
@@ -386,7 +385,7 @@ All MCP server types support tool filtering to restrict which tools are availabl
|
||||
|
||||
### Legacy Configuration Support
|
||||
|
||||
MCPHost maintains full backward compatibility with the previous configuration format. **Note**: A recent bug fix improved legacy stdio transport reliability for external MCP servers (Docker, NPX, etc.).
|
||||
KIT maintains full backward compatibility with the previous configuration format. **Note**: A recent bug fix improved legacy stdio transport reliability for external MCP servers (Docker, NPX, etc.).
|
||||
|
||||
#### Legacy STDIO Format
|
||||
```json
|
||||
@@ -448,7 +447,7 @@ MCPHost maintains full backward compatibility with the previous configuration fo
|
||||
|
||||
### Transport Types
|
||||
|
||||
MCPHost supports four transport types:
|
||||
KIT supports four transport types:
|
||||
- **`stdio`**: Launches a local process and communicates via stdin/stdout (used by `"local"` servers)
|
||||
- **`sse`**: Connects to a server using Server-Sent Events (legacy format)
|
||||
- **`streamable`**: Connects to a server using Streamable HTTP protocol (used by `"remote"` servers)
|
||||
@@ -465,12 +464,12 @@ You can specify a custom system prompt using the `--system-prompt` flag. You can
|
||||
|
||||
1. **Pass the prompt directly as text:**
|
||||
```bash
|
||||
mcphost --system-prompt "You are a helpful assistant that responds in a friendly tone."
|
||||
kit --system-prompt "You are a helpful assistant that responds in a friendly tone."
|
||||
```
|
||||
|
||||
2. **Pass a path to a text file containing the prompt:**
|
||||
```bash
|
||||
mcphost --system-prompt ./prompts/assistant.md
|
||||
kit --system-prompt ./prompts/assistant.md
|
||||
```
|
||||
|
||||
Example `assistant.md` file:
|
||||
@@ -487,14 +486,14 @@ You can specify a custom system prompt using the `--system-prompt` flag. You can
|
||||
|
||||
## Usage 🚀
|
||||
|
||||
MCPHost is a CLI tool that allows you to interact with various AI models through a unified interface. It supports various tools through MCP servers and can run in both interactive and non-interactive modes.
|
||||
KIT is a CLI tool that allows you to interact with various AI models through a unified interface. It supports various tools through MCP servers and can run in both interactive and non-interactive modes.
|
||||
|
||||
### Interactive Mode (Default)
|
||||
|
||||
Start an interactive conversation session:
|
||||
|
||||
```bash
|
||||
mcphost
|
||||
kit
|
||||
```
|
||||
|
||||
### Script Mode
|
||||
@@ -503,10 +502,10 @@ Run executable YAML-based automation scripts with variable substitution support:
|
||||
|
||||
```bash
|
||||
# Using the script subcommand
|
||||
mcphost script myscript.sh
|
||||
kit script myscript.sh
|
||||
|
||||
# With variables
|
||||
mcphost script myscript.sh --args:directory /tmp --args:name "John"
|
||||
kit script myscript.sh --args:directory /tmp --args:name "John"
|
||||
|
||||
# Direct execution (if executable and has shebang)
|
||||
./myscript.sh
|
||||
@@ -517,7 +516,7 @@ mcphost script myscript.sh --args:directory /tmp --args:name "John"
|
||||
Scripts combine YAML configuration with prompts in a single executable file. The configuration must be wrapped in frontmatter delimiters (`---`). You can either include the prompt in the YAML configuration or place it after the closing frontmatter delimiter:
|
||||
|
||||
```yaml
|
||||
#!/usr/bin/env -S mcphost script
|
||||
#!/usr/bin/env -S kit script
|
||||
---
|
||||
# This script uses the container-use MCP server from https://github.com/dagger/container-use
|
||||
mcpServers:
|
||||
@@ -533,7 +532,7 @@ prompt: |
|
||||
Or alternatively, omit the `prompt:` field and place the prompt after the frontmatter:
|
||||
|
||||
```yaml
|
||||
#!/usr/bin/env -S mcphost script
|
||||
#!/usr/bin/env -S kit script
|
||||
---
|
||||
# This script uses the container-use MCP server from https://github.com/dagger/container-use
|
||||
mcpServers:
|
||||
@@ -556,12 +555,12 @@ Variables can be provided via command line arguments:
|
||||
|
||||
```bash
|
||||
# Script with variables
|
||||
mcphost script myscript.sh --args:directory /tmp --args:name "John"
|
||||
kit script myscript.sh --args:directory /tmp --args:name "John"
|
||||
```
|
||||
|
||||
##### Variable Syntax
|
||||
|
||||
MCPHost supports these variable syntaxes:
|
||||
KIT supports these variable syntaxes:
|
||||
|
||||
1. **Required Environment Variables**: `${env://VAR}` - Must be set in environment
|
||||
2. **Optional Environment Variables**: `${env://VAR:-default}` - Uses default if not set
|
||||
@@ -570,7 +569,7 @@ MCPHost supports these variable syntaxes:
|
||||
|
||||
Example script with mixed environment variables and script arguments:
|
||||
```yaml
|
||||
#!/usr/bin/env -S mcphost script
|
||||
#!/usr/bin/env -S kit script
|
||||
---
|
||||
mcpServers:
|
||||
github:
|
||||
@@ -600,16 +599,16 @@ export DEBUG="true"
|
||||
export WORK_DIR="/home/user/projects"
|
||||
|
||||
# Uses env vars and defaults: name="World", repo_type="public", command="gh", count="10"
|
||||
mcphost script myscript.sh
|
||||
kit script myscript.sh
|
||||
|
||||
# Override specific script arguments
|
||||
mcphost script myscript.sh --args:name "John" --args:username "alice"
|
||||
kit script myscript.sh --args:name "John" --args:username "alice"
|
||||
|
||||
# Override multiple script arguments
|
||||
mcphost script myscript.sh --args:name "John" --args:username "alice" --args:repo_type "private"
|
||||
kit script myscript.sh --args:name "John" --args:username "alice" --args:repo_type "private"
|
||||
|
||||
# Mix of env vars, provided args, and default values
|
||||
mcphost script myscript.sh --args:name "Alice" --args:command "gh api" --args:count "5"
|
||||
kit script myscript.sh --args:name "Alice" --args:command "gh api" --args:count "5"
|
||||
```
|
||||
|
||||
##### Default Value Features
|
||||
@@ -627,7 +626,7 @@ mcphost script myscript.sh --args:name "Alice" --args:command "gh api" --args:co
|
||||
|
||||
#### Script Features
|
||||
|
||||
- **Executable**: Use shebang line for direct execution (`#!/usr/bin/env -S mcphost script`)
|
||||
- **Executable**: Use shebang line for direct execution (`#!/usr/bin/env -S kit script`)
|
||||
- **YAML Configuration**: Define MCP servers directly in the script
|
||||
- **Embedded Prompts**: Include the prompt in the YAML
|
||||
- **Variable Substitution**: Use `${variable}` and `${variable:-default}` syntax with `--args:variable value`
|
||||
@@ -637,7 +636,7 @@ mcphost script myscript.sh --args:name "Alice" --args:command "gh api" --args:co
|
||||
- **Tool Filtering**: Supports `allowedTools`/`excludedTools` per server
|
||||
- **Clean Exit**: Automatically exits after completion
|
||||
|
||||
**Note**: The shebang line requires `env -S` to handle the multi-word command `mcphost script`. This is supported on most modern Unix-like systems.
|
||||
**Note**: The shebang line requires `env -S` to handle the multi-word command `kit script`. This is supported on most modern Unix-like systems.
|
||||
|
||||
#### Script Examples
|
||||
|
||||
@@ -647,30 +646,30 @@ See `examples/scripts/` for sample scripts:
|
||||
|
||||
### Hooks System
|
||||
|
||||
MCPHost supports a powerful hooks system that allows you to execute custom commands at specific points during execution. This enables security policies, logging, custom integrations, and automated workflows.
|
||||
KIT supports a powerful hooks system that allows you to execute custom commands at specific points during execution. This enables security policies, logging, custom integrations, and automated workflows.
|
||||
|
||||
#### Quick Start
|
||||
|
||||
1. Initialize a hooks configuration:
|
||||
```bash
|
||||
mcphost hooks init
|
||||
kit hooks init
|
||||
```
|
||||
|
||||
2. View active hooks:
|
||||
```bash
|
||||
mcphost hooks list
|
||||
kit hooks list
|
||||
```
|
||||
|
||||
3. Validate your configuration:
|
||||
```bash
|
||||
mcphost hooks validate
|
||||
kit hooks validate
|
||||
```
|
||||
|
||||
#### Configuration
|
||||
|
||||
Hooks are configured in YAML files with the following precedence (highest to lowest):
|
||||
- `.mcphost/hooks.yml` (project-specific hooks)
|
||||
- `$XDG_CONFIG_HOME/mcphost/hooks.yml` (user global hooks, defaults to `~/.config/mcphost/hooks.yml`)
|
||||
- `.kit/hooks.yml` (project-specific hooks)
|
||||
- `$XDG_CONFIG_HOME/kit/hooks.yml` (user global hooks, defaults to `~/.config/kit/hooks.yml`)
|
||||
|
||||
Example configuration:
|
||||
```yaml
|
||||
@@ -685,7 +684,7 @@ hooks:
|
||||
UserPromptSubmit:
|
||||
- hooks:
|
||||
- type: command
|
||||
command: "~/.mcphost/hooks/log-prompt.sh"
|
||||
command: "~/.kit/hooks/log-prompt.sh"
|
||||
```
|
||||
|
||||
#### Available Hook Events
|
||||
@@ -695,7 +694,7 @@ hooks:
|
||||
- **UserPromptSubmit**: When user submits a prompt
|
||||
- **Stop**: When the agent finishes responding
|
||||
- **SubagentStop**: When a subagent (Task tool) finishes
|
||||
- **Notification**: When MCPHost sends notifications
|
||||
- **Notification**: When KIT sends notifications
|
||||
|
||||
#### Security
|
||||
|
||||
@@ -703,7 +702,7 @@ hooks:
|
||||
|
||||
To temporarily disable all hooks, use the `--no-hooks` flag:
|
||||
```bash
|
||||
mcphost --no-hooks
|
||||
kit --no-hooks
|
||||
```
|
||||
|
||||
See the example hook scripts in `examples/hooks/`:
|
||||
@@ -717,34 +716,34 @@ Run a single prompt and exit - perfect for scripting and automation:
|
||||
|
||||
```bash
|
||||
# Basic non-interactive usage
|
||||
mcphost -p "What is the weather like today?"
|
||||
kit -p "What is the weather like today?"
|
||||
|
||||
# Quiet mode - only output the AI response (no UI elements)
|
||||
mcphost -p "What is 2+2?" --quiet
|
||||
kit -p "What is 2+2?" --quiet
|
||||
|
||||
# Use with different models
|
||||
mcphost -m ollama/qwen2.5:3b -p "Explain quantum computing" --quiet
|
||||
kit -m ollama/qwen2.5:3b -p "Explain quantum computing" --quiet
|
||||
```
|
||||
|
||||
### Model Generation Parameters
|
||||
|
||||
MCPHost supports fine-tuning model behavior through various parameters:
|
||||
KIT supports fine-tuning model behavior through various parameters:
|
||||
|
||||
```bash
|
||||
# Control response length
|
||||
mcphost -p "Explain AI" --max-tokens 1000
|
||||
kit -p "Explain AI" --max-tokens 1000
|
||||
|
||||
# Adjust creativity (0.0 = focused, 1.0 = creative)
|
||||
mcphost -p "Write a story" --temperature 0.9
|
||||
kit -p "Write a story" --temperature 0.9
|
||||
|
||||
# Control diversity with nucleus sampling
|
||||
mcphost -p "Generate ideas" --top-p 0.8
|
||||
kit -p "Generate ideas" --top-p 0.8
|
||||
|
||||
# Limit token choices for more focused responses
|
||||
mcphost -p "Answer precisely" --top-k 20
|
||||
kit -p "Answer precisely" --top-k 20
|
||||
|
||||
# Set custom stop sequences
|
||||
mcphost -p "Generate code" --stop-sequences "```","END"
|
||||
kit -p "Generate code" --stop-sequences "```","END"
|
||||
```
|
||||
|
||||
These parameters work with all supported providers (OpenAI, Anthropic, Google, Ollama) where supported by the underlying model.
|
||||
@@ -762,13 +761,13 @@ Models can be specified using the `--model` (`-m`) flag:
|
||||
#### Interactive Mode
|
||||
```bash
|
||||
# Use Ollama with Qwen model
|
||||
mcphost -m ollama/qwen2.5:3b
|
||||
kit -m ollama/qwen2.5:3b
|
||||
|
||||
# Use OpenAI's GPT-4
|
||||
mcphost -m openai/gpt-4
|
||||
kit -m openai/gpt-4
|
||||
|
||||
# Use OpenAI-compatible model with custom URL and API key
|
||||
mcphost --model openai/<your-model-name> \
|
||||
kit --model openai/<your-model-name> \
|
||||
--provider-url <your-base-url> \
|
||||
--provider-api-key <your-api-key>
|
||||
```
|
||||
@@ -776,27 +775,27 @@ mcphost --model openai/<your-model-name> \
|
||||
#### Non-Interactive Mode
|
||||
```bash
|
||||
# Single prompt with full UI
|
||||
mcphost -p "List files in the current directory"
|
||||
kit -p "List files in the current directory"
|
||||
|
||||
# Compact mode for cleaner output without fancy styling
|
||||
mcphost -p "List files in the current directory" --compact
|
||||
kit -p "List files in the current directory" --compact
|
||||
|
||||
# Quiet mode for scripting (only AI response output, no UI elements)
|
||||
mcphost -p "What is the capital of France?" --quiet
|
||||
kit -p "What is the capital of France?" --quiet
|
||||
|
||||
# Use in shell scripts
|
||||
RESULT=$(mcphost -p "Calculate 15 * 23" --quiet)
|
||||
RESULT=$(kit -p "Calculate 15 * 23" --quiet)
|
||||
echo "The answer is: $RESULT"
|
||||
|
||||
# Pipe to other commands
|
||||
mcphost -p "Generate a random UUID" --quiet | tr '[:lower:]' '[:upper:]'
|
||||
kit -p "Generate a random UUID" --quiet | tr '[:lower:]' '[:upper:]'
|
||||
```
|
||||
|
||||
### Flags
|
||||
- `--provider-url string`: Base URL for the provider API (applies to OpenAI, Anthropic, Ollama, and Google)
|
||||
- `--provider-api-key string`: API key for the provider (applies to OpenAI, Anthropic, and Google)
|
||||
- `--tls-skip-verify`: Skip TLS certificate verification (WARNING: insecure, use only for self-signed certificates)
|
||||
- `--config string`: Config file location (default is $HOME/.mcphost.yml)
|
||||
- `--config string`: Config file location (default is $HOME/.kit.yml)
|
||||
- `--system-prompt string`: system-prompt file location
|
||||
- `--debug`: Enable debug logging
|
||||
- `--max-steps int`: Maximum number of agent steps (0 for unlimited, default: 0)
|
||||
@@ -807,9 +806,9 @@ mcphost -p "Generate a random UUID" --quiet | tr '[:lower:]' '[:upper:]'
|
||||
- `--stream`: Enable streaming responses (default: true, use `--stream=false` to disable)
|
||||
|
||||
### Authentication Subcommands
|
||||
- `mcphost auth login anthropic`: Authenticate with Anthropic using OAuth (alternative to API keys)
|
||||
- `mcphost auth logout anthropic`: Remove stored OAuth credentials
|
||||
- `mcphost auth status`: Show authentication status
|
||||
- `kit auth login anthropic`: Authenticate with Anthropic using OAuth (alternative to API keys)
|
||||
- `kit auth logout anthropic`: Remove stored OAuth credentials
|
||||
- `kit auth status`: Show authentication status
|
||||
|
||||
**Note**: OAuth credentials (when present) take precedence over API keys from environment variables and `--provider-api-key` flags.
|
||||
|
||||
@@ -822,11 +821,10 @@ mcphost -p "Generate a random UUID" --quiet | tr '[:lower:]' '[:upper:]'
|
||||
|
||||
### Configuration File Support
|
||||
|
||||
All command-line flags can be configured via the config file. MCPHost will look for configuration in this order:
|
||||
1. `~/.mcphost.yml` or `~/.mcphost.json` (preferred)
|
||||
2. `~/.mcp.yml` or `~/.mcp.json` (backwards compatibility)
|
||||
All command-line flags can be configured via the config file. KIT will look for configuration in this order:
|
||||
1. `~/.kit.yml` or `~/.kit.json`
|
||||
|
||||
Example config file (`~/.mcphost.yml`):
|
||||
Example config file (`~/.kit.yml`):
|
||||
```yaml
|
||||
# MCP Servers - New Simplified Format
|
||||
mcpServers:
|
||||
@@ -882,16 +880,16 @@ While chatting, you can use:
|
||||
### Authentication Commands
|
||||
|
||||
Optional OAuth authentication for Anthropic (alternative to API keys):
|
||||
- `mcphost auth login anthropic`: Authenticate using OAuth
|
||||
- `mcphost auth logout anthropic`: Remove stored OAuth credentials
|
||||
- `mcphost auth status`: Show authentication status
|
||||
- `kit auth login anthropic`: Authenticate using OAuth
|
||||
- `kit auth logout anthropic`: Remove stored OAuth credentials
|
||||
- `kit auth status`: Show authentication status
|
||||
|
||||
### Global Flags
|
||||
- `--config`: Specify custom config file location
|
||||
|
||||
## Automation & Scripting 🤖
|
||||
|
||||
MCPHost's non-interactive mode makes it perfect for automation, scripting, and integration with other tools.
|
||||
KIT's non-interactive mode makes it perfect for automation, scripting, and integration with other tools.
|
||||
|
||||
### Use Cases
|
||||
|
||||
@@ -899,11 +897,11 @@ MCPHost's non-interactive mode makes it perfect for automation, scripting, and i
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Get weather and save to file
|
||||
mcphost -p "What's the weather in New York?" --quiet > weather.txt
|
||||
kit -p "What's the weather in New York?" --quiet > weather.txt
|
||||
|
||||
# Process files with AI
|
||||
for file in *.txt; do
|
||||
summary=$(mcphost -p "Summarize this file: $(cat $file)" --quiet)
|
||||
summary=$(kit -p "Summarize this file: $(cat $file)" --quiet)
|
||||
echo "$file: $summary" >> summaries.txt
|
||||
done
|
||||
```
|
||||
@@ -912,27 +910,27 @@ done
|
||||
```bash
|
||||
# Code review automation
|
||||
DIFF=$(git diff HEAD~1)
|
||||
mcphost -p "Review this code diff and suggest improvements: $DIFF" --quiet
|
||||
kit -p "Review this code diff and suggest improvements: $DIFF" --quiet
|
||||
|
||||
# Generate release notes
|
||||
COMMITS=$(git log --oneline HEAD~10..HEAD)
|
||||
mcphost -p "Generate release notes from these commits: $COMMITS" --quiet
|
||||
kit -p "Generate release notes from these commits: $COMMITS" --quiet
|
||||
```
|
||||
|
||||
#### Data Processing
|
||||
```bash
|
||||
# Process CSV data
|
||||
mcphost -p "Analyze this CSV data and provide insights: $(cat data.csv)" --quiet
|
||||
kit -p "Analyze this CSV data and provide insights: $(cat data.csv)" --quiet
|
||||
|
||||
# Generate reports
|
||||
mcphost -p "Create a summary report from this JSON: $(cat metrics.json)" --quiet
|
||||
kit -p "Create a summary report from this JSON: $(cat metrics.json)" --quiet
|
||||
```
|
||||
|
||||
#### API Integration
|
||||
```bash
|
||||
# Use as a microservice
|
||||
curl -X POST http://localhost:8080/process \
|
||||
-d "$(mcphost -p 'Generate a UUID' --quiet)"
|
||||
-d "$(kit -p 'Generate a UUID' --quiet)"
|
||||
```
|
||||
|
||||
### Tips for Scripting
|
||||
@@ -961,12 +959,12 @@ mcpServers:
|
||||
DEBUG: "${env://DEBUG:-false}"
|
||||
|
||||
# Use in scripts
|
||||
mcphost script my-script.sh --args:username alice
|
||||
kit script my-script.sh --args:username alice
|
||||
```
|
||||
|
||||
## MCP Server Compatibility 🔌
|
||||
|
||||
MCPHost can work with any MCP-compliant server. For examples and reference implementations, see the [MCP Servers Repository](https://github.com/modelcontextprotocol/servers).
|
||||
KIT can work with any MCP-compliant server. For examples and reference implementations, see the [MCP Servers Repository](https://github.com/modelcontextprotocol/servers).
|
||||
|
||||
## Contributing 🤝
|
||||
|
||||
|
||||
+9
-9
@@ -6,7 +6,7 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/mark3labs/mcphost/internal/auth"
|
||||
"github.com/mark3labs/kit/internal/auth"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -26,9 +26,9 @@ Available providers:
|
||||
- anthropic: Anthropic Claude API (OAuth)
|
||||
|
||||
Examples:
|
||||
mcphost auth login anthropic
|
||||
mcphost auth logout anthropic
|
||||
mcphost auth status`,
|
||||
kit auth login anthropic
|
||||
kit auth logout anthropic
|
||||
kit auth status`,
|
||||
}
|
||||
|
||||
// authLoginCmd represents the login subcommand for authenticating with AI providers.
|
||||
@@ -47,7 +47,7 @@ Available providers:
|
||||
- anthropic: Anthropic Claude API (OAuth)
|
||||
|
||||
Example:
|
||||
mcphost auth login anthropic`,
|
||||
kit auth login anthropic`,
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: runAuthLogin,
|
||||
}
|
||||
@@ -67,7 +67,7 @@ Available providers:
|
||||
- anthropic: Anthropic Claude API
|
||||
|
||||
Example:
|
||||
mcphost auth logout anthropic`,
|
||||
kit auth logout anthropic`,
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: runAuthLogout,
|
||||
}
|
||||
@@ -84,7 +84,7 @@ This command displays which providers have stored credentials and when they were
|
||||
It does not display the actual API keys for security reasons.
|
||||
|
||||
Example:
|
||||
mcphost auth status`,
|
||||
kit auth status`,
|
||||
RunE: runAuthStatus,
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ func runAuthStatus(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
fmt.Println("\nTo authenticate with a provider:")
|
||||
fmt.Println(" mcphost auth login anthropic")
|
||||
fmt.Println(" kit auth login anthropic")
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -231,7 +231,7 @@ func loginAnthropic() error {
|
||||
fmt.Println("✅ Successfully authenticated with Anthropic!")
|
||||
fmt.Printf("📁 Credentials stored in: %s\n", cm.GetCredentialsPath())
|
||||
fmt.Println("\n🎉 Your OAuth credentials will now be used for Anthropic API calls.")
|
||||
fmt.Println("💡 You can check your authentication status with: mcphost auth status")
|
||||
fmt.Println("💡 You can check your authentication status with: kit auth status")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
+17
-17
@@ -5,18 +5,18 @@ import (
|
||||
"os"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/mark3labs/mcphost/internal/hooks"
|
||||
"github.com/mark3labs/kit/internal/hooks"
|
||||
"github.com/spf13/cobra"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// hooksCmd represents the hooks command for managing MCPHost hook configurations.
|
||||
// hooksCmd represents the hooks command for managing KIT hook configurations.
|
||||
// Hooks allow users to execute custom scripts or commands at various points
|
||||
// during MCPHost execution, such as before/after tool use or when prompts are submitted.
|
||||
// during KIT execution, such as before/after tool use or when prompts are submitted.
|
||||
var hooksCmd = &cobra.Command{
|
||||
Use: "hooks",
|
||||
Short: "Manage MCPHost hooks",
|
||||
Long: "Commands for managing and testing MCPHost hooks configuration",
|
||||
Short: "Manage KIT hooks",
|
||||
Long: "Commands for managing and testing KIT hooks configuration",
|
||||
}
|
||||
|
||||
// hooksListCmd represents the list subcommand for displaying all configured hooks.
|
||||
@@ -74,7 +74,7 @@ var hooksValidateCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
// hooksInitCmd represents the init subcommand for generating an example hooks configuration.
|
||||
// It creates a .mcphost/hooks.yml file with sample hook configurations demonstrating
|
||||
// It creates a .kit/hooks.yml file with sample hook configurations demonstrating
|
||||
// various hook events and common use cases like logging commands and tool usage.
|
||||
var hooksInitCmd = &cobra.Command{
|
||||
Use: "init",
|
||||
@@ -89,7 +89,7 @@ var hooksInitCmd = &cobra.Command{
|
||||
Hooks: []hooks.HookEntry{
|
||||
{
|
||||
Type: "command",
|
||||
Command: `mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/mcphost/logs" && jq -r '"[" + (now | strftime("%Y-%m-%d %H:%M:%S")) + "] $ " + .tool_input.command' >> "${XDG_CONFIG_HOME:-$HOME/.config}/mcphost/logs/bash-commands.log"`,
|
||||
Command: `mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/kit/logs" && jq -r '"[" + (now | strftime("%Y-%m-%d %H:%M:%S")) + "] $ " + .tool_input.command' >> "${XDG_CONFIG_HOME:-$HOME/.config}/kit/logs/bash-commands.log"`,
|
||||
Timeout: 5,
|
||||
},
|
||||
},
|
||||
@@ -99,7 +99,7 @@ var hooksInitCmd = &cobra.Command{
|
||||
Hooks: []hooks.HookEntry{
|
||||
{
|
||||
Type: "command",
|
||||
Command: `jq -c '{time: now | strftime("%Y-%m-%d %H:%M:%S"), event: "pre", tool: .tool_name, input: .tool_input}' >> "${XDG_CONFIG_HOME:-$HOME/.config}/mcphost/logs/all-tools.jsonl"`,
|
||||
Command: `jq -c '{time: now | strftime("%Y-%m-%d %H:%M:%S"), event: "pre", tool: .tool_name, input: .tool_input}' >> "${XDG_CONFIG_HOME:-$HOME/.config}/kit/logs/all-tools.jsonl"`,
|
||||
Timeout: 5,
|
||||
},
|
||||
},
|
||||
@@ -112,7 +112,7 @@ var hooksInitCmd = &cobra.Command{
|
||||
Hooks: []hooks.HookEntry{
|
||||
{
|
||||
Type: "command",
|
||||
Command: `jq -c '{time: now | strftime("%Y-%m-%d %H:%M:%S"), cmd: .tool_input.command, exit: .tool_response._meta.exit, stdout: (.tool_response._meta.stdout | rtrimstr("\n") | .[0:100]), stderr: (.tool_response._meta.stderr | rtrimstr("\n"))}' >> "${XDG_CONFIG_HOME:-$HOME/.config}/mcphost/logs/bash-audit.jsonl"`,
|
||||
Command: `jq -c '{time: now | strftime("%Y-%m-%d %H:%M:%S"), cmd: .tool_input.command, exit: .tool_response._meta.exit, stdout: (.tool_response._meta.stdout | rtrimstr("\n") | .[0:100]), stderr: (.tool_response._meta.stderr | rtrimstr("\n"))}' >> "${XDG_CONFIG_HOME:-$HOME/.config}/kit/logs/bash-audit.jsonl"`,
|
||||
Timeout: 5,
|
||||
},
|
||||
},
|
||||
@@ -122,7 +122,7 @@ var hooksInitCmd = &cobra.Command{
|
||||
Hooks: []hooks.HookEntry{
|
||||
{
|
||||
Type: "command",
|
||||
Command: `jq -c '{time: now | strftime("%Y-%m-%d %H:%M:%S"), tool: .tool_name, response_preview: (.tool_response | tostring | .[0:200])}' >> "${XDG_CONFIG_HOME:-$HOME/.config}/mcphost/logs/mcp-tools.jsonl"`,
|
||||
Command: `jq -c '{time: now | strftime("%Y-%m-%d %H:%M:%S"), tool: .tool_name, response_preview: (.tool_response | tostring | .[0:200])}' >> "${XDG_CONFIG_HOME:-$HOME/.config}/kit/logs/mcp-tools.jsonl"`,
|
||||
Timeout: 5,
|
||||
},
|
||||
},
|
||||
@@ -134,7 +134,7 @@ var hooksInitCmd = &cobra.Command{
|
||||
Hooks: []hooks.HookEntry{
|
||||
{
|
||||
Type: "command",
|
||||
Command: `mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/mcphost/logs" && jq -r '"[" + (now | strftime("%Y-%m-%d %H:%M:%S")) + "] " + .prompt' >> "${XDG_CONFIG_HOME:-$HOME/.config}/mcphost/logs/prompts.log"`,
|
||||
Command: `mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/kit/logs" && jq -r '"[" + (now | strftime("%Y-%m-%d %H:%M:%S")) + "] " + .prompt' >> "${XDG_CONFIG_HOME:-$HOME/.config}/kit/logs/prompts.log"`,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -145,7 +145,7 @@ var hooksInitCmd = &cobra.Command{
|
||||
Hooks: []hooks.HookEntry{
|
||||
{
|
||||
Type: "command",
|
||||
Command: `jq -r '"[" + (now | strftime("%Y-%m-%d %H:%M:%S")) + "] Session " + .session_id + " stopped"' >> "${XDG_CONFIG_HOME:-$HOME/.config}/mcphost/logs/sessions.log"`,
|
||||
Command: `jq -r '"[" + (now | strftime("%Y-%m-%d %H:%M:%S")) + "] Session " + .session_id + " stopped"' >> "${XDG_CONFIG_HOME:-$HOME/.config}/kit/logs/sessions.log"`,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -153,9 +153,9 @@ var hooksInitCmd = &cobra.Command{
|
||||
},
|
||||
}
|
||||
|
||||
// Create .mcphost directory if it doesn't exist
|
||||
if err := os.MkdirAll(".mcphost", 0755); err != nil {
|
||||
return fmt.Errorf("creating .mcphost directory: %w", err)
|
||||
// Create .kit directory if it doesn't exist
|
||||
if err := os.MkdirAll(".kit", 0755); err != nil {
|
||||
return fmt.Errorf("creating .kit directory: %w", err)
|
||||
}
|
||||
|
||||
// Write example configuration
|
||||
@@ -164,11 +164,11 @@ var hooksInitCmd = &cobra.Command{
|
||||
return fmt.Errorf("marshaling example: %w", err)
|
||||
}
|
||||
|
||||
if err := os.WriteFile(".mcphost/hooks.yml", data, 0644); err != nil {
|
||||
if err := os.WriteFile(".kit/hooks.yml", data, 0644); err != nil {
|
||||
return fmt.Errorf("writing example: %w", err)
|
||||
}
|
||||
|
||||
fmt.Println("Created .mcphost/hooks.yml with example configuration")
|
||||
fmt.Println("Created .kit/hooks.yml with example configuration")
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
+10
-10
@@ -4,7 +4,7 @@ import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/mark3labs/mcphost/internal/models"
|
||||
"github.com/mark3labs/kit/internal/models"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -13,22 +13,22 @@ var modelsAllFlag bool
|
||||
var modelsCmd = &cobra.Command{
|
||||
Use: "models [provider]",
|
||||
Short: "List available models from the model database",
|
||||
Long: `List models known to mcphost from the models.dev database.
|
||||
Long: `List models known to kit from the models.dev database.
|
||||
|
||||
By default, shows only providers that mcphost can use (native fantasy
|
||||
By default, shows only providers that kit can use (native fantasy
|
||||
providers plus openai-compatible auto-routed providers). Use --all
|
||||
to show every provider in the database.
|
||||
|
||||
When a provider name is given, shows only that provider's models.
|
||||
|
||||
Note: models not listed here can still be used — the database is
|
||||
advisory. Run 'mcphost update-models' to refresh.
|
||||
advisory. Run 'kit update-models' to refresh.
|
||||
|
||||
Examples:
|
||||
mcphost models
|
||||
mcphost models --all
|
||||
mcphost models anthropic
|
||||
mcphost models deepseek`,
|
||||
kit models
|
||||
kit models --all
|
||||
kit models anthropic
|
||||
kit models deepseek`,
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
RunE: runModels,
|
||||
}
|
||||
@@ -67,7 +67,7 @@ func printAllProviders(registry *models.ModelsRegistry, showAll bool) error {
|
||||
}
|
||||
|
||||
if len(withModels) == 0 {
|
||||
fmt.Println("No models in database. Run 'mcphost update-models' to fetch.")
|
||||
fmt.Println("No models in database. Run 'kit update-models' to fetch.")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ func printAllProviders(registry *models.ModelsRegistry, showAll bool) error {
|
||||
func printProvider(registry *models.ModelsRegistry, provider string) error {
|
||||
m, err := registry.GetModelsForProvider(provider)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unknown provider %q. Run 'mcphost models' to see all providers", provider)
|
||||
return fmt.Errorf("unknown provider %q. Run 'kit models' to see all providers", provider)
|
||||
}
|
||||
|
||||
if len(m) == 0 {
|
||||
|
||||
+31
-31
@@ -10,11 +10,11 @@ import (
|
||||
|
||||
tea "charm.land/bubbletea/v2"
|
||||
"charm.land/fantasy"
|
||||
"github.com/mark3labs/mcphost/internal/agent"
|
||||
"github.com/mark3labs/mcphost/internal/app"
|
||||
"github.com/mark3labs/mcphost/internal/config"
|
||||
"github.com/mark3labs/mcphost/internal/session"
|
||||
"github.com/mark3labs/mcphost/internal/ui"
|
||||
"github.com/mark3labs/kit/internal/agent"
|
||||
"github.com/mark3labs/kit/internal/app"
|
||||
"github.com/mark3labs/kit/internal/config"
|
||||
"github.com/mark3labs/kit/internal/session"
|
||||
"github.com/mark3labs/kit/internal/ui"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"golang.org/x/term"
|
||||
@@ -80,13 +80,13 @@ func (a *agentUIAdapter) GetLoadedServerNames() []string {
|
||||
}
|
||||
|
||||
// rootCmd represents the base command when called without any subcommands.
|
||||
// This is the main entry point for the MCPHost CLI application, providing
|
||||
// This is the main entry point for the KIT CLI application, providing
|
||||
// an interface to interact with various AI models through a unified interface
|
||||
// with support for MCP servers and tool integration.
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "mcphost",
|
||||
Use: "kit",
|
||||
Short: "Chat with AI models through a unified interface",
|
||||
Long: `MCPHost is a CLI tool that allows you to interact with various AI models
|
||||
Long: `KIT is a CLI tool that allows you to interact with various AI models
|
||||
through a unified interface. It supports various tools through MCP servers
|
||||
and provides streaming responses.
|
||||
|
||||
@@ -98,41 +98,41 @@ Available models can be specified using the --model flag:
|
||||
|
||||
Examples:
|
||||
# Interactive mode
|
||||
mcphost -m ollama/qwen2.5:3b
|
||||
mcphost -m openai/gpt-4
|
||||
mcphost -m google/gemini-2.0-flash
|
||||
kit -m ollama/qwen2.5:3b
|
||||
kit -m openai/gpt-4
|
||||
kit -m google/gemini-2.0-flash
|
||||
|
||||
# Non-interactive mode
|
||||
mcphost -p "What is the weather like today?"
|
||||
mcphost -p "Calculate 15 * 23" --quiet
|
||||
kit -p "What is the weather like today?"
|
||||
kit -p "Calculate 15 * 23" --quiet
|
||||
|
||||
# Session management
|
||||
mcphost --save-session ./my-session.json -p "Hello"
|
||||
mcphost --load-session ./my-session.json -p "Continue our conversation"
|
||||
mcphost --load-session ./session.json --save-session ./session.json -p "Next message"
|
||||
mcphost --session ./session.json -p "Next message"
|
||||
kit --save-session ./my-session.json -p "Hello"
|
||||
kit --load-session ./my-session.json -p "Continue our conversation"
|
||||
kit --load-session ./session.json --save-session ./session.json -p "Next message"
|
||||
kit --session ./session.json -p "Next message"
|
||||
|
||||
# Script mode
|
||||
mcphost script myscript.sh`,
|
||||
kit script myscript.sh`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return runMCPHost(context.Background())
|
||||
return runKit(context.Background())
|
||||
},
|
||||
}
|
||||
|
||||
// GetRootCommand returns the root command with the version set.
|
||||
// This function is the main entry point for the MCPHost CLI and should be
|
||||
// This function is the main entry point for the KIT CLI and should be
|
||||
// called from main.go with the appropriate version string.
|
||||
func GetRootCommand(v string) *cobra.Command {
|
||||
rootCmd.Version = v
|
||||
return rootCmd
|
||||
}
|
||||
|
||||
// InitConfig initializes the configuration for MCPHost by loading config files,
|
||||
// InitConfig initializes the configuration for KIT by loading config files,
|
||||
// environment variables, and hooks configuration. It follows this priority order:
|
||||
// 1. Command-line specified config file (--config flag)
|
||||
// 2. Current directory config file (.mcphost or .mcp)
|
||||
// 3. Home directory config file (~/.mcphost or ~/.mcp)
|
||||
// 4. Environment variables (MCPHOST_* prefix)
|
||||
// 2. Current directory config file (.kit)
|
||||
// 3. Home directory config file (~/.kit)
|
||||
// 4. Environment variables (KIT_* prefix)
|
||||
// This function is automatically called by cobra before command execution.
|
||||
func InitConfig() {
|
||||
if configFile != "" {
|
||||
@@ -162,7 +162,7 @@ func InitConfig() {
|
||||
|
||||
// Try to find and load config file using viper's search mechanism
|
||||
configLoaded := false
|
||||
configNames := []string{".mcphost", ".mcp"} // Try .mcphost first, then legacy .mcp
|
||||
configNames := []string{".kit"}
|
||||
|
||||
for _, name := range configNames {
|
||||
viper.SetConfigName(name)
|
||||
@@ -192,7 +192,7 @@ func InitConfig() {
|
||||
}
|
||||
|
||||
// Set environment variable prefix
|
||||
viper.SetEnvPrefix("MCPHOST")
|
||||
viper.SetEnvPrefix("KIT")
|
||||
viper.AutomaticEnv()
|
||||
|
||||
}
|
||||
@@ -261,7 +261,7 @@ func init() {
|
||||
}
|
||||
|
||||
rootCmd.PersistentFlags().
|
||||
StringVar(&configFile, "config", "", "config file (default is $HOME/.mcp.json)")
|
||||
StringVar(&configFile, "config", "", "config file (default is $HOME/.kit.yml)")
|
||||
rootCmd.PersistentFlags().
|
||||
StringVar(&systemPromptFile, "system-prompt", "", "system prompt text or path to text file")
|
||||
|
||||
@@ -332,7 +332,7 @@ func init() {
|
||||
rootCmd.AddCommand(authCmd)
|
||||
}
|
||||
|
||||
func runMCPHost(ctx context.Context) error {
|
||||
func runKit(ctx context.Context) error {
|
||||
return runNormalMode(ctx)
|
||||
}
|
||||
|
||||
@@ -538,9 +538,9 @@ func runNormalMode(ctx context.Context) error {
|
||||
|
||||
// Set metadata
|
||||
_ = sessionManager.SetMetadata(session.Metadata{
|
||||
MCPHostVersion: "dev", // TODO: Get actual version
|
||||
Provider: parsedProvider,
|
||||
Model: modelName,
|
||||
KitVersion: "dev", // TODO: Get actual version
|
||||
Provider: parsedProvider,
|
||||
Model: modelName,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -9,15 +9,15 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/mark3labs/mcphost/internal/app"
|
||||
"github.com/mark3labs/mcphost/internal/config"
|
||||
"github.com/mark3labs/mcphost/internal/ui"
|
||||
"github.com/mark3labs/kit/internal/app"
|
||||
"github.com/mark3labs/kit/internal/config"
|
||||
"github.com/mark3labs/kit/internal/ui"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// scriptCmd represents the script command for executing MCPHost script files.
|
||||
// scriptCmd represents the script command for executing KIT script files.
|
||||
// Script files can contain YAML frontmatter configuration followed by a prompt,
|
||||
// allowing for reproducible AI interactions with custom configurations and
|
||||
// variable substitution support.
|
||||
@@ -47,7 +47,7 @@ Variables in the script can be substituted using ${variable} syntax.
|
||||
Variables can have default values using ${variable:-default} syntax.
|
||||
Pass variables using --args:variable value syntax:
|
||||
|
||||
mcphost script myscript.sh --args:directory /tmp --args:name "John"
|
||||
kit script myscript.sh --args:directory /tmp --args:name "John"
|
||||
|
||||
This will replace ${directory} with "/tmp" and ${name} with "John" in the script.
|
||||
Variables with defaults (${var:-default}) are optional and use the default if not provided.`,
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/mark3labs/mcphost/internal/models"
|
||||
"github.com/mark3labs/kit/internal/models"
|
||||
)
|
||||
|
||||
// TestDeepSeekChatScriptMode tests the regression where deepseek-chat model
|
||||
@@ -18,7 +18,7 @@ func TestDeepSeekChatScriptMode(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
scriptPath := filepath.Join(tempDir, "deepseek-script.sh")
|
||||
|
||||
scriptContent := `#!/usr/bin/env -S mcphost script
|
||||
scriptContent := `#!/usr/bin/env -S kit script
|
||||
---
|
||||
model: "openai/deepseek-chat"
|
||||
provider-url: "https://api.deepseek.com/v1"
|
||||
|
||||
@@ -12,7 +12,7 @@ func TestScriptWithEnvAndArgsSubstitution(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
scriptPath := filepath.Join(tempDir, "test-script.sh")
|
||||
|
||||
scriptContent := `#!/usr/bin/env -S mcphost script
|
||||
scriptContent := `#!/usr/bin/env -S kit script
|
||||
---
|
||||
mcpServers:
|
||||
github:
|
||||
@@ -113,7 +113,7 @@ func TestScriptWithMissingRequiredEnvVar(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
scriptPath := filepath.Join(tempDir, "test-script.sh")
|
||||
|
||||
scriptContent := `#!/usr/bin/env -S mcphost script
|
||||
scriptContent := `#!/usr/bin/env -S kit script
|
||||
---
|
||||
mcpServers:
|
||||
github:
|
||||
@@ -150,7 +150,7 @@ func TestScriptWithMissingRequiredArg(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
scriptPath := filepath.Join(tempDir, "test-script.sh")
|
||||
|
||||
scriptContent := `#!/usr/bin/env -S mcphost script
|
||||
scriptContent := `#!/usr/bin/env -S kit script
|
||||
---
|
||||
mcpServers:
|
||||
github:
|
||||
@@ -185,7 +185,7 @@ func TestScriptProcessingOrder(t *testing.T) {
|
||||
scriptPath := filepath.Join(tempDir, "test-script.sh")
|
||||
|
||||
// This script tests that env vars are processed first, then script args
|
||||
scriptContent := `#!/usr/bin/env -S mcphost script
|
||||
scriptContent := `#!/usr/bin/env -S kit script
|
||||
---
|
||||
mcpServers:
|
||||
test:
|
||||
@@ -241,7 +241,7 @@ func TestScriptBackwardCompatibility(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
scriptPath := filepath.Join(tempDir, "test-script.sh")
|
||||
|
||||
scriptContent := `#!/usr/bin/env -S mcphost script
|
||||
scriptContent := `#!/usr/bin/env -S kit script
|
||||
---
|
||||
mcpServers:
|
||||
filesystem:
|
||||
|
||||
+6
-6
@@ -5,12 +5,12 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/mark3labs/mcphost/internal/agent"
|
||||
"github.com/mark3labs/mcphost/internal/app"
|
||||
"github.com/mark3labs/mcphost/internal/config"
|
||||
"github.com/mark3labs/mcphost/internal/models"
|
||||
"github.com/mark3labs/mcphost/internal/tools"
|
||||
"github.com/mark3labs/mcphost/internal/ui"
|
||||
"github.com/mark3labs/kit/internal/agent"
|
||||
"github.com/mark3labs/kit/internal/app"
|
||||
"github.com/mark3labs/kit/internal/config"
|
||||
"github.com/mark3labs/kit/internal/models"
|
||||
"github.com/mark3labs/kit/internal/tools"
|
||||
"github.com/mark3labs/kit/internal/ui"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/mark3labs/mcphost/internal/models"
|
||||
"github.com/mark3labs/kit/internal/models"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -26,16 +26,16 @@ detection, and model suggestions.
|
||||
When run without arguments, fetches from models.dev.
|
||||
|
||||
Sources:
|
||||
(none) Fetch from models.dev (or MCPHOST_MODELS_URL override)
|
||||
(none) Fetch from models.dev (or KIT_MODELS_URL override)
|
||||
<url> Fetch from a custom URL
|
||||
<file> Load from a local JSON file
|
||||
embedded Reset to the built-in database shipped with this binary
|
||||
|
||||
Examples:
|
||||
mcphost update-models
|
||||
mcphost update-models https://models.dev/api.json
|
||||
mcphost update-models /path/to/models.json
|
||||
mcphost update-models embedded`,
|
||||
kit update-models
|
||||
kit update-models https://models.dev/api.json
|
||||
kit update-models /path/to/models.json
|
||||
kit update-models embedded`,
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
RunE: runUpdateModels,
|
||||
}
|
||||
@@ -56,7 +56,7 @@ func runUpdateModels(_ *cobra.Command, args []string) error {
|
||||
|
||||
case source == "":
|
||||
url := defaultModelsURL
|
||||
if override := os.Getenv("MCPHOST_MODELS_URL"); override != "" {
|
||||
if override := os.Getenv("KIT_MODELS_URL"); override != "" {
|
||||
url = override
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "Fetching models from %s...\n", url)
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
./output/mcphost --model openai:<your-model-name> \
|
||||
./output/kit --model openai:<your-model-name> \
|
||||
--openai-url <your-base-url> \
|
||||
--openai-api-key <your-api-key> \
|
||||
--config ./conf/demo.json --debug
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
RUN_NAME="mcphost"
|
||||
RUN_NAME="kit"
|
||||
|
||||
mkdir -p output
|
||||
go build -o output/${RUN_NAME}
|
||||
@@ -3,12 +3,12 @@ Thanks for your contribution, you can follow these step to run this repo and deb
|
||||
## Run demo
|
||||
1. clone this repo to your work dir.
|
||||
```bash
|
||||
git clone https://github.com/mark3labs/mcphost.git
|
||||
git clone https://github.com/mark3labs/kit.git
|
||||
```
|
||||
|
||||
2. enter the `contribute` dir.
|
||||
```bash
|
||||
cd mcphost/contribute
|
||||
cd kit/contribute
|
||||
```
|
||||
|
||||
3. run `build.sh` to build your binary file.
|
||||
@@ -22,7 +22,7 @@ Thanks for your contribution, you can follow these step to run this repo and deb
|
||||
vi boost.sh
|
||||
```
|
||||
|
||||
5. run `boost.sh` to run your mcphost, if you don't want run it in debug model, you can delete the `--debug` flag in `boost.sh`.
|
||||
5. run `boost.sh` to run kit, if you don't want run it in debug model, you can delete the `--debug` flag in `boost.sh`.
|
||||
```bash
|
||||
./boost.sh
|
||||
```
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"""
|
||||
Monitors MCP tool usage and enforces policies.
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
import re
|
||||
@@ -11,62 +12,65 @@ from datetime import datetime
|
||||
# Define MCP tool policies
|
||||
BLOCKED_MCP_TOOLS = [
|
||||
"mcp__github__delete_.*", # Block all GitHub delete operations
|
||||
"mcp__aws__.*_production", # Block production AWS operations
|
||||
"mcp__aws__.*_production", # Block production AWS operations
|
||||
]
|
||||
|
||||
RATE_LIMITS = {
|
||||
"mcp__openai__.*": (10, 60), # 10 calls per 60 seconds
|
||||
}
|
||||
|
||||
|
||||
def check_rate_limit(tool_name, limits):
|
||||
# This is a simplified example - real implementation would need persistent storage
|
||||
# For now, just log the attempt
|
||||
return True
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
input_data = json.load(sys.stdin)
|
||||
tool_name = input_data.get('tool_name', '')
|
||||
|
||||
tool_name = input_data.get("tool_name", "")
|
||||
|
||||
# Check if tool is blocked
|
||||
for pattern in BLOCKED_MCP_TOOLS:
|
||||
if re.match(pattern, tool_name):
|
||||
output = {
|
||||
"decision": "block",
|
||||
"reason": f"Tool {tool_name} is blocked by security policy"
|
||||
"reason": f"Tool {tool_name} is blocked by security policy",
|
||||
}
|
||||
print(json.dumps(output))
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
# Check rate limits
|
||||
for pattern, (limit, window) in RATE_LIMITS.items():
|
||||
if re.match(pattern, tool_name):
|
||||
if not check_rate_limit(tool_name, (limit, window)):
|
||||
output = {
|
||||
"decision": "block",
|
||||
"reason": f"Rate limit exceeded: {limit} calls per {window}s"
|
||||
"reason": f"Rate limit exceeded: {limit} calls per {window}s",
|
||||
}
|
||||
print(json.dumps(output))
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
# Log MCP tool usage
|
||||
log_entry = {
|
||||
"timestamp": datetime.now().isoformat(),
|
||||
"tool": tool_name,
|
||||
"input": input_data.get('tool_input', {})
|
||||
"input": input_data.get("tool_input", {}),
|
||||
}
|
||||
|
||||
|
||||
# Use XDG_CONFIG_HOME if set, otherwise default to ~/.config
|
||||
config_home = os.environ.get('XDG_CONFIG_HOME', os.path.expanduser('~/.config'))
|
||||
log_dir = os.path.join(config_home, 'mcphost', 'logs')
|
||||
config_home = os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config"))
|
||||
log_dir = os.path.join(config_home, "kit", "logs")
|
||||
os.makedirs(log_dir, exist_ok=True)
|
||||
|
||||
|
||||
with open(os.path.join(log_dir, "mcp-usage.jsonl"), "a") as f:
|
||||
f.write(json.dumps(log_entry) + "\n")
|
||||
|
||||
|
||||
except Exception as e:
|
||||
print(f"Hook error: {e}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main()
|
||||
|
||||
@@ -10,7 +10,7 @@ prompt=$(echo "$input" | jq -r '.prompt // empty')
|
||||
if [ -n "$prompt" ]; then
|
||||
# Use XDG_CONFIG_HOME if set, otherwise default to ~/.config
|
||||
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}"
|
||||
LOG_DIR="$CONFIG_DIR/mcphost/logs"
|
||||
LOG_DIR="$CONFIG_DIR/kit/logs"
|
||||
|
||||
# Create log directory if it doesn't exist
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
||||
+10
-10
@@ -1,6 +1,6 @@
|
||||
# MCPHost Script Examples
|
||||
# KIT Script Examples
|
||||
|
||||
This directory contains example scripts demonstrating various features of MCPHost's script mode.
|
||||
This directory contains example scripts demonstrating various features of KIT's script mode.
|
||||
|
||||
## Scripts
|
||||
|
||||
@@ -16,13 +16,13 @@ Demonstrates the new default values feature for script variables.
|
||||
**Usage:**
|
||||
```bash
|
||||
# Use all defaults
|
||||
mcphost script default-values-demo.sh
|
||||
kit script default-values-demo.sh
|
||||
|
||||
# Override specific variables
|
||||
mcphost script default-values-demo.sh --args:user_name "John" --args:work_dir "/projects"
|
||||
kit script default-values-demo.sh --args:user_name "John" --args:work_dir "/projects"
|
||||
|
||||
# Override multiple variables
|
||||
mcphost script default-values-demo.sh \
|
||||
kit script default-values-demo.sh \
|
||||
--args:user_name "Alice" \
|
||||
--args:editor "vim" \
|
||||
--args:format "json"
|
||||
@@ -39,20 +39,20 @@ Demonstrates TLS skip verify for connecting to providers with self-signed certif
|
||||
**Usage:**
|
||||
```bash
|
||||
# Run with TLS skip verify enabled (configured in script)
|
||||
mcphost script tls-test-script.sh
|
||||
kit script tls-test-script.sh
|
||||
|
||||
# Override the provider URL
|
||||
mcphost script tls-test-script.sh --provider-url https://192.168.1.100:443
|
||||
kit script tls-test-script.sh --provider-url https://192.168.1.100:443
|
||||
|
||||
# Disable TLS skip verify via command line (overrides script config)
|
||||
mcphost script tls-test-script.sh --tls-skip-verify=false
|
||||
kit script tls-test-script.sh --tls-skip-verify=false
|
||||
```
|
||||
|
||||
⚠️ **WARNING**: Only use `tls-skip-verify` for development or when connecting to trusted servers with self-signed certificates.
|
||||
|
||||
## Variable Syntax Reference
|
||||
|
||||
MCPHost scripts support two types of variables:
|
||||
KIT scripts support two types of variables:
|
||||
|
||||
### Required Variables
|
||||
```bash
|
||||
@@ -80,4 +80,4 @@ ${variable:-default_value}
|
||||
|
||||
## Backward Compatibility
|
||||
|
||||
All existing scripts using `${variable}` syntax continue to work unchanged. The new default syntax is purely additive.
|
||||
All existing scripts using `${variable}` syntax continue to work unchanged. The new default syntax is purely additive.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env -S mcphost script
|
||||
#!/usr/bin/env -S kit script
|
||||
---
|
||||
# Demo script showcasing default values in MCPHost scripts
|
||||
# Demo script showcasing default values in KIT scripts
|
||||
model: "anthropic/claude-sonnet-4-5-20250929"
|
||||
mcpServers:
|
||||
filesystem:
|
||||
@@ -19,7 +19,7 @@ mcpServers:
|
||||
|
||||
Hello ${user_name:-Anonymous User}!
|
||||
|
||||
This script demonstrates the new default values feature in MCPHost scripts.
|
||||
This script demonstrates the new default values feature in KIT scripts.
|
||||
|
||||
## Your Configuration:
|
||||
- Working directory: ${work_dir:-/tmp}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env -S mcphost script
|
||||
#!/usr/bin/env -S kit script
|
||||
---
|
||||
# Example script demonstrating both environment variable and script argument substitution
|
||||
# Environment variables are processed first, then script arguments
|
||||
@@ -31,7 +31,7 @@ Working directory is ${env://WORK_DIR:-/tmp}.
|
||||
# export WORK_DIR="/home/user/projects"
|
||||
#
|
||||
# 2. Run with script arguments:
|
||||
# mcphost script env-substitution-script.sh --args:username alice --args:repo_type private --args:count 5
|
||||
# kit script env-substitution-script.sh --args:username alice --args:repo_type private --args:count 5
|
||||
#
|
||||
# This will:
|
||||
# - Use GITHUB_TOKEN from environment
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env -S mcphost script
|
||||
#!/usr/bin/env -S kit script
|
||||
---
|
||||
# This script uses the container-use MCP server from https://github.com/dagger/container-use
|
||||
mcpServers:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env -S mcphost script
|
||||
#!/usr/bin/env -S kit script
|
||||
Hello! This is a simple script that uses the default MCP configuration.
|
||||
What's 2 + 2?
|
||||
What tools do you have?
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env -S mcphost script
|
||||
#!/usr/bin/env -S kit script
|
||||
---
|
||||
# Example script demonstrating TLS skip verify for self-signed certificates
|
||||
model: "ollama/llama3.2"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
module github.com/mark3labs/mcphost
|
||||
module github.com/mark3labs/kit
|
||||
|
||||
go 1.26.0
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@ import (
|
||||
|
||||
"charm.land/fantasy"
|
||||
|
||||
"github.com/mark3labs/mcphost/internal/config"
|
||||
"github.com/mark3labs/mcphost/internal/models"
|
||||
"github.com/mark3labs/mcphost/internal/tools"
|
||||
"github.com/mark3labs/kit/internal/config"
|
||||
"github.com/mark3labs/kit/internal/models"
|
||||
"github.com/mark3labs/kit/internal/tools"
|
||||
)
|
||||
|
||||
// AgentConfig holds configuration options for creating a new Agent.
|
||||
@@ -141,7 +141,7 @@ func (a *Agent) GenerateWithLoop(ctx context.Context, messages []fantasy.Message
|
||||
|
||||
// GenerateWithLoopAndStreaming processes messages using the fantasy agent with streaming and callbacks.
|
||||
// Fantasy handles the tool call loop internally. We map fantasy's rich callback system
|
||||
// to mcphost's existing callback interface for UI integration.
|
||||
// to kit's existing callback interface for UI integration.
|
||||
func (a *Agent) GenerateWithLoopAndStreaming(ctx context.Context, messages []fantasy.Message,
|
||||
onToolCall ToolCallHandler, onToolExecution ToolExecutionHandler, onToolResult ToolResultHandler,
|
||||
onResponse ResponseHandler, onToolCallContent ToolCallContentHandler,
|
||||
|
||||
@@ -4,9 +4,9 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/mark3labs/mcphost/internal/config"
|
||||
"github.com/mark3labs/mcphost/internal/models"
|
||||
"github.com/mark3labs/mcphost/internal/tools"
|
||||
"github.com/mark3labs/kit/internal/config"
|
||||
"github.com/mark3labs/kit/internal/models"
|
||||
"github.com/mark3labs/kit/internal/tools"
|
||||
)
|
||||
|
||||
// SpinnerFunc is a function type for showing spinners during agent creation.
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import (
|
||||
tea "charm.land/bubbletea/v2"
|
||||
"charm.land/fantasy"
|
||||
|
||||
"github.com/mark3labs/mcphost/internal/agent"
|
||||
"github.com/mark3labs/kit/internal/agent"
|
||||
)
|
||||
|
||||
// App is the application-layer orchestrator. It owns the agentic loop,
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
"charm.land/fantasy"
|
||||
|
||||
"github.com/mark3labs/mcphost/internal/agent"
|
||||
"github.com/mark3labs/kit/internal/agent"
|
||||
)
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"sync"
|
||||
|
||||
"charm.land/fantasy"
|
||||
"github.com/mark3labs/mcphost/internal/session"
|
||||
"github.com/mark3labs/kit/internal/session"
|
||||
)
|
||||
|
||||
// MessageStore is a thread-safe store for the conversation history. It wraps a
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"charm.land/fantasy"
|
||||
"github.com/mark3labs/mcphost/internal/session"
|
||||
"github.com/mark3labs/kit/internal/session"
|
||||
)
|
||||
|
||||
// makeTextMsg builds a minimal fantasy.Message with a single TextPart.
|
||||
|
||||
@@ -5,9 +5,9 @@ import (
|
||||
|
||||
"charm.land/fantasy"
|
||||
|
||||
"github.com/mark3labs/mcphost/internal/agent"
|
||||
"github.com/mark3labs/mcphost/internal/config"
|
||||
"github.com/mark3labs/mcphost/internal/session"
|
||||
"github.com/mark3labs/kit/internal/agent"
|
||||
"github.com/mark3labs/kit/internal/config"
|
||||
"github.com/mark3labs/kit/internal/session"
|
||||
)
|
||||
|
||||
// AgentRunner is the minimal interface the app layer requires from the agent
|
||||
|
||||
@@ -57,7 +57,7 @@ type CredentialManager struct {
|
||||
|
||||
// NewCredentialManager creates a new credential manager instance. It determines
|
||||
// the appropriate credentials path based on XDG_CONFIG_HOME or falls back to
|
||||
// ~/.config/.mcphost/credentials.json. Returns an error if the home directory
|
||||
// ~/.config/.kit/credentials.json. Returns an error if the home directory
|
||||
// cannot be determined.
|
||||
func NewCredentialManager() (*CredentialManager, error) {
|
||||
credentialsPath, err := getCredentialsPath()
|
||||
@@ -74,16 +74,16 @@ func NewCredentialManager() (*CredentialManager, error) {
|
||||
func getCredentialsPath() (string, error) {
|
||||
// Try XDG_CONFIG_HOME first
|
||||
if xdgConfig := os.Getenv("XDG_CONFIG_HOME"); xdgConfig != "" {
|
||||
return filepath.Join(xdgConfig, ".mcphost", "credentials.json"), nil
|
||||
return filepath.Join(xdgConfig, ".kit", "credentials.json"), nil
|
||||
}
|
||||
|
||||
// Fall back to ~/.config/.mcphost/credentials.json
|
||||
// Fall back to ~/.config/.kit/credentials.json
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get home directory: %w", err)
|
||||
}
|
||||
|
||||
return filepath.Join(homeDir, ".config", ".mcphost", "credentials.json"), nil
|
||||
return filepath.Join(homeDir, ".config", ".kit", "credentials.json"), nil
|
||||
}
|
||||
|
||||
// LoadCredentials loads credentials from the JSON file. If the file doesn't exist,
|
||||
@@ -272,5 +272,5 @@ func GetAnthropicAPIKey(flagValue string) (string, string, error) {
|
||||
return envKey, "ANTHROPIC_API_KEY environment variable", nil
|
||||
}
|
||||
|
||||
return "", "", fmt.Errorf("no Anthropic API key found. Use 'mcphost auth login anthropic', set ANTHROPIC_API_KEY environment variable, or use --provider-api-key flag")
|
||||
return "", "", fmt.Errorf("no Anthropic API key found. Use 'kit auth login anthropic', set ANTHROPIC_API_KEY environment variable, or use --provider-api-key flag")
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
|
||||
func TestCredentialManager(t *testing.T) {
|
||||
// Create a temporary directory for testing
|
||||
tempDir, err := os.MkdirTemp("", "mcphost-auth-test")
|
||||
tempDir, err := os.MkdirTemp("", "kit-auth-test")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp dir: %v", err)
|
||||
}
|
||||
@@ -125,7 +125,7 @@ func TestValidateAnthropicAPIKey(t *testing.T) {
|
||||
|
||||
func TestGetAnthropicAPIKey(t *testing.T) {
|
||||
// Create a temporary directory for testing
|
||||
tempDir, err := os.MkdirTemp("", "mcphost-auth-test")
|
||||
tempDir, err := os.MkdirTemp("", "kit-auth-test")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp dir: %v", err)
|
||||
}
|
||||
@@ -210,7 +210,7 @@ func TestGetAnthropicAPIKey(t *testing.T) {
|
||||
|
||||
func TestCredentialStorePersistence(t *testing.T) {
|
||||
// Create a temporary directory for testing
|
||||
tempDir, err := os.MkdirTemp("", "mcphost-auth-test")
|
||||
tempDir, err := os.MkdirTemp("", "kit-auth-test")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp dir: %v", err)
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ Usage notes:
|
||||
- It is very helpful if you write a clear, concise description of what this command does in 5-10 words.
|
||||
- If the output exceeds 30000 characters, output will be truncated before being returned to you.
|
||||
- VERY IMPORTANT: You MUST avoid using search commands like find and grep. Instead use Grep, Glob, or Task to search. You MUST avoid read tools like cat, head, tail, and ls, and use Read and LS to read files.
|
||||
- If you _still_ need to run grep, STOP. ALWAYS USE ripgrep at rg (or /usr/bin/rg) first, which all mcphost users have pre-installed.
|
||||
- If you _still_ need to run grep, STOP. ALWAYS USE ripgrep at rg (or /usr/bin/rg) first, which all kit users have pre-installed.
|
||||
- When issuing multiple commands, use the ';' or '&&' operator to separate them. DO NOT use newlines (newlines are ok in quoted strings).
|
||||
- Try to maintain your current working directory throughout the session by using absolute paths and avoiding usage of cd. You may use cd if the User explicitly requests it.
|
||||
<good-example>
|
||||
|
||||
@@ -264,16 +264,16 @@ func LoadSystemPrompt(input string) (string, error) {
|
||||
}
|
||||
|
||||
// EnsureConfigExists checks if a config file exists and creates a default one if not.
|
||||
// It searches for .mcphost.{yml,yaml,json} or legacy .mcp.{yml,yaml,json} files in
|
||||
// the user's home directory. If none exist, creates a default .mcphost.yml with examples.
|
||||
// It searches for .kit.{yml,yaml,json} files in the user's home directory.
|
||||
// If none exist, creates a default .kit.yml with examples.
|
||||
func EnsureConfigExists() error {
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error getting home directory: %v", err)
|
||||
}
|
||||
|
||||
// Check for existing config files (new format first, then legacy)
|
||||
configNames := []string{".mcphost", ".mcp"}
|
||||
// Check for existing config files
|
||||
configNames := []string{".kit"}
|
||||
configTypes := []string{"yml", "yaml", "json"}
|
||||
|
||||
for _, configName := range configNames {
|
||||
@@ -290,9 +290,9 @@ func EnsureConfigExists() error {
|
||||
return createDefaultConfig(homeDir)
|
||||
}
|
||||
|
||||
// createDefaultConfig creates a default .mcphost.yml file in the user's home directory
|
||||
// createDefaultConfig creates a default .kit.yml file in the user's home directory
|
||||
func createDefaultConfig(homeDir string) error {
|
||||
configPath := filepath.Join(homeDir, ".mcphost.yml")
|
||||
configPath := filepath.Join(homeDir, ".kit.yml")
|
||||
|
||||
// Create the file
|
||||
file, err := os.Create(configPath)
|
||||
@@ -302,7 +302,7 @@ func createDefaultConfig(homeDir string) error {
|
||||
defer func() { _ = file.Close() }()
|
||||
|
||||
// Write a comprehensive YAML template with examples
|
||||
content := `# MCPHost Configuration File
|
||||
content := `# KIT Configuration File
|
||||
# All command-line flags can be configured here
|
||||
# This demonstrates the simplified local/remote/builtin server configuration
|
||||
|
||||
|
||||
@@ -207,7 +207,7 @@ func TestConfig_Validate(t *testing.T) {
|
||||
|
||||
func TestEnsureConfigExists(t *testing.T) {
|
||||
// Create a temporary directory for testing
|
||||
tempDir, err := os.MkdirTemp("", "mcphost_config_test")
|
||||
tempDir, err := os.MkdirTemp("", "kit_config_test")
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating temp dir: %v", err)
|
||||
}
|
||||
@@ -225,7 +225,7 @@ func TestEnsureConfigExists(t *testing.T) {
|
||||
}
|
||||
|
||||
// Verify the config file was created
|
||||
configPath := filepath.Join(tempDir, ".mcphost.yml")
|
||||
configPath := filepath.Join(tempDir, ".kit.yml")
|
||||
if _, err := os.Stat(configPath); os.IsNotExist(err) {
|
||||
t.Fatalf("Config file was not created at %s", configPath)
|
||||
}
|
||||
@@ -240,7 +240,7 @@ func TestEnsureConfigExists(t *testing.T) {
|
||||
|
||||
// Verify it contains the expected sections
|
||||
expectedSections := []string{
|
||||
"# MCPHost Configuration File",
|
||||
"# KIT Configuration File",
|
||||
"mcpServers:",
|
||||
"# Local MCP servers",
|
||||
"# Builtin MCP servers",
|
||||
@@ -437,11 +437,11 @@ func TestMCPServerConfig_RemoteFormatWithHeaders(t *testing.T) {
|
||||
name: "Legacy remote server with headers",
|
||||
jsonData: `{
|
||||
"url": "https://legacy.example.com/mcp",
|
||||
"headers": ["Content-Type: application/json", "User-Agent: MCPHost/1.0"]
|
||||
"headers": ["Content-Type: application/json", "User-Agent: KIT/1.0"]
|
||||
}`,
|
||||
expectedType: "",
|
||||
expectedURL: "https://legacy.example.com/mcp",
|
||||
expectedHeaders: []string{"Content-Type: application/json", "User-Agent: MCPHost/1.0"},
|
||||
expectedHeaders: []string{"Content-Type: application/json", "User-Agent: KIT/1.0"},
|
||||
expectedTransport: "sse",
|
||||
},
|
||||
{
|
||||
@@ -558,7 +558,7 @@ func TestMCPServerConfig_HeadersParsing(t *testing.T) {
|
||||
|
||||
func TestEnsureConfigExistsWhenFileExists(t *testing.T) {
|
||||
// Create a temporary directory for testing
|
||||
tempDir, err := os.MkdirTemp("", "mcphost_config_test")
|
||||
tempDir, err := os.MkdirTemp("", "kit_config_test")
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating temp dir: %v", err)
|
||||
}
|
||||
@@ -570,7 +570,7 @@ func TestEnsureConfigExistsWhenFileExists(t *testing.T) {
|
||||
defer func() { _ = os.Setenv("HOME", oldHome) }()
|
||||
|
||||
// Create an existing config file
|
||||
configPath := filepath.Join(tempDir, ".mcphost.yml")
|
||||
configPath := filepath.Join(tempDir, ".kit.yml")
|
||||
existingContent := "# Existing config\nmcpServers:\n test: {}\n"
|
||||
err = os.WriteFile(configPath, []byte(existingContent), 0644)
|
||||
if err != nil {
|
||||
|
||||
@@ -3,7 +3,7 @@ package hooks
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/mark3labs/mcphost/internal/config"
|
||||
"github.com/mark3labs/kit/internal/config"
|
||||
"gopkg.in/yaml.v3"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -35,7 +35,7 @@ type HookEntry struct {
|
||||
|
||||
// LoadHooksConfig loads and merges hook configurations from multiple sources.
|
||||
// It searches for hooks.{json,yml} files in standard locations (XDG config directory,
|
||||
// local .mcphost directory) and any custom paths provided. Configurations are merged
|
||||
// local .kit directory) and any custom paths provided. Configurations are merged
|
||||
// with later sources taking precedence. Environment variable substitution is applied
|
||||
// to all loaded configurations.
|
||||
func LoadHooksConfig(customPaths ...string) (*HookConfig, error) {
|
||||
@@ -44,10 +44,10 @@ func LoadHooksConfig(customPaths ...string) (*HookConfig, error) {
|
||||
|
||||
// Define search paths in order of precedence (lowest to highest)
|
||||
searchPaths := []string{
|
||||
filepath.Join(configDir, "mcphost", "hooks.json"),
|
||||
filepath.Join(configDir, "mcphost", "hooks.yml"),
|
||||
".mcphost/hooks.json",
|
||||
".mcphost/hooks.yml",
|
||||
filepath.Join(configDir, "kit", "hooks.json"),
|
||||
filepath.Join(configDir, "kit", "hooks.yml"),
|
||||
".kit/hooks.json",
|
||||
".kit/hooks.yml",
|
||||
}
|
||||
|
||||
// Add custom paths with highest precedence
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package hooks
|
||||
|
||||
// HookEvent represents a point in MCPHost's lifecycle where hooks can be executed.
|
||||
// HookEvent represents a point in KIT's lifecycle where hooks can be executed.
|
||||
// Events can be tool-related (requiring matchers) or lifecycle-related.
|
||||
type HookEvent string
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Executor handles hook execution for MCPHost lifecycle events. It manages
|
||||
// Executor handles hook execution for KIT lifecycle events. It manages
|
||||
// hook configuration, executes matching hooks in parallel, and processes
|
||||
// their outputs to determine application behavior.
|
||||
type Executor struct {
|
||||
|
||||
@@ -55,7 +55,7 @@ type StopInput struct {
|
||||
Meta json.RawMessage `json:"meta,omitempty"` // Additional metadata (e.g., token usage, model info)
|
||||
}
|
||||
|
||||
// HookOutput represents the JSON output from a hook that controls MCPHost behavior.
|
||||
// HookOutput represents the JSON output from a hook that controls KIT behavior.
|
||||
// Hooks can decide whether to continue execution, provide reasons for stopping,
|
||||
// suppress output, or block tool execution. The Decision field can be "approve",
|
||||
// "block", or empty (default behavior).
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ hooks:
|
||||
UserPromptSubmit:
|
||||
- hooks:
|
||||
- type: command
|
||||
command: "date >> /tmp/mcphost-prompts.log"
|
||||
command: "date >> /tmp/kit-prompts.log"
|
||||
PostToolUse:
|
||||
- matcher: ".*"
|
||||
hooks:
|
||||
|
||||
@@ -17,18 +17,18 @@ type cacheEnvelope struct {
|
||||
Providers map[string]modelsDBProvider `json:"providers"`
|
||||
}
|
||||
|
||||
// dataDir returns the mcphost data directory following XDG Base Directory spec.
|
||||
// dataDir returns the kit data directory following XDG Base Directory spec.
|
||||
//
|
||||
// Linux/macOS: $XDG_DATA_HOME/mcphost (default ~/.local/share/mcphost)
|
||||
// Windows: %LOCALAPPDATA%/mcphost
|
||||
// Linux/macOS: $XDG_DATA_HOME/kit (default ~/.local/share/kit)
|
||||
// Windows: %LOCALAPPDATA%/kit
|
||||
func dataDir() (string, error) {
|
||||
if xdg := os.Getenv("XDG_DATA_HOME"); xdg != "" {
|
||||
return filepath.Join(xdg, "mcphost"), nil
|
||||
return filepath.Join(xdg, "kit"), nil
|
||||
}
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
if local := os.Getenv("LOCALAPPDATA"); local != "" {
|
||||
return filepath.Join(local, "mcphost"), nil
|
||||
return filepath.Join(local, "kit"), nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ func dataDir() (string, error) {
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("cannot determine home directory: %w", err)
|
||||
}
|
||||
return filepath.Join(home, ".local", "share", "mcphost"), nil
|
||||
return filepath.Join(home, ".local", "share", "kit"), nil
|
||||
}
|
||||
|
||||
// cachePath returns the full path to the cache file.
|
||||
|
||||
@@ -23,8 +23,8 @@ import (
|
||||
"charm.land/fantasy/providers/openrouter"
|
||||
"charm.land/fantasy/providers/vercel"
|
||||
|
||||
"github.com/mark3labs/mcphost/internal/auth"
|
||||
"github.com/mark3labs/mcphost/internal/ui/progress"
|
||||
"github.com/mark3labs/kit/internal/auth"
|
||||
"github.com/mark3labs/kit/internal/ui/progress"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -353,7 +353,7 @@ func createAnthropicProvider(ctx context.Context, config *ProviderConfig, modelN
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if os.Getenv("DEBUG") != "" || os.Getenv("MCPHOST_DEBUG") != "" {
|
||||
if os.Getenv("DEBUG") != "" || os.Getenv("KIT_DEBUG") != "" {
|
||||
fmt.Fprintf(os.Stderr, "Using Anthropic API key from: %s\n", source)
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ func NewModelsRegistry() *ModelsRegistry {
|
||||
// buildFromModelsDB converts models.dev provider data into our internal format.
|
||||
// It tries the on-disk cache first and falls back to the embedded database.
|
||||
func buildFromModelsDB() map[string]ProviderInfo {
|
||||
// Try cached data first (from `mcphost update-models`)
|
||||
// Try cached data first (from `kit update-models`)
|
||||
dbProviders, _ := LoadCachedProviders()
|
||||
if len(dbProviders) == 0 {
|
||||
// Fall back to compile-time embedded data
|
||||
|
||||
@@ -32,8 +32,8 @@ type Session struct {
|
||||
// Metadata contains session metadata that provides context about the
|
||||
// environment and configuration used during the conversation.
|
||||
type Metadata struct {
|
||||
// MCPHostVersion is the version of MCPHost used for this session
|
||||
MCPHostVersion string `json:"mcphost_version"`
|
||||
// KitVersion is the version of KIT used for this session
|
||||
KitVersion string `json:"kit_version"`
|
||||
// Provider is the LLM provider used (e.g., "anthropic", "openai", "gemini")
|
||||
Provider string `json:"provider"`
|
||||
// Model is the specific model identifier used for the conversation
|
||||
|
||||
@@ -9,11 +9,11 @@ import (
|
||||
"time"
|
||||
|
||||
"charm.land/fantasy"
|
||||
"github.com/mark3labs/kit/internal/builtin"
|
||||
"github.com/mark3labs/kit/internal/config"
|
||||
"github.com/mark3labs/mcp-go/client"
|
||||
"github.com/mark3labs/mcp-go/client/transport"
|
||||
"github.com/mark3labs/mcp-go/mcp"
|
||||
"github.com/mark3labs/mcphost/internal/builtin"
|
||||
"github.com/mark3labs/mcphost/internal/config"
|
||||
)
|
||||
|
||||
// ConnectionPoolConfig defines configuration parameters for the MCP connection pool.
|
||||
@@ -396,7 +396,7 @@ func (p *MCPConnectionPool) initializeClient(ctx context.Context, client client.
|
||||
initRequest := mcp.InitializeRequest{}
|
||||
initRequest.Params.ProtocolVersion = mcp.LATEST_PROTOCOL_VERSION
|
||||
initRequest.Params.ClientInfo = mcp.Implementation{
|
||||
Name: "mcphost",
|
||||
Name: "kit",
|
||||
Version: "1.0.0",
|
||||
}
|
||||
initRequest.Params.Capabilities = mcp.ClientCapabilities{}
|
||||
@@ -513,7 +513,7 @@ func (p *MCPConnectionPool) GetConnectionStats() map[string]any {
|
||||
}
|
||||
|
||||
// ServerName returns the server name associated with this MCP connection.
|
||||
// This is the configured name from the MCPHost configuration, not necessarily
|
||||
// This is the configured name from the KIT configuration, not necessarily
|
||||
// the actual server implementation name.
|
||||
func (c *MCPConnection) ServerName() string {
|
||||
return c.serverName
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
"charm.land/fantasy"
|
||||
"github.com/mark3labs/mcp-go/mcp"
|
||||
"github.com/mark3labs/mcphost/internal/config"
|
||||
"github.com/mark3labs/kit/internal/config"
|
||||
)
|
||||
|
||||
// MCPToolManager manages MCP (Model Context Protocol) tools and clients across multiple servers.
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/mark3labs/mcphost/internal/config"
|
||||
"github.com/mark3labs/kit/internal/config"
|
||||
)
|
||||
|
||||
func TestMCPToolManager_LoadTools_WithTimeout(t *testing.T) {
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"testing"
|
||||
|
||||
tea "charm.land/bubbletea/v2"
|
||||
"github.com/mark3labs/mcphost/internal/app"
|
||||
"github.com/mark3labs/kit/internal/app"
|
||||
)
|
||||
|
||||
// ==========================================================================
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ import (
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
// CLI manages the command-line interface for MCPHost, providing message rendering,
|
||||
// CLI manages the command-line interface for KIT, providing message rendering,
|
||||
// user input handling, and display management. It supports both standard and compact
|
||||
// display modes, handles streaming responses, tracks token usage, and manages the
|
||||
// overall conversation flow between the user and AI assistants.
|
||||
|
||||
@@ -67,7 +67,7 @@ type Theme struct {
|
||||
Highlight color.Color
|
||||
}
|
||||
|
||||
// DefaultTheme creates and returns the default MCPHost theme based on the Catppuccin
|
||||
// DefaultTheme creates and returns the default KIT theme based on the Catppuccin
|
||||
// Mocha (dark) and Latte (light) color palettes. This theme provides a cohesive,
|
||||
// pleasant visual experience with carefully selected colors for different UI elements.
|
||||
func DefaultTheme() Theme {
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
|
||||
tea "charm.land/bubbletea/v2"
|
||||
|
||||
"github.com/mark3labs/mcphost/internal/app"
|
||||
"github.com/mark3labs/kit/internal/app"
|
||||
)
|
||||
|
||||
// CLIEventHandler routes app-layer events to CLI display methods for
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/mark3labs/mcphost/internal/auth"
|
||||
"github.com/mark3labs/mcphost/internal/models"
|
||||
"github.com/mark3labs/kit/internal/auth"
|
||||
"github.com/mark3labs/kit/internal/models"
|
||||
)
|
||||
|
||||
// AgentInterface defines the minimal interface required from the agent package
|
||||
|
||||
@@ -19,7 +19,7 @@ const (
|
||||
AssistantMessage
|
||||
ToolMessage
|
||||
ToolCallMessage // New type for showing tool calls in progress
|
||||
SystemMessage // New type for MCPHost system messages (help, tools, etc.)
|
||||
SystemMessage // New type for KIT system messages (help, tools, etc.)
|
||||
ErrorMessage // New type for error messages
|
||||
)
|
||||
|
||||
@@ -171,9 +171,9 @@ func (r *MessageRenderer) RenderAssistantMessage(content string, timestamp time.
|
||||
}
|
||||
}
|
||||
|
||||
// RenderSystemMessage renders MCPHost system messages such as help text, command outputs,
|
||||
// RenderSystemMessage renders KIT system messages such as help text, command outputs,
|
||||
// and informational notifications. These messages are displayed with a distinctive system
|
||||
// color border and "MCPHost System" label to differentiate them from user and AI content.
|
||||
// color border and "KIT System" label to differentiate them from user and AI content.
|
||||
func (r *MessageRenderer) RenderSystemMessage(content string, timestamp time.Time) UIMessage {
|
||||
// Format timestamp
|
||||
timeStr := timestamp.Local().Format("15:04")
|
||||
@@ -192,7 +192,7 @@ func (r *MessageRenderer) RenderSystemMessage(content string, timestamp time.Tim
|
||||
}
|
||||
|
||||
// Create info line
|
||||
info := fmt.Sprintf(" MCPHost System (%s)", timeStr)
|
||||
info := fmt.Sprintf(" KIT System (%s)", timeStr)
|
||||
|
||||
// Combine content and info
|
||||
fullContent := strings.TrimSuffix(messageContent, "\n") + "\n" +
|
||||
@@ -260,7 +260,7 @@ func (r *MessageRenderer) RenderDebugMessage(message string, timestamp time.Time
|
||||
info := baseStyle.
|
||||
Width(r.width - 5). // Account for margins and padding
|
||||
Foreground(theme.Muted).
|
||||
Render(fmt.Sprintf(" MCPHost (%s)", timeStr))
|
||||
Render(fmt.Sprintf(" KIT (%s)", timeStr))
|
||||
|
||||
// Combine all parts
|
||||
fullContent := lipgloss.JoinVertical(lipgloss.Left,
|
||||
@@ -316,7 +316,7 @@ func (r *MessageRenderer) RenderDebugConfigMessage(config map[string]any, timest
|
||||
info := baseStyle.
|
||||
Width(r.width - 1).
|
||||
Foreground(theme.Muted).
|
||||
Render(fmt.Sprintf(" MCPHost (%s)", timeStr))
|
||||
Render(fmt.Sprintf(" KIT (%s)", timeStr))
|
||||
|
||||
// Combine parts
|
||||
parts := []string{header}
|
||||
@@ -751,7 +751,7 @@ func (c *MessageContainer) renderEmptyState() string {
|
||||
title := baseStyle.
|
||||
Foreground(theme.System).
|
||||
Bold(true).
|
||||
Render("MCPHost")
|
||||
Render("KIT")
|
||||
|
||||
// Subtitle with better typography
|
||||
subtitle := baseStyle.
|
||||
@@ -824,7 +824,7 @@ func (c *MessageContainer) renderCompactEmptyState() string {
|
||||
welcome := lipgloss.NewStyle().
|
||||
Foreground(theme.System).
|
||||
Bold(true).
|
||||
Render("MCPHost - AI Assistant with MCP Tools")
|
||||
Render("KIT - AI Assistant with MCP Tools")
|
||||
|
||||
help := lipgloss.NewStyle().
|
||||
Foreground(theme.Muted).
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
|
||||
tea "charm.land/bubbletea/v2"
|
||||
"charm.land/lipgloss/v2"
|
||||
"github.com/mark3labs/mcphost/internal/app"
|
||||
"github.com/mark3labs/kit/internal/app"
|
||||
)
|
||||
|
||||
// appState represents the current state of the parent TUI model.
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
|
||||
tea "charm.land/bubbletea/v2"
|
||||
"charm.land/fantasy"
|
||||
"github.com/mark3labs/mcphost/internal/app"
|
||||
"github.com/mark3labs/kit/internal/app"
|
||||
)
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
|
||||
tea "charm.land/bubbletea/v2"
|
||||
"charm.land/lipgloss/v2"
|
||||
"github.com/mark3labs/mcphost/internal/app"
|
||||
"github.com/mark3labs/kit/internal/app"
|
||||
)
|
||||
|
||||
// knightRiderFrames generates a KITT-style scanning animation where a bright
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"charm.land/lipgloss/v2"
|
||||
"github.com/charmbracelet/glamour"
|
||||
"github.com/charmbracelet/glamour/ansi"
|
||||
"github.com/mark3labs/mcphost/internal/config"
|
||||
"github.com/mark3labs/kit/internal/config"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"charm.land/lipgloss/v2"
|
||||
"image/color"
|
||||
|
||||
"github.com/mark3labs/mcphost/internal/models"
|
||||
"github.com/mark3labs/kit/internal/models"
|
||||
)
|
||||
|
||||
// UsageStats encapsulates detailed token usage and cost breakdown for a single
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/mark3labs/mcphost/internal/models"
|
||||
"github.com/mark3labs/kit/internal/models"
|
||||
)
|
||||
|
||||
// stripAnsi removes ANSI escape codes from a string for test comparisons.
|
||||
|
||||
@@ -3,7 +3,7 @@ package ui
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/mark3labs/mcphost/internal/models"
|
||||
"github.com/mark3labs/kit/internal/models"
|
||||
)
|
||||
|
||||
func TestUsageTracker_OAuthCosts(t *testing.T) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/charmbracelet/fang"
|
||||
"github.com/mark3labs/mcphost/cmd"
|
||||
"github.com/mark3labs/kit/cmd"
|
||||
)
|
||||
|
||||
var version = "dev"
|
||||
@@ -14,7 +14,7 @@ var version = "dev"
|
||||
func main() {
|
||||
for _, arg := range os.Args[1:] {
|
||||
if arg == "--version" || arg == "-v" {
|
||||
fmt.Printf("mcphost version %s\n", version)
|
||||
fmt.Printf("kit version %s\n", version)
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
+11
-11
@@ -1,11 +1,11 @@
|
||||
# MCPHost SDK
|
||||
# KIT SDK
|
||||
|
||||
The MCPHost SDK allows you to use MCPHost programmatically from Go applications without spawning OS processes.
|
||||
The KIT SDK allows you to use KIT programmatically from Go applications without spawning OS processes.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
go get github.com/mark3labs/mcphost
|
||||
go get github.com/mark3labs/kit
|
||||
```
|
||||
|
||||
## Basic Usage
|
||||
@@ -18,13 +18,13 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/mark3labs/mcphost/sdk"
|
||||
"github.com/mark3labs/kit/sdk"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
|
||||
// Create MCPHost instance with default configuration
|
||||
// Create Kit instance with default configuration
|
||||
host, err := sdk.New(ctx, nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@@ -44,9 +44,9 @@ func main() {
|
||||
## Configuration
|
||||
|
||||
The SDK behaves identically to the CLI:
|
||||
- Loads configuration from `~/.mcphost.yml` by default
|
||||
- Loads configuration from `~/.kit.yml` by default
|
||||
- Creates default configuration if none exists
|
||||
- Respects all environment variables (`MCPHOST_*`)
|
||||
- Respects all environment variables (`KIT_*`)
|
||||
- Uses the same defaults as the CLI
|
||||
|
||||
### Options
|
||||
@@ -116,14 +116,14 @@ host.ClearSession()
|
||||
|
||||
### Types
|
||||
|
||||
- `MCPHost` - Main SDK type
|
||||
- `Kit` - Main SDK type
|
||||
- `Options` - Configuration options
|
||||
- `Message` - Conversation message
|
||||
- `ToolCall` - Tool invocation details
|
||||
|
||||
### Methods
|
||||
|
||||
- `New(ctx, opts)` - Create new MCPHost instance
|
||||
- `New(ctx, opts)` - Create new Kit instance
|
||||
- `Prompt(ctx, message)` - Send message and get response
|
||||
- `PromptWithCallbacks(ctx, message, ...)` - Send message with progress callbacks
|
||||
- `LoadSession(path)` - Load session from file
|
||||
@@ -137,7 +137,7 @@ host.ClearSession()
|
||||
|
||||
All CLI environment variables work with the SDK:
|
||||
|
||||
- `MCPHOST_MODEL` - Override model
|
||||
- `KIT_MODEL` - Override model
|
||||
- `ANTHROPIC_API_KEY` - Anthropic API key
|
||||
- `OPENAI_API_KEY` - OpenAI API key
|
||||
- `GEMINI_API_KEY` - Google API key
|
||||
@@ -145,4 +145,4 @@ All CLI environment variables work with the SDK:
|
||||
|
||||
## License
|
||||
|
||||
Same as MCPHost CLI
|
||||
Same as KIT CLI
|
||||
|
||||
@@ -5,13 +5,13 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/mark3labs/mcphost/sdk"
|
||||
"github.com/mark3labs/kit/sdk"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
|
||||
// Example 1: Use all defaults (loads ~/.mcphost.yml)
|
||||
// Example 1: Use all defaults (loads ~/.kit.yml)
|
||||
fmt.Println("=== Example 1: Default configuration ===")
|
||||
host, err := sdk.New(ctx, nil)
|
||||
if err != nil {
|
||||
|
||||
@@ -6,13 +6,13 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/mark3labs/mcphost/sdk"
|
||||
"github.com/mark3labs/kit/sdk"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
|
||||
// Create MCPHost with environment variable for API key
|
||||
// Create Kit with environment variable for API key
|
||||
// Expects ANTHROPIC_API_KEY or appropriate provider key to be set
|
||||
host, err := sdk.New(ctx, &sdk.Options{
|
||||
Quiet: true, // Suppress debug output for scripting
|
||||
|
||||
+19
-19
@@ -5,23 +5,23 @@ import (
|
||||
"fmt"
|
||||
|
||||
"charm.land/fantasy"
|
||||
"github.com/mark3labs/mcphost/cmd"
|
||||
"github.com/mark3labs/mcphost/internal/agent"
|
||||
"github.com/mark3labs/mcphost/internal/config"
|
||||
"github.com/mark3labs/mcphost/internal/session"
|
||||
"github.com/mark3labs/kit/cmd"
|
||||
"github.com/mark3labs/kit/internal/agent"
|
||||
"github.com/mark3labs/kit/internal/config"
|
||||
"github.com/mark3labs/kit/internal/session"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// MCPHost provides programmatic access to mcphost functionality, allowing
|
||||
// Kit provides programmatic access to kit functionality, allowing
|
||||
// integration of MCP tools and LLM interactions into Go applications. It manages
|
||||
// agents, sessions, and model configurations.
|
||||
type MCPHost struct {
|
||||
type Kit struct {
|
||||
agent *agent.Agent
|
||||
sessionMgr *session.Manager
|
||||
modelString string
|
||||
}
|
||||
|
||||
// Options configures MCPHost creation with optional overrides for model,
|
||||
// Options configures Kit creation with optional overrides for model,
|
||||
// prompts, configuration, and behavior settings. All fields are optional
|
||||
// and will use CLI defaults if not specified.
|
||||
type Options struct {
|
||||
@@ -33,10 +33,10 @@ type Options struct {
|
||||
Quiet bool // Suppress debug output
|
||||
}
|
||||
|
||||
// New creates an MCPHost instance using the same initialization as the CLI.
|
||||
// New creates a Kit instance using the same initialization as the CLI.
|
||||
// It loads configuration, initializes MCP servers, creates the LLM model, and
|
||||
// sets up the agent for interaction. Returns an error if initialization fails.
|
||||
func New(ctx context.Context, opts *Options) (*MCPHost, error) {
|
||||
func New(ctx context.Context, opts *Options) (*Kit, error) {
|
||||
if opts == nil {
|
||||
opts = &Options{}
|
||||
}
|
||||
@@ -83,7 +83,7 @@ func New(ctx context.Context, opts *Options) (*MCPHost, error) {
|
||||
// Create session manager
|
||||
sessionMgr := session.NewManager("")
|
||||
|
||||
return &MCPHost{
|
||||
return &Kit{
|
||||
agent: a,
|
||||
sessionMgr: sessionMgr,
|
||||
modelString: viper.GetString("model"),
|
||||
@@ -93,7 +93,7 @@ func New(ctx context.Context, opts *Options) (*MCPHost, error) {
|
||||
// Prompt sends a message to the agent and returns the response. The agent may
|
||||
// use tools as needed to generate the response. The conversation history is
|
||||
// automatically maintained in the session. Returns an error if generation fails.
|
||||
func (m *MCPHost) Prompt(ctx context.Context, message string) (string, error) {
|
||||
func (m *Kit) Prompt(ctx context.Context, message string) (string, error) {
|
||||
// Get messages from session
|
||||
messages := m.sessionMgr.GetMessages()
|
||||
|
||||
@@ -124,7 +124,7 @@ func (m *MCPHost) Prompt(ctx context.Context, message string) (string, error) {
|
||||
// PromptWithCallbacks sends a message with callbacks for monitoring tool execution
|
||||
// and streaming responses. The callbacks allow real-time observation of tool calls,
|
||||
// results, and response generation. Returns the final response or an error.
|
||||
func (m *MCPHost) PromptWithCallbacks(
|
||||
func (m *Kit) PromptWithCallbacks(
|
||||
ctx context.Context,
|
||||
message string,
|
||||
onToolCall func(name, args string),
|
||||
@@ -161,13 +161,13 @@ func (m *MCPHost) PromptWithCallbacks(
|
||||
|
||||
// GetSessionManager returns the current session manager for direct access
|
||||
// to conversation history and session manipulation.
|
||||
func (m *MCPHost) GetSessionManager() *session.Manager {
|
||||
func (m *Kit) GetSessionManager() *session.Manager {
|
||||
return m.sessionMgr
|
||||
}
|
||||
|
||||
// LoadSession loads a previously saved session from a file, restoring the
|
||||
// conversation history. Returns an error if the file cannot be loaded or parsed.
|
||||
func (m *MCPHost) LoadSession(path string) error {
|
||||
func (m *Kit) LoadSession(path string) error {
|
||||
s, err := session.LoadFromFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -178,25 +178,25 @@ func (m *MCPHost) LoadSession(path string) error {
|
||||
|
||||
// SaveSession saves the current session to a file for later restoration.
|
||||
// Returns an error if the session cannot be written to the specified path.
|
||||
func (m *MCPHost) SaveSession(path string) error {
|
||||
func (m *Kit) SaveSession(path string) error {
|
||||
return m.sessionMgr.GetSession().SaveToFile(path)
|
||||
}
|
||||
|
||||
// ClearSession clears the current session history, starting a new conversation
|
||||
// with an empty message history.
|
||||
func (m *MCPHost) ClearSession() {
|
||||
func (m *Kit) ClearSession() {
|
||||
m.sessionMgr = session.NewManager("")
|
||||
}
|
||||
|
||||
// GetModelString returns the current model string identifier (e.g.,
|
||||
// "anthropic/claude-sonnet-4-5-20250929" or "openai/gpt-4") being used by the agent.
|
||||
func (m *MCPHost) GetModelString() string {
|
||||
func (m *Kit) GetModelString() string {
|
||||
return m.modelString
|
||||
}
|
||||
|
||||
// Close cleans up resources including MCP server connections and model resources.
|
||||
// Should be called when the MCPHost instance is no longer needed. Returns an
|
||||
// Should be called when the Kit instance is no longer needed. Returns an
|
||||
// error if cleanup fails.
|
||||
func (m *MCPHost) Close() error {
|
||||
func (m *Kit) Close() error {
|
||||
return m.agent.Close()
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/mark3labs/mcphost/sdk"
|
||||
"github.com/mark3labs/kit/sdk"
|
||||
)
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
@@ -18,7 +18,7 @@ func TestNew(t *testing.T) {
|
||||
// Test default initialization
|
||||
host, err := sdk.New(ctx, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create MCPHost with defaults: %v", err)
|
||||
t.Fatalf("Failed to create Kit with defaults: %v", err)
|
||||
}
|
||||
defer func() { _ = host.Close() }()
|
||||
|
||||
@@ -42,7 +42,7 @@ func TestNewWithOptions(t *testing.T) {
|
||||
|
||||
host, err := sdk.New(ctx, opts)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create MCPHost with options: %v", err)
|
||||
t.Fatalf("Failed to create Kit with options: %v", err)
|
||||
}
|
||||
defer func() { _ = host.Close() }()
|
||||
|
||||
@@ -60,7 +60,7 @@ func TestSessionManagement(t *testing.T) {
|
||||
|
||||
host, err := sdk.New(ctx, &sdk.Options{Quiet: true})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create MCPHost: %v", err)
|
||||
t.Fatalf("Failed to create Kit: %v", err)
|
||||
}
|
||||
defer func() { _ = host.Close() }()
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package sdk
|
||||
|
||||
import (
|
||||
"charm.land/fantasy"
|
||||
"github.com/mark3labs/mcphost/internal/session"
|
||||
"github.com/mark3labs/kit/internal/session"
|
||||
)
|
||||
|
||||
// Message is an alias for session.Message providing SDK users with access
|
||||
|
||||
@@ -8,7 +8,7 @@ New capabilities: message queueing during streaming, double-tap ESC cancellation
|
||||
|
||||
## User Story
|
||||
|
||||
As an MCPHost user, I want the TUI to remain responsive during agent streaming so I can queue follow-up messages, cancel in-progress work, and see a persistent input area -- instead of waiting for each response to complete before typing.
|
||||
As a KIT user, I want the TUI to remain responsive during agent streaming so I can queue follow-up messages, cancel in-progress work, and see a persistent input area -- instead of waiting for each response to complete before typing.
|
||||
|
||||
As a developer, I want the TUI architecture to follow Bubble Tea's idiomatic child-model pattern so components are composable, testable, and extensible without terminal ownership conflicts.
|
||||
|
||||
@@ -381,7 +381,7 @@ printResult(result)
|
||||
assistant (claude-sonnet-4-20250514)
|
||||
Let me check the build first.
|
||||
|
||||
⚙ bash: go build -o output/mcphost
|
||||
⚙ bash: go build -o output/kit
|
||||
◇◇◇◆◇◇◇ Executing...
|
||||
|
||||
─────────────────────────────────── 2 queued
|
||||
@@ -395,7 +395,7 @@ printResult(result)
|
||||
I need to run a command to check the build.
|
||||
|
||||
┌─ Tool Approval ──────────────────────┐
|
||||
│ bash: go build -o output/mcphost │
|
||||
│ bash: go build -o output/kit │
|
||||
│ │
|
||||
│ [Yes] No │
|
||||
└──────────────────────────────────────┘
|
||||
|
||||
Reference in New Issue
Block a user