Content
# mcplease
`mcplease` is a local MCP aggregator daemon. Configure your MCP clients once to talk to `mcplease`, then configure downstream MCP servers in one XDG config file.
## MVP Status
The MVP supports:
- local MCP HTTP endpoint;
- HTTP upstream MCP servers;
- `initialize`, `tools/list`, and `tools/call`;
- namespaced tools such as `github.search_repositories`;
- per-upstream headers with `${ENV_VAR}` expansion.
- per-upstream headers and stdio env values with `op://` 1Password references.
- TUI toggles for upstreams and individual tools.
## Config Path
Config path priority:
1. `--config`
2. `MCPLEASE_CONFIG`
3. `$XDG_CONFIG_HOME/mcplease/config.yaml`
4. `~/.config/mcplease/config.yaml`
## Example Config
```yaml
version: 1
server:
listen: 127.0.0.1:7331
storage:
path: ~/.config/mcplease/mcplease.db
stats:
enabled: true
upstreams:
github:
transport: http
url: http://127.0.0.1:3101/mcp
headers:
Authorization: "Bearer ${GITHUB_MCP_TOKEN}"
```
Secrets in upstream `headers` and stdio `env` values can come from environment variables or 1Password:
```yaml
upstreams:
github:
transport: http
url: http://127.0.0.1:3101/mcp
headers:
Authorization: "Bearer op://Private/GitHub MCP/token"
context7:
transport: stdio
command: npx
args:
- -y
- "@upstash/context7-mcp"
env:
CONTEXT7_API_KEY: "op://Private/Context7/token"
```
1Password references are read at startup with `op read <reference>`, so the 1Password CLI must be installed and signed in. A missing CLI, invalid reference, or locked 1Password session fails config loading with the affected config field in the error.
`storage.path` is the single SQLite database used for usage stats, OAuth tokens, known tools, and disabled-tool policy. Older configs that only set `stats.path` continue to use that path as the storage database.
## Run
```bash
cargo run -- --config ./config.yaml
```
## TUI
```bash
cargo run -- tui --config ./config.yaml
```
Use `Tab` to switch between upstream and tool screens. Tool rows are populated from the last successful daemon discovery. Disabling a tool hides it from `tools/list` and rejects `tools/call` immediately; no reload is required.
## Tool Search Surface
By default, `mcplease` exposes every discovered upstream tool through `tools/list` on `/mcp`.
For large tool catalogs, point clients at `/mcp/search` to expose a small gateway surface instead:
```text
http://127.0.0.1:7331/mcp/search
```
Search mode exposes:
- `search_tools`: search the hidden tool catalog and return compact candidates.
- `describe_tools`: return full definitions and input schemas for exact tool names.
- `call_tool`: call a real upstream tool by exact exposed name.
The search backend is internal. It uses the local SQLite storage database with FTS5/BM25 and rebuilds the index after startup discovery and hot reload.
To inspect the local tool-search index directly:
```bash
mcplease call tool-search --query "github repositories"
```
## Logs
By default, `mcplease` logs at `info` level unless `RUST_LOG` is set.
For debug logs:
```bash
cargo run -- --config ./config.yaml --log-level debug
```
`--log-level` accepts `trace`, `debug`, `info`, `warn`, or `error` and overrides `RUST_LOG` for `mcplease` logs.
For structured JSON logs:
```bash
cargo run -- --config ./config.yaml --log-level debug --json-logs
```