loading…
Search for a command to run...
loading…
A modular, extensible MCP multi-server hub that gives LLMs sandboxed file access, Git operations, web fetching, and persistent memory, deployable via Ansible.
A modular, extensible MCP multi-server hub that gives LLMs sandboxed file access, Git operations, web fetching, and persistent memory, deployable via Ansible.
A modular, extensible Model Context Protocol multi-server hub — built in TypeScript for IT automation teams.
Give your LLM access to real-world tools: files, Git, web content, and persistent memory. Deploy to any number of client machines simultaneously via Ansible.
mcp-tool-hub/
├── packages/
│ ├── core/ ← Shared types + BaseMCPServer abstract class
│ ├── server-filesystem/ ← Sandboxed local file access (read/write/list/delete)
│ ├── server-git/ ← Git log, diff, file contents, branches, status
│ ├── server-fetch/ ← Web fetching: HTML, JSON APIs, URL health checks
│ └── server-memory/ ← Persistent JSON knowledge base (survives restarts)
├── host/ ← Orchestrator: registry + CLI + stdio JSON interface
├── ansible/ ← Playbook, inventory, systemd service templates
└── docs/ ← How to add new servers (with template)
The architecture follows the Model Context Protocol pattern:
toolName → server at runtime{"toolName":"...", "arguments":{...}} on stdin, reads the result from stdoutBaseMCPServer, register in cli.tsgit clone https://github.com/your-org/mcp-tool-hub.git
cd mcp-tool-hub
npm install
npm run build
cp .env.example .env
# Edit .env with your paths and settings
# Via npm
npm run start --workspace=host
# Or directly
node host/dist/cli.js
Send JSON to stdin, get JSON from stdout:
echo '{"toolName":"read_file","arguments":{"path":"hello.txt"}}' | node host/dist/cli.js
All operations sandboxed to MCP_FS_ROOT. Path traversal (../) is blocked.
| Tool | Description |
|---|---|
read_file |
Read file contents (utf8 or base64) |
write_file |
Write or append to a file |
list_directory |
List directory contents (optionally recursive) |
delete_file |
Delete a file |
move_file |
Move or rename a file |
get_file_info |
Get size, dates, and type of a path |
Read-only. No write operations.
| Tool | Description |
|---|---|
git_log |
Commit history for a repo or file |
git_show_file |
File contents at a specific commit/branch |
git_diff |
Diff between two refs |
git_status |
Working tree status |
git_branches |
List branches (local + optional remote) |
git_show_commit |
Full commit details and diff |
Supports optional domain allowlist via MCP_FETCH_ALLOWED_DOMAINS.
| Tool | Description |
|---|---|
fetch_url |
Fetch HTML or text from a URL |
fetch_json |
Fetch and parse a JSON API response |
check_url |
Check if a URL is reachable (HEAD request) |
Persistent across restarts. Backed by a JSON file.
| Tool | Description |
|---|---|
memory_set |
Store a value with key, namespace, and tags |
memory_get |
Retrieve a value by key |
memory_search |
Full-text search across all entries |
memory_delete |
Delete an entry |
memory_list_namespaces |
List all namespaces with counts |
memory_clear_namespace |
Delete all entries in a namespace |
Deploy to all your client machines simultaneously:
cd ansible
# First time
ansible-playbook -i inventory.yml deploy-mcp-hub.yml
# Update only (rebuild + restart)
ansible-playbook -i inventory.yml deploy-mcp-hub.yml --tags update
# Deploy to specific group
ansible-playbook -i inventory.yml deploy-mcp-hub.yml --limit servers
The playbook:
mcp-hub system user.env config from your Ansible variablesPer-host variables in inventory.yml let you configure different allowed domains, log levels, and paths per machine group.
See docs/adding-a-new-server.template.ts for the full template with comments.
In short:
// 1. Create packages/server-myservice/src/my-server.ts
export class MyServer extends BaseMCPServer {
constructor(options: MyOptions) {
super(SERVER_INFO, options);
this.registerTool("my_tool", this.handleMyTool.bind(this));
}
private async handleMyTool(args) {
return this.ok({ result: "done" });
}
}
// 2. Register in host/src/cli.ts
hub.use(new MyServer({ apiKey: process.env.MY_API_KEY! }));
Ideas: server-slack, server-postgres, server-docker, server-ansible, server-ssh, server-jira
| Variable | Default | Description |
|---|---|---|
MCP_DATA_DIR |
./mcp-data |
Root for all hub data |
MCP_FS_ROOT |
./mcp-data/files |
Filesystem sandbox root |
MCP_GIT_WORKSPACE |
./mcp-data/repos |
Git repos base path |
MCP_MEMORY_PATH |
./mcp-data/memory.json |
Memory store file |
MCP_FETCH_ALLOWED_DOMAINS |
(empty = all) | Comma-separated domain allowlist |
MCP_LOG_LEVEL |
info |
debug|info|warn|error |
commit, push, or clone operations exposed.PrivateTmp=true and NoNewPrivileges=true.fetch API)server-git)Добавь это в claude_desktop_config.json и перезапусти Claude Desktop.
{
"mcpServers": {
"mcp-tool-hub": {
"command": "npx",
"args": []
}
}
}