slife-mcp
Standalone MCP proxy service — manages persistent connections to external MCP servers and exposes them through a single MCP endpoint.
Quick Start
pip install slife-mcp
# Run — auto-detects mode:
slife-mcp # with slife.json5 → HTTP, without → stdio
slife-mcp --port 8888 # HTTP on custom port
slife-mcp --host 0.0.0.0 --port 9876 # HTTP on all interfaces
How It Works
MCP clients ←→ slife-mcp ←→ external MCP servers (filesystem, search, fetch, …)
slife-mcp acts as a proxy layer between MCP clients and external MCP servers. Instead of each client managing its own server connections, slife-mcp maintains persistent connections centrally and exposes all tools through a single endpoint.
Key design decisions:
- Raw JSON-RPC over subprocess pipes — no
anyio, noClientSession. AvoidsTaskGroupconflicts with FastMCP and keeps the implementation simple and debuggable. - Connection pooling — servers are kept alive across requests. Disconnected servers can be reconnected at runtime without restarting slife-mcp.
- Stderr capture — when a server fails to connect, its stderr output is included in the error message so the LLM (or human operator) can understand and fix the problem.
- Progressive disclosure — servers default to eager mode (tools loaded at startup), but can be configured as lazy (connected, tools hidden) to keep the tool list lean. Switch between modes at runtime with
mcp_set_disclosure.
This supports any MCP-compatible server, including:
- Pre-built MCP servers — filesystem, web search (Serper, Tavily), fetch, etc.
- REST API servers — anyapi-mcp-server converts OpenAPI specs to MCP tools, making any REST API (GitHub, Jira, GitLab, Slack…) callable as tools.
Configuration
Create slife.json5 in your working directory:
{
mcp: {
// wrapper.url — where clients connect to slife-mcp
wrapper: {
url: "http://127.0.0.1:9876/mcp",
},
// External MCP servers to auto-connect at startup
servers: {
filesystem: {
command: "npx",
args: ["-y", "@modelcontextprotocol/server-filesystem", "/allowed/path"],
},
serper: {
command: "npx",
args: ["-y", "serper-search-scrape-mcp-server"],
env: {
SERPER_API_KEY: "${SERPER_API_KEY}",
},
},
},
},
}
Environment variable references (${VAR} and ${VAR:-default}) are resolved at runtime.
Management Tools
Once running, clients can call these tools to manage connections:
| Tool | Description |
|---|---|
mcp_add_server |
Connect to an external MCP server (activate=false for lazy) |
mcp_remove_server |
Disconnect and remove a server |
mcp_list_servers |
List all servers with status, tool count, and active state |
mcp_check_server |
Check a single server's status and active flag |
mcp_list_tools |
List all tools from a server, even if inactive |
mcp_set_disclosure |
Switch between eager (tools loaded) and lazy (tools hidden) |
mcp_call_tool |
Call a tool on a connected server (arguments as JSON string) |
mcp_reload |
Reconnect one or all servers to refresh tool lists |
mcp_call_tool expects tool arguments as a JSON string:
{
"server": "filesystem",
"tool_name": "read_file",
"arguments": "{\"path\": \"/tmp/example.txt\"}"
}
Progressive Disclosure
Servers default to eager mode — all tools loaded at startup. For servers with many tools, use activate: false when adding or disclosure: "lazy" in config:
servers: {
"big-api": {
command: "npx", args: [...],
disclosure: "lazy", // connect but don't load tools yet
}
}
Lazy servers connect at startup but don't disclose tools. Clients browse tools with mcp_list_tools({server: "big-api"}), then call mcp_set_disclosure({name: "big-api", disclosure: "eager"}) to load them.
Transport Modes
| Mode | Trigger | Use case |
|---|---|---|
| HTTP | TTY (terminal) with slife.json5 |
Standalone service, shared by multiple clients |
| stdio | Piped stdin (child process) | Spawned by slife agent as a subprocess |
Auto-detection logic:
- If stdin is not a TTY (piped) → stdio mode — used when slife spawns slife-mcp as a child process.
- If stdin is a TTY (terminal) → looks for
slife.json5→ readsmcp.wrapper.urlfor host/port → HTTP mode. - Use
--host/--portCLI flags to override config values.
In HTTP mode, the server listens on the configured host:port and serves the MCP protocol at the /mcp path. Multiple MCP clients can connect simultaneously.
In stdio mode, the server reads/writes JSON-RPC messages on stdin/stdout — exactly one client (the parent process).
Architecture
┌──────────┐ HTTP/stdio ┌───────────────┐ JSON-RPC ┌──────────────────┐
│ Client │ ◄────────────────► │ slife-mcp │ ◄───────────────► │ External MCP │
│ (slife) │ │ (FastMCP) │ subprocess │ servers │
└──────────┘ │ │ │ ┌─ filesystem │
│ ConnectionPool│ │ ├─ serper │
│ ├─ conn #1 │───────────────────│ ├─ fetch │
│ ├─ conn #2 │ │ └─ anyapi │
│ └─ conn #3 │ └──────────────────┘
└───────────────┘
server.py— FastMCP server entry point with 8 management tools. Handles transport auto-detection and config parsing.connection.py—MCPServerConnection(per-server lifecycle: spawn, JSON-RPC handshake, tool discovery, call, disconnect) andConnectionPool(collection management).
Requirements
- Python ≥ 3.13
fastmcp≥ 2.0.0json5≥ 0.15.0
License
MIT
Metadata
Release files for slife-mcp 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| slife_mcp-0.1.3.tar.gz | 13.0 kB | Without provenance | Details for slife_mcp-0.1.3.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| slife_mcp-0.1.3-py3-none-any.whl | Python 3 | none | any | Details for slife_mcp-0.1.3-py3-none-any.whl |
Total release size: 25.9 kB
Release files / slife_mcp-0.1.3.tar.gz
| Download URL | slife_mcp-0.1.3.tar.gz |
|---|---|
| Size | 13.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d9fae85b5ff1f787c4e675ea5665bdc063fe92727822ccdcc6aa324f135bc89a
|
|
BLAKE2b-256 checksum How to use checksums |
734bc11ef479a363d693decd888cba6ad26b05f7282ce846a46d239087112eb4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / slife_mcp-0.1.3-py3-none-any.whl
| Download URL | slife_mcp-0.1.3-py3-none-any.whl |
|---|---|
| Size | 12.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c922931e7c9d7268248e55171f4d6dde6a0e13e70dfa82603ec64c809b4e8565
|
|
BLAKE2b-256 checksum How to use checksums |
96e9128b5b50931ab91b7313b0e2031dbc066a262113ccecb8e3852235f6f9bf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for slife-mcp 0.1.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.