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.
Discuss the Project on Discord
MCPHost acts as a host in the MCP client-server architecture, where:
This architecture allows language models to:
Currently supports:
allowedTools
and excludedTools
per server# For all providers (use --provider-api-key flag or these environment variables) export OPENAI_API_KEY='your-openai-key' # For OpenAI export ANTHROPIC_API_KEY='your-anthropic-key' # For Anthropic export GOOGLE_API_KEY='your-google-key' # For Google/Gemini
You can also configure the Ollama client using standard environment variables, such as OLLAMA_HOST
for the Ollama base URL.
export GOOGLE_API_KEY='your-api-key'
--provider-url
and --provider-api-key
flags or set environment variablesmcphost --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.
go install github.com/mark3labs/mcphost@latest
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)Config file locations by OS:
~/.mcphost.yml
, ~/.mcphost.json
, ~/.mcp.yml
, ~/.mcp.json
%USERPROFILE%\.mcphost.yml
, %USERPROFILE%\.mcphost.json
, %USERPROFILE%\.mcp.yml
, %USERPROFILE%\.mcp.json
You can also specify a custom location using the --config
flag.
MCPHost 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 valueThis allows you to keep sensitive information like API keys in environment variables while maintaining flexible configuration.
Example:
mcpServers: github: type: local command: ["docker", "run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN=${env://GITHUB_TOKEN}", "ghcr.io/github/github-mcp-server"] environment: DEBUG: "${env://DEBUG:-false}" LOG_LEVEL: "${env://LOG_LEVEL:-info}" model: "${env://MODEL:-anthropic:claude-sonnet-4-20250514}" provider-api-key: "${env://OPENAI_API_KEY}" # Required - will fail if not set
Usage:
# Set required environment variables export GITHUB_TOKEN="ghp_your_token_here" export OPENAI_API_KEY="your_openai_key" # Optionally override defaults export DEBUG="true" export MODEL="openai:gpt-4" # Run mcphost mcphostSimplified Configuration Schema
MCPHost now supports a simplified configuration schema with three server types:
For local MCP servers that run commands on your machine:
{ "mcpServers": { "filesystem": { "type": "local", "command": ["npx", "@modelcontextprotocol/server-filesystem", "${env://WORK_DIR:-/tmp}"], "environment": { "DEBUG": "${env://DEBUG:-false}", "LOG_LEVEL": "${env://LOG_LEVEL:-info}", "API_TOKEN": "${env://FS_API_TOKEN}" }, "allowedTools": ["read_file", "write_file"], "excludedTools": ["delete_file"] }, "github": { "type": "local", "command": ["docker", "run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN=${env://GITHUB_TOKEN}", "ghcr.io/github/github-mcp-server"], "environment": { "DEBUG": "${env://DEBUG:-false}" } }, "sqlite": { "type": "local", "command": ["uvx", "mcp-server-sqlite", "--db-path", "${env://DB_PATH:-/tmp/foo.db}"], "environment": { "SQLITE_DEBUG": "${env://DEBUG:-0}", "DATABASE_URL": "${env://DATABASE_URL:-sqlite:///tmp/foo.db}" } } } }
Each local server entry requires:
type
: Must be set to "local"
command
: Array containing the command and all its argumentsenvironment
: (Optional) Object with environment variables as key-value pairsallowedTools
: (Optional) Array of tool names to include (whitelist)excludedTools
: (Optional) Array of tool names to exclude (blacklist)For remote MCP servers accessible via HTTP:
{ "mcpServers": { "websearch": { "type": "remote", "url": "${env://WEBSEARCH_URL:-https://api.example.com/mcp}", "headers": ["Authorization: Bearer ${env://WEBSEARCH_TOKEN}"] }, "weather": { "type": "remote", "url": "${env://WEATHER_URL:-https://weather-mcp.example.com}" } } }
Each remote server entry requires:
type
: Must be set to "remote"
url
: The URL where the MCP server is accessibleheaders
: (Optional) Array of HTTP headers for authentication and custom headersRemote servers automatically use the StreamableHTTP transport for optimal performance.
For builtin MCP servers that run in-process for optimal performance:
{ "mcpServers": { "filesystem": { "type": "builtin", "name": "fs", "options": { "allowed_directories": ["${env://WORK_DIR:-/tmp}", "${env://HOME}/documents"] }, "allowedTools": ["read_file", "write_file", "list_directory"] }, "filesystem-cwd": { "type": "builtin", "name": "fs" } } }
Each builtin server entry requires:
type
: Must be set to "builtin"
name
: Internal name of the builtin server (e.g., "fs"
for filesystem)options
: Configuration options specific to the builtin serverAvailable Builtin Servers:
fs
(filesystem): Secure filesystem access with configurable allowed directories
allowed_directories
: Array of directory paths that the server can access (defaults to current working directory if not specified)bash
: Execute bash commands with security restrictions and timeout controls
todo
: Manage ephemeral todo lists for task tracking during sessions
http
: Fetch web content and convert to text, markdown, or HTML formats
fetch
(fetch and convert web content), fetch_summarize
(fetch and summarize web content using AI), fetch_extract
(fetch and extract specific data using AI), fetch_filtered_json
(fetch JSON and filter using gjson path syntax){ "mcpServers": { "filesystem": { "type": "builtin", "name": "fs", "options": { "allowed_directories": ["/tmp", "/home/user/documents"] } }, "bash-commands": { "type": "builtin", "name": "bash" }, "task-manager": { "type": "builtin", "name": "todo" }, "web-fetcher": { "type": "builtin", "name": "http" } } }
All MCP server types support tool filtering to restrict which tools are available:
allowedTools
: Whitelist - only specified tools are available from the serverexcludedTools
: Blacklist - all tools except specified ones are available{ "mcpServers": { "filesystem-readonly": { "type": "builtin", "name": "fs", "allowedTools": ["read_file", "list_directory"] }, "filesystem-safe": { "type": "local", "command": ["npx", "@modelcontextprotocol/server-filesystem", "/tmp"], "excludedTools": ["delete_file"] } } }
Note: allowedTools
and excludedTools
are mutually exclusive - you can only use one per server.
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.).
{ "mcpServers": { "sqlite": { "command": "uvx", "args": ["mcp-server-sqlite", "--db-path", "/tmp/foo.db"], "env": { "DEBUG": "true" } } } }
{ "mcpServers": { "server_name": { "url": "http://some_host:8000/sse", "headers": ["Authorization: Bearer my-token"] } } }Legacy Docker/Container Format
{ "mcpServers": { "phalcon": { "command": "docker", "args": [ "run", "-i", "--rm", "ghcr.io/mark3labs/phalcon-mcp:latest", "serve" ] } } }Legacy Streamable HTTP Format
{ "mcpServers": { "websearch": { "transport": "streamable", "url": "https://api.example.com/mcp", "headers": ["Authorization: Bearer your-api-token"] } } }
MCPHost 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)inprocess
: Runs builtin servers in-process for optimal performance (used by "builtin"
servers)The simplified schema automatically maps:
"local"
type → stdio
transport"remote"
type → streamable
transport"builtin"
type → inprocess
transportYou can specify a custom system prompt using the --system-prompt
flag. You can either:
Pass the prompt directly as text:
mcphost --system-prompt "You are a helpful assistant that responds in a friendly tone."
Pass a path to a text file containing the prompt:
mcphost --system-prompt ./prompts/assistant.md
Example assistant.md
file:
You are a helpful coding assistant. Please: - Write clean, readable code - Include helpful comments - Follow best practices - Explain your reasoning
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.
Interactive Mode (Default)Start an interactive conversation session:
Run executable YAML-based automation scripts with variable substitution support:
# Using the script subcommand mcphost script myscript.sh # With variables mcphost script myscript.sh --args:directory /tmp --args:name "John" # Direct execution (if executable and has shebang) ./myscript.sh
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:
#!/usr/bin/env -S mcphost script --- # This script uses the container-use MCP server from https://github.com/dagger/container-use mcpServers: container-use: type: "local" command: ["cu", "stdio"] prompt: | Create 2 variations of a simple hello world app using Flask and FastAPI. Each in their own environment. Give me the URL of each app ---
Or alternatively, omit the prompt:
field and place the prompt after the frontmatter:
#!/usr/bin/env -S mcphost script --- # This script uses the container-use MCP server from https://github.com/dagger/container-use mcpServers: container-use: type: "local" command: ["cu", "stdio"] --- Create 2 variations of a simple hello world app using Flask and FastAPI. Each in their own environment. Give me the URL of each app
Scripts support both environment variable substitution and script argument substitution:
${env://VAR}
and ${env://VAR:-default}
- Processed first${variable}
and ${variable:-default}
- Processed after environment variablesVariables can be provided via command line arguments:
# Script with variables mcphost script myscript.sh --args:directory /tmp --args:name "John"
MCPHost supports these variable syntaxes:
${env://VAR}
- Must be set in environment${env://VAR:-default}
- Uses default if not set${variable}
- Must be provided via --args:variable value
${variable:-default}
- Uses default if not providedExample script with mixed environment variables and script arguments:
#!/usr/bin/env -S mcphost script --- mcpServers: github: type: "local" command: ["gh", "api"] environment: GITHUB_TOKEN: "${env://GITHUB_TOKEN}" DEBUG: "${env://DEBUG:-false}" filesystem: type: "local" command: ["npx", "-y", "@modelcontextprotocol/server-filesystem", "${env://WORK_DIR:-/tmp}"] model: "${env://MODEL:-anthropic:claude-sonnet-4-20250514}" --- Hello ${name:-World}! Please list ${repo_type:-public} repositories for user ${username}. Working directory is ${env://WORK_DIR:-/tmp}. Use the ${command:-gh} command to fetch ${count:-10} repositories.
# Set environment variables first export GITHUB_TOKEN="ghp_your_token_here" 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 # Override specific script arguments mcphost 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" # Mix of env vars, provided args, and default values mcphost script myscript.sh --args:name "Alice" --args:command "gh api" --args:count "5"
${var:-}
- Uses empty string if not provided${path:-/tmp/default/path}
- Supports paths, URLs, etc.${msg:-Hello World}
- Supports spaces in default values${variable}
syntax continues to work unchangedImportant:
${env://GITHUB_TOKEN}
) are required and must be set in the environment${username}
) are required and must be provided via --args:variable value
syntax#!/usr/bin/env -S mcphost script
)${variable}
and ${variable:-default}
syntax with --args:variable value
mcpServers
defined, uses default configallowedTools
/excludedTools
per serverNote: The shebang line requires env -S
to handle the multi-word command mcphost script
. This is supported on most modern Unix-like systems.
See examples/scripts/
for sample scripts:
example-script.sh
- Script with custom MCP serverssimple-script.sh
- Script using default config fallbackMCPHost 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.
Initialize a hooks configuration:
View active hooks:
Validate your 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
)Example configuration:
hooks: PreToolUse: - matcher: "bash" hooks: - type: command command: "/usr/local/bin/validate-bash.py" timeout: 5 UserPromptSubmit: - hooks: - type: command command: "~/.mcphost/hooks/log-prompt.sh"
⚠️ WARNING: Hooks execute arbitrary commands on your system. Only use hooks from trusted sources and always review hook commands before enabling them.
To temporarily disable all hooks, use the --no-hooks
flag:
See the example hook scripts in examples/hooks/
:
bash-validator.py
- Validates and blocks dangerous bash commandsprompt-logger.sh
- Logs all user prompts with timestampsmcp-monitor.py
- Monitors and enforces policies on MCP tool usageRun a single prompt and exit - perfect for scripting and automation:
# Basic non-interactive usage mcphost -p "What is the weather like today?" # Quiet mode - only output the AI response (no UI elements) mcphost -p "What is 2+2?" --quiet # Use with different models mcphost -m ollama:qwen2.5:3b -p "Explain quantum computing" --quietModel Generation Parameters
MCPHost supports fine-tuning model behavior through various parameters:
# Control response length mcphost -p "Explain AI" --max-tokens 1000 # Adjust creativity (0.0 = focused, 1.0 = creative) mcphost -p "Write a story" --temperature 0.9 # Control diversity with nucleus sampling mcphost -p "Generate ideas" --top-p 0.8 # Limit token choices for more focused responses mcphost -p "Answer precisely" --top-k 20 # Set custom stop sequences mcphost -p "Generate code" --stop-sequences "```","END"
These parameters work with all supported providers (OpenAI, Anthropic, Google, Ollama) where supported by the underlying model.
Models can be specified using the --model
(-m
) flag:
anthropic:claude-sonnet-4-20250514
, anthropic:claude-3-5-sonnet-latest
, anthropic:claude-3-5-haiku-latest
openai:gpt-4
, openai:gpt-4-turbo
, openai:gpt-3.5-turbo
google:gemini-2.0-flash
, google:gemini-1.5-pro
ollama:llama3.2
, ollama:qwen2.5:3b
, ollama:mistral
--provider-url
# Use Ollama with Qwen model mcphost -m ollama:qwen2.5:3b # Use OpenAI's GPT-4 mcphost -m openai:gpt-4 # Use OpenAI-compatible model with custom URL and API key mcphost --model openai:<your-model-name> \ --provider-url <your-base-url> \ --provider-api-key <your-api-key>
# Single prompt with full UI mcphost -p "List files in the current directory" # Compact mode for cleaner output without fancy styling mcphost -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 # Use in shell scripts RESULT=$(mcphost -p "Calculate 15 * 23" --quiet) echo "The answer is: $RESULT" # Pipe to other commands mcphost -p "Generate a random UUID" --quiet | tr '[:lower:]' '[:upper:]'
--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)--system-prompt string
: system-prompt file location--debug
: Enable debug logging--max-steps int
: Maximum number of agent steps (0 for unlimited, default: 0)-m, --model string
: Model to use (format: provider:model) (default "anthropic:claude-sonnet-4-20250514")-p, --prompt string
: Run in non-interactive mode with the given prompt--quiet
: Suppress all output except the AI response (only works with --prompt)--compact
: Enable compact output mode without fancy styling (ideal for scripting and automation)--stream
: Enable streaming responses (default: true, use --stream=false
to disable)mcphost auth login anthropic
: Authenticate with Anthropic using OAuth (alternative to API keys)mcphost auth logout anthropic
: Remove stored OAuth credentialsmcphost auth status
: Show authentication statusNote: OAuth credentials (when present) take precedence over API keys from environment variables and --provider-api-key
flags.
--max-tokens int
: Maximum number of tokens in the response (default: 4096)--temperature float32
: Controls randomness in responses (0.0-1.0, default: 0.7)--top-p float32
: Controls diversity via nucleus sampling (0.0-1.0, default: 0.95)--top-k int32
: Controls diversity by limiting top K tokens to sample from (default: 40)--stop-sequences strings
: Custom stop sequences (comma-separated)All command-line flags can be configured via the config file. MCPHost will look for configuration in this order:
~/.mcphost.yml
or ~/.mcphost.json
(preferred)~/.mcp.yml
or ~/.mcp.json
(backwards compatibility)Example config file (~/.mcphost.yml
):
# MCP Servers - New Simplified Format mcpServers: filesystem-local: type: "local" command: ["npx", "@modelcontextprotocol/server-filesystem", "/path/to/files"] environment: DEBUG: "true" filesystem-builtin: type: "builtin" name: "fs" options: allowed_directories: ["/tmp", "/home/user/documents"] websearch: type: "remote" url: "https://api.example.com/mcp" # Application settings model: "anthropic:claude-sonnet-4-20250514" max-steps: 20 debug: false system-prompt: "/path/to/system-prompt.txt" # Model generation parameters max-tokens: 4096 temperature: 0.7 top-p: 0.95 top-k: 40 stop-sequences: ["Human:", "Assistant:"] # Streaming configuration stream: false # Disable streaming (default: true) # API Configuration provider-api-key: "your-api-key" # For OpenAI, Anthropic, or Google provider-url: "https://api.openai.com/v1" # Custom base URL tls-skip-verify: false # Skip TLS certificate verification (default: false)
Note: Command-line flags take precedence over config file values.
While chatting, you can use:
/help
: Show available commands/tools
: List all available tools/servers
: List configured MCP servers/history
: Display conversation history/quit
: Exit the applicationCtrl+C
: Exit at any timeOptional OAuth authentication for Anthropic (alternative to API keys):
mcphost auth login anthropic
: Authenticate using OAuthmcphost auth logout anthropic
: Remove stored OAuth credentialsmcphost auth status
: Show authentication status--config
: Specify custom config file locationMCPHost's non-interactive mode makes it perfect for automation, scripting, and integration with other tools.
#!/bin/bash # Get weather and save to file mcphost -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) echo "$file: $summary" >> summaries.txt done
# Code review automation DIFF=$(git diff HEAD~1) mcphost -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
# Process CSV data mcphost -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
# Use as a microservice curl -X POST http://localhost:8080/process \ -d "$(mcphost -p 'Generate a UUID' --quiet)"
--quiet
flag to get clean output suitable for parsing (only AI response, no UI)--compact
flag for simplified output without fancy styling (when you want to see UI elements)--compact
and --quiet
are mutually exclusive - --compact
has no effect with --quiet
${env://VAR}
syntax in config files and scripts for environment variable substitutiongrep
, awk
, sed
, etc.)# Set sensitive variables in environment export GITHUB_TOKEN="ghp_your_token_here" export OPENAI_API_KEY="your_openai_key" export DATABASE_URL="postgresql://user:pass@localhost/db" # Use in config files mcpServers: github: environment: GITHUB_TOKEN: "${env://GITHUB_TOKEN}" DEBUG: "${env://DEBUG:-false}" # Use in scripts mcphost script my-script.sh --args:username aliceMCP Server Compatibility 🔌
MCPHost can work with any MCP-compliant server. For examples and reference implementations, see the MCP Servers Repository.
Contributions are welcome! Feel free to:
Please ensure your contributions follow good coding practices and include appropriate tests.
This project is licensed under the MIT License - see the LICENSE file for details.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4