Skip to content

Alembic

Field Value
Owner Olger Avila (IT)
Status live
Runs on Windows Server, "Jetty box" (192.168.1.6, office LAN)
Connectivity Public HTTPS via Caddy reverse proxy, NOT via Cloudflare Tunnel
Hostname mcp.alquemis.com
Repository Alquemis-Automation/Alembic (private) — moved from Olger's personal account, renamed from "MCP-Internal"

What it is

A read-only MCP server giving Claude (and other authorized MCP clients) access to two Alquemis data sources:

  • Oracle INTG4PDB — company catalog, global config, and the Compras app's purchase requests/POs (schema BIO).
  • SAP Business One — via a local Oracle cache (BIO.SB1_* tables, refreshed by ETL at 3am; up to ~24h stale), and optionally the live SAP B1 Service Layer (client exists, currently unused by any active tool — kept on standby for future real-time needs).

Built with FastMCP (mcp[cli]), Python 3.13. Publishes six read-only JSON-RPC tools; nothing creates, modifies, or cancels data in either system.

Athanor built its own SAP B1 connector/MCP independently in the same window this one was being finished (2026-07-09) — see connectors/sap-b1/README.md for that history. Olger's is the canonical implementation going forward; Athanor's was retired to avoid duplicate work.

Tools published

Tool Function
list_companias(estado='A', etl='S') List group companies (initials, alias, name, tax ID)
get_compania(compania) Detail for one company, by initials or alias
get_config(config) Value of a global config entry
get_open_purchase_orders(compania, proveedor) Open POs for a supplier
get_purchase_order_lines(compania, doc_entry) Lines of a PO by DocEntry
get_purchase_order_full(compania, doc_entry) Combined SAP + INT_SOLCOMP view, including inconsistencies

How it's reached

Endpoint: https://mcp.alquemis.com/<TOKEN>/, MCP streamable-HTTP transport.

Claude ──HTTPS──► mcp.alquemis.com/<TOKEN>/  (443, TLS)
                        │  201.202.107.128 → NAT → 192.168.1.6
                        ▼
                     Caddy
                        │  1. terminates TLS (Let's Encrypt)
                        │  2. validates the token in the URL path
                        │  3. rewrites Host → localhost:8000
                        ▼
              127.0.0.1:8000  (FastMCP / Uvicorn, loopback-only)
                        │  4. validates Host (anti DNS-rebinding)
                        │  5. dispatches the requested tool
                        ▼
              Oracle (192.168.1.5:1521) or, optionally, SAP B1 Service Layer

Security notes: - The Python MCP process only listens on loopback (127.0.0.1:8000) — never directly reachable from the network. Caddy is the only component with public ports (80/443). - The token is embedded in the URL path (handle_path /<TOKEN>/*); any request without it gets a 404, not a 401 — the service's existence isn't revealed to unauthenticated requests. - FastMCP rejects requests with an unexpected Host header (anti DNS-rebinding), which is why Caddy must rewrite Host to localhost:8000 before proxying. - Oracle access uses a dedicated read-only user (BIOMCP) with grants limited to select/ execute on specific objects — even a compromised MCP process can't write to Oracle.

Configuration

.env file on the server (not versioned) holds Oracle/SAP connection parameters. SAP B1 Service Layer credentials are read dynamically from the Oracle table BIO.SB1_GENERAL, not hardcoded anywhere in the app.

Dependencies

  • Oracle INTG4PDB at 192.168.1.5:1521 (Easy Connect: 192.168.1.5:1521/INTG4PDB.Bioland.local)
  • SAP B1 Service Layer at sap-bioland-sl.skyinone.net:50000 (/b1s/v2/) — client exists, not currently used by any active tool
  • Caddy + Let's Encrypt (auto-renewed TLS for mcp.alquemis.com)
  • Windows services via NSSM (caddy, mcp-sapb1)
  • Consumer: Mycelium's procurement agent (Hyphae / "Compras Agent")

Known limitations

  • Read-only. No creates, updates, or cancellations of POs, business partners, or items.
  • Cache staleness. PO queries hit the local Oracle cache (ETL at 3am) — up to 24h behind SAP B1, not real-time.
  • Narrow scope. Only the six tools listed — no items, sales orders, invoices, etc.
  • Manual deploy. No CI/CD; deploy is git push + copy server.py to the server + restart the Windows service.
  • Single shared token. Auth is one bearer token in the URL, not per-user identity — no rotation automation.