IT Operations Hub
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@IT Operations Hubshow me all active critical problems in Zabbix"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
IT Operations Hub
เกตเวย์ MCP รวมศูนย์สำหรับงาน IT Operations และบัญชี Express — เอเจนต์ AI คุยกับ Zabbix 7, MeshCentral, และ Express Accounting (express.co.th) ผ่าน SSE และ Streamable HTTP หลัง Cloudflare Tunnel และ Nginx RBAC
A production Docker Compose stack:
Cloudflare Tunnel → Nginx (Bearer RBAC + OAuth DCR, SSE/WebSocket) → mcp-hub-it | mcp-hub-admin | mcp-hub-accounting → sub-mcp-zabbix | sub-mcp-meshcentral | sub-mcp-express → Zabbix / MeshCentral / Express books
All services share a single bridge network, infra-net. MCP hubs and databases are not published on the host. Only LAN/VPN ports for the gateway, Zabbix, and MeshCentral agents are bound.
Architecture
AI agents (Claude Desktop, Cursor, ChatGPT, Grok)
| HTTPS (+ OAuth DCR token page, or Authorization: Bearer)
v
Cloudflare Zero Trust ──tunnel──► cloudflared
|
v
Nginx :80 (internal) / MCP_LAN_PORT on the host
OAuth /authorize /token /register /.well-known/* → mcp-oauth (token-paste page)
Bearer IT_TOKEN → role it → /mcp/it/* (it + admin)
Bearer ADMIN_TOKEN → role admin → /mcp/admin/* (admin only)
Bearer ACCOUNTING_TOKEN → role accounting → /mcp/accounting/* (accounting only)
|
+--> mcp-hub-it:3000 Zabbix + MeshCentral inventory
+--> mcp-hub-admin:3000 same + meshcentral_run_shell
+--> mcp-hub-accounting:3000 Express Accounting read-only
|
+--> sub-mcp-zabbix / sub-mcp-meshcentral
+--> sub-mcp-express fixture | http adapter | DBF
|
+--> zabbix-web / zabbix-server / zabbix-db
+--> meshcentral
+--> Express books (sample, sidecar REST, or .DBF)Tools
Tool | IT hub | Admin hub | Accounting hub |
| yes | yes | no |
| yes | yes | no |
| yes | yes | no |
| yes | yes | no |
| no | yes | no |
| no | no | yes |
| no | no | yes |
| no | no | yes |
| no | no | yes |
| no | no | yes |
| no | no | yes |
Nginx rejects an IT token on /mcp/admin/ and /mcp/accounting/ with HTTP 403. An accounting token cannot call IT or admin paths. The IT hub process does not register the shell tool. Express tools are read-only; see docs/EXPRESS.md.
Related MCP server: Enterprise MCP Server
Requirements
Docker Engine 24+ with Compose v2
A host that can reach ESXi / switches / NVR / Windows agents on the LAN (Zabbix server port
10051, MeshCentral443/4433)Optional: Cloudflare account for the public MCP hostname
Quick start
git clone <this-repo>
cd itops-mcp-hub
cp .env.example .envEdit .env:
Generate unique RBAC tokens (URL-safe, no spaces or quotes):
openssl rand -hex 32 # IT_TOKEN openssl rand -hex 32 # ADMIN_TOKEN openssl rand -hex 32 # ACCOUNTING_TOKENSet
ZABBIX_DB_PASSWORDand MeshCentralMESHCENTRAL_PASSWORD/MESHCENTRAL_API_KEY.Leave
CLOUDFLARE_TUNNEL_TOKENempty until Zero Trust is configured.
Bring the stack up (LAN/VPN mode, no tunnel):
docker compose up -dFirst boot of Zabbix Postgres schema can take a couple of minutes. Watch:
docker compose ps
docker compose logs -f zabbix-server zabbix-web nginx mcp-hub-itGateway status page (LAN): http://<compose-host>:9080/
Service | Default LAN port | Notes |
MCP + status page |
| Nginx. MCP paths require a Bearer token |
Zabbix UI |
| First login |
Zabbix server |
| Agents, ESXi, SNMP traps path into the server |
MeshCentral HTTPS |
| Create the first admin when |
MeshCentral agent |
| Agent/MPS |
Cloudflare Tunnel (public MCP URL)
docker compose --profile tunnel up -dcloudflared is distroless and expects a real CLOUDFLARE_TUNNEL_TOKEN. Do not start this profile until the token is set.
First-run: Zabbix API token
The MCP Zabbix server authenticates with a Zabbix API token (Bearer), not the UI password.
Open
http://<host>:9443and log in asAdmin.Change the Admin password; set
ZABBIX_WEB_PASSWORDin.envto match.User menu → API tokens → Create token
mcp-gateway.Put the secret into
ZABBIX_API_TOKENand recreate the Zabbix MCP container:docker compose up -d --force-recreate sub-mcp-zabbix
Alternatively, after the UI is up:
node scripts/create-zabbix-api-token.mjs
# paste the printed value into ZABBIX_API_TOKENCreate host groups that match how you filter devices (ESXi, Switches, CCTV, Windows servers, …). zabbix_get_device_status searches group names.
First-run: MeshCentral
Open
https://<host>:9444(self-signed certificate on a fresh volume).Create the account that matches
MESHCENTRAL_USER/MESHCENTRAL_PASSWORD.Set
MESHCENTRAL_ALLOW_NEW_ACCOUNTS=falseand recreatemeshcentralafter the first admin exists.Install MeshAgents on Windows / Linux / ESXi management jump hosts as needed.
meshcentral_get_inventoryreads the cached node list over/control.ashx(action: "nodes"). CPU/RAM are returned when MeshCentral already stored them on the node object; they are not probed live.meshcentral_run_shellusesruncommands(PowerShell on Windows, POSIX shell otherwise) and is exposed only on the admin hub.
MESHCENTRAL_API_KEY is used as the control-channel password when MESHCENTRAL_PASSWORD is empty. Prefer a dedicated MeshCentral service user. Authentication is the MeshCentral x-meshauth header (base64(user),base64(pass)).
Internal TLS to https://meshcentral:443 uses a self-signed cert. Keep MESHCENTRAL_TLS_INSECURE=true unless you mounted a real certificate into meshcentral-data.
Cloudflare Zero Trust
This is the public path for AI clients. MeshCentral agents and Zabbix pollers stay on the LAN; only the MCP gateway is published.
1. Tunnel
Zero Trust → Networks → Tunnels → Create a locally managed tunnel.
Copy the token into
CLOUDFLARE_TUNNEL_TOKEN.Public hostname, for example
mcp.example.com:Type: HTTP
URL:
http://nginx:80The connector runs inside
infra-net, so it must use the Compose service namenginx, not a host port.
docker compose --profile tunnel up -d
Set PUBLIC_MCP_ORIGIN=https://mcp.example.com (the same public hostname) so ChatGPT/Grok OAuth discovery advertises the real URL. Then recreate mcp-oauth and nginx.
Optional origin settings in the hostname:
HTTP Host Header:
mcp.example.comDisable chunked encoding: off (SSE needs chunked transfer)
No extra origin TLS (nginx listens HTTP on 80)
2. Access application (service tokens)
Zero Trust → Access → Applications → Add Self-hosted.
Application domain:
mcp.example.com(include/mcp*if you split policies).Identity: Service Auth (and optionally your IdP for humans).
Create a Service Token (
Client ID+Client Secret).Policy: Service Token is valid, then allow.
Cloudflare consumes the service token headers at the edge. Configure the application to forward these headers to origin (Access → Application → Settings / Overview, depending on the dashboard version):
Header | Purpose |
| Service token id (validated by Cloudflare, then forwarded) |
| Service token secret |
| Must pass through unmodified — Nginx maps this to |
| Set by Cloudflare after a successful Access login |
If Access strips Authorization, Nginx will 401 every MCP call. Add Authorization to the allowed/forwarded header list, or put the MCP Bearer token in a second Access-approved header and change Nginx — this repo expects Authorization: Bearer <IT_TOKEN|ADMIN_TOKEN|ACCOUNTING_TOKEN>.
Create two Access service tokens if you want to rotate IT and Admin Cloudflare identities independently of the MCP RBAC tokens.
3. SSE through Cloudflare
Nginx already sets proxy_buffering off, gzip off, X-Accel-Buffering: no, and 1-hour proxy timeouts. In the tunnel hostname, do not enable extra buffering or “HTTP/2 to origin” if SSE stalls; HTTP/1.1 to nginx is the safe origin protocol.
Team trial: ChatGPT / Grok (read-only)
ขณะรอ ai-tools-mcp (ชั้นอนุมัติคำสั่ง privileged) ทีมทดลองบน ChatGPT / Grok ได้ เฉพาะเส้น IT
URL:
https://<tunnel-host>/mcp/it/mcp— เลือก OAuth (อย่าเลือก Token ใน ChatGPT ถ้าต้องการหน้าเว็บ)ครั้งแรกเบราว์เซอร์เปิด
https://<tunnel-host>/authorizeให้วางIT_TOKENเหมือน ai-collaboration-mcpตั้ง
PUBLIC_MCP_ORIGIN=https://<tunnel-host>ใน.envแล้ว recreatemcp-oauth+nginxห้าม
ADMIN_TOKENและห้าม/mcp/admin/สำหรับทีมทดลองทีมบัญชีใช้เส้นแยก
https://<tunnel-host>/mcp/accounting/mcp+ACCOUNTING_TOKEN+ scopemcp:accounting— ดู docs/EXPRESS.mdขั้นตอนละเอียดอยู่ที่ docs/TEAM-CONNECT.md
meshcentral_run_shell ยังปิดสำหรับทีมทดลองจนกว่าจะมี payload-hash approval + human queue + audit
MCP client configuration
Replace host, tokens, and Cloudflare service-token values. Claude Desktop still uses the legacy SSE transport (/sse). Newer clients can use Streamable HTTP (/mcp).
Claude Desktop / SSE (IT role)
claude_desktop_config.json:
{
"mcpServers": {
"itops-it": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://mcp.example.com/mcp/it/sse",
"--header",
"Authorization: Bearer ${IT_TOKEN}",
"--header",
"CF-Access-Client-Id: ${CF_ACCESS_CLIENT_ID}",
"--header",
"CF-Access-Client-Secret: ${CF_ACCESS_CLIENT_SECRET}"
]
}
}
}If your client supports URL + headers natively:
{
"mcpServers": {
"itops-it": {
"url": "https://mcp.example.com/mcp/it/sse",
"transport": "sse",
"headers": {
"Authorization": "Bearer IT_TOKEN_HERE",
"CF-Access-Client-Id": "CLIENT_ID.access",
"CF-Access-Client-Secret": "CLIENT_SECRET"
}
},
"itops-admin": {
"url": "https://mcp.example.com/mcp/admin/sse",
"transport": "sse",
"headers": {
"Authorization": "Bearer ADMIN_TOKEN_HERE",
"CF-Access-Client-Id": "CLIENT_ID.access",
"CF-Access-Client-Secret": "CLIENT_SECRET"
}
}
}
}Streamable HTTP
{
"mcpServers": {
"itops-accounting": {
"url": "https://mcp.example.com/mcp/accounting/mcp",
"headers": {
"Authorization": "Bearer ACCOUNTING_TOKEN_HERE"
}
}
}
}LAN test without Cloudflare
curl -sS http://127.0.0.1:9080/healthz
curl -sS -D- -o /dev/null \
-H "Authorization: Bearer $IT_TOKEN" \
http://127.0.0.1:9080/mcp/it/
curl -sS -D- -o /dev/null \
-H "Authorization: Bearer $IT_TOKEN" \
http://127.0.0.1:9080/mcp/admin/
# expect 403 on the admin path
curl -sS -D- -o /dev/null \
-H "Authorization: Bearer $IT_TOKEN" \
http://127.0.0.1:9080/mcp/accounting/
# expect 403 — books are not an IT role
curl -sS -D- -o /dev/null \
-H "Authorization: Bearer $ACCOUNTING_TOKEN" \
http://127.0.0.1:9080/mcp/accounting/Repository layout
docker-compose.yml
nginx/ # RBAC reverse proxy + status page
packages/
Dockerfile # shared Node 22 image, ARG SERVICE=
mcp-common/ # Streamable HTTP + SSE helper
mcp-zabbix/ # Zabbix JSON-RPC tools
mcp-meshcentral/ # MeshCentral control.ashx tools
mcp-express/ # Express Accounting (fixture / HTTP / DBF)
mcp-hub/ # aggregator; HUB_ROLE=it|admin|accounting
mcp-oauth/ # OAuth 2.1 + DCR; /authorize asks for site token
scripts/create-zabbix-api-token.mjs
docs/EXPRESS.md # Express Accounting backends and RBACOperations notes
Rotate
IT_TOKEN/ADMIN_TOKEN/ACCOUNTING_TOKENby changing.envanddocker compose up -d --force-recreate nginx mcp-oauth.Do not publish
mcp-hub-*,sub-mcp-*, orzabbix-dbto the internet.meshcentral_run_shellruns as SYSTEM/root (runAsUser: 0) on the agent. TreatADMIN_TOKENlike production break-glass.After changing MeshCentral hostname or published HTTPS port, update
config.jsonin themeshcentral-datavolume (aliasPort/cert) so agent download URLs stay correct.Logs are JSON lines from the Node services and json-file rotated at 10 MB × 3.
Nested Docker / CI hosts
If containers start but Nginx cannot reach mcp-hub-* (SSE hangs after a 200 auth, ping between containers fails), the kernel is filtering bridged traffic:
sudo sysctl -w net.bridge.bridge-nf-call-iptables=0
sudo sysctl -w net.bridge.bridge-nf-call-ip6tables=0This is a host setting, not a Compose service setting. Normal bare-metal or VM Docker installs already have working inter-container connectivity.
License
Internal operations tooling. Review Zabbix and MeshCentral licenses for the upstream images.
This server cannot be deployed
Maintenance
Related MCP Connectors
Zero-setup MCP gateway securely connecting AI to your tools with authentication and workflows
Let AI agents query data and act across all your business apps via MCP.
- ZapierOAuthcom.zapier
Hosted MCP server connecting AI assistants to 9,000+ apps and 40,000+ actions via Zapier.
MCP server unifying ERPs, CRMs, APIs and knowledge base for Claude, ChatGPT and Gemini.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to discover and execute tools via a secure MCP server with JWT authentication, RBAC, rate limiting, and audit logging.1MIT
- FlicenseNot gradedqualityCmaintenanceA single MCP server that exposes safe, permission-checked tools for AI assistants to reach file systems, databases, APIs, Git, cloud services, and business applications.-
- AlicenseNot gradedqualityBmaintenanceProvides a secure MCP gateway for AI agents to access APIs without exposing raw credentials, with scoped access, audit logging, and OAuth support.MIT
- AlicenseNot gradedqualityCmaintenanceSecure MCP server that exposes WAFpass REST endpoints as tools for AI assistants, with role-based filtering and token validation.Apache 2.0