1. Introduction

Why this platform exists

AI-assisted tools — chat assistants, coding agents, document retrieval — have become a significant productivity multiplier across the software industry. However, EUMETSAT's Directive on the use of Generative AI (DGD) and the Acceptable Use Policy (AUP) rightly restrict cloud-based GenAI services for categories of information where sending data to external providers is not permitted:

Restricted with cloud AIReason
IPR-restricted source codeEUMETSAT may not have redistribution rights to share with external AI providers
Export-controlled codeExport-controlled source code cannot be transmitted to external/cloud services
EUM-exclusive licensed codeCode licensed exclusively for EUMETSAT cannot be exposed to third-party AI platforms
Confidential or restricted informationAUP Section 5: must only be used with EUMETSAT-approved and issued information systems
Sensitive corporate dataInformation that could jeopardise operations or expose internal processes

This creates a significant gap: staff cannot benefit from AI-assisted productivity when working on the most sensitive and critical materials — precisely the areas where AI assistance could deliver the most value. As identified in the DGD feedback process (Item 11): "The use case for running AI on premise for data that is too sensitive to run in the cloud is not covered."

The solution: locally hosted LLMs

The Cloud LLM platform addresses this gap by running large language models on EUMETSAT-owned hardware within the corporate network. No data leaves the EUMETSAT perimeter. There are no external AI providers, no third-party data processors, and no cloud jurisdiction involved. The models run as inference-only services — they are not trained or fine-tuned on EUMETSAT data, and context windows are cleared after each session.

This architectural approach means the platform qualifies as a "EUMETSAT-approved and issued information system" under AUP Section 5, enabling AI-assisted work on the full spectrum of information classifications:

Use caseCloud AILocal LLM
AI-assisted development of non-sensitive code✅ Permitted✅ Permitted
AI-assisted development of IPR-restricted code❌ Prohibited✅ Permitted
AI-assisted development of export-controlled code❌ Prohibited✅ Permitted
AI-assisted development of EUM-exclusive licensed code❌ Prohibited✅ Permitted
AI-assisted analysis of confidential documents❌ Prohibited✅ Permitted
AI-assisted processing of sensitive corporate data❌ Prohibited✅ Permitted
AI-assisted code review and refactoring of sensitive codebases❌ Prohibited✅ Permitted
AI-assisted document retrieval & Q&A on internal knowledge bases❌ Not available✅ Permitted

How local hosting addresses DGD concerns

DGD / policy concernHow local hosting resolves it
Data exfiltration to external AI providersNo data leaves EUMETSAT infrastructure. The LLM runs on EUMETSAT-owned hardware within the corporate network.
Third-party data processing (GDPR, EU AI Act)No third-party processor is involved. All processing is performed by EUMETSAT-owned infrastructure.
IPR and licensing exposureSource code and licensed materials never leave EUMETSAT-controlled systems. No external party gains access.
Export control violationsExport-controlled code is processed entirely within EUMETSAT premises on EUMETSAT-owned hardware.
Cloud Act / foreign government accessNo cloud provider involvement. No foreign jurisdiction applies.
Unclear data retention by AI providersNo external data retention. Context windows are cleared after each session. No model training on EUMETSAT data.
AUP Section 5 — confidential/restricted infoLocally hosted LLMs on EUMETSAT-issued infrastructure qualify as "EUMETSAT-approved and issued information systems."

Architectural principles

  • Inference only. Models are used for generation, not training. No fine-tuning or training is performed on EUMETSAT data.
  • Open-weights models. All models use permissive open-weights licenses (Apache 2.0, MIT, or equivalent), permitting local deployment without commercial licensing dependencies.
  • No external API calls. The LLM does not make any external API calls. Internet access for model inference is disabled by default.
  • Authentication & authorisation. Access is limited to named, authorised users with valid EUMETSAT credentials.
  • Full auditability. All requests are logged with user identity, model, token usage, and timestamps for accountability.
  • No persistent data retention. Context windows are cleared after each interaction. No EUMETSAT data is persisted beyond the active session by the LLM.

Current status

This platform is currently a Proof of Concept (PoC). Access is restricted to named, authorised users and is not yet intended for wide-scale deployment. The PoC serves to validate the architecture, evaluate model quality for EUMETSAT use cases, and support the formal vetting process under DGD Section 4.

Strategic value. A vetted local LLM infrastructure enables EUMETSAT to unlock AI productivity for sensitive work, maintain full data sovereignty, comply with existing policies by design, and pave the way for broader adoption — including AI agents, MCP-based integrations, and AI-assisted software development for sensitive codebases.
↑ Back to top

2. Requesting Access

How to get access

To request access to the EUMETSAT Cloud LLM platform, send an email to borys.saulyak@eumetsat.int with a short description of your intended use case. An administrator will create your account and provide onboarding instructions.

What you get

Once approved, you receive:

  • A LibreChat account — the chat web UI for interactive use, available at https://llm.cloud.eumetsat.int/chat/.
  • An API key — for programmatic access to the OpenAI-compatible LLM Gateway endpoint.

Registration

Account registration is restricted to the following email domains:

  • @eumetsat.int (staff)
  • @external.eumetsat.int (contractors and external collaborators)

Teams

Users are assigned to a team for budget tracking and usage attribution. When requesting access, you can either:

  • Ask to join an existing team, or
  • Request a new team to be created for your group

Each user can only belong to one team at a time. If your role changes, contact the administrator to switch teams.

LLM Gateway console & self-management

The LLM Gateway console is available to all users for self-service account management:

  • Regenerate or rotate your API key
  • Reset your password
  • View your personal usage statistics and spend

Administrative features — model management, team budget tracking, virtual keys, and global usage analytics — require admin privileges. To request admin access, contact borys.saulyak@eumetsat.int with a justification.

↑ Back to top

3. Using LibreChat

LibreChat is the primary chat interface for the platform. To get started:

  1. Navigate to https://llm.cloud.eumetsat.int/chat/
  2. Register an account using your EUMETSAT email. Registration is limited to @eumetsat.int and @external.eumetsat.int domains.
  3. Sign in with your EUMETSAT email and password.

Models available in the dropdown

Select a model from the dropdown in the prompt bar. The following aliases are available:

auto, medium, qwen-vl-medium, big, huge, ragflow-kb

Only aliases are callable. Backend model names (e.g. qwen3.8-27b, glm-5.2-fp8) are shown for reference only and are not accepted by the API.

Agents

LibreChat ships with four pre-configured agents that bundle a model, a set of MCP tools, and tuned settings. Pick the agent that best fits your task from the agent selector:

AgentModelContextPurpose
My EUMETSAT Assistant
(default)
qwen-vl-medium 100K General-purpose assistant with vision support. Supports image uploads. Use for everyday tasks and image/screenshot analysis.
EUMETSAT Assistant XXL huge (glm-5.2-fp8) 200K Largest available model. For complex reasoning, long-document analysis and multi-step tasks. No vision.
EUMETSAT Assistant XL big (glm-5.2-w4a16) 160K Faster and cheaper than XXL, for complex reasoning and multi-step tasks. No vision.
EUMETSAT Assistant (auto) auto 200K Automatically selects the best model based on prompt size. Context window adapts automatically. No vision.

Image uploads

To upload an image and ask questions about it, select the My EUMETSAT Assistant agent (model qwen-vl-medium). LibreChat detects vision capability by checking the model name; only this agent enables the image upload button.

Memory

The assistant has a persistent key/value memory store — it remembers your preferences across conversations. You can toggle memory on or off per conversation from the conversation settings.

Web search

Built-in SearxNG + Firecrawl web search is pinned to the prompt bar by default. Use it to retrieve up-to-date information from the public web within your chat.

MCP Tools in chat

Several MCP (Model Context Protocol) tools are available directly in the chat. See Section 8 — MCP Tools for the full list. The tools include:

  • web-fetch — fetch and read content from web URLs
  • email — send emails to @eumetsat.int addresses
  • code — execute Python or Bash code in isolated containers
  • ragflow — search and upload documents to the knowledge base
  • ocr — extract text from PDFs and images
  • jira — read and write Jira issues and Confluence pages (OAuth 2.0)

File uploads

You can attach files to any conversation. Limits:

  • Up to 1024 MB per file
  • Up to 1024 MB total per conversation
↑ Back to top

4. API Access from Python

The platform exposes an OpenAI-compatible API via the LLM Gateway. You can use any OpenAI SDK client by pointing it at the EUMETSAT endpoint.

Endpoint & authentication

  • Base URL: https://llm.cloud.eumetsat.int/models/v1
  • API key: Get one from the LLM Gateway console at https://llm.cloud.eumetsat.int/models/ui/ (admin access required), or request one by email.
  • Protocol: OpenAI-compatible — any OpenAI SDK client works out of the box.
  • Model names: Use aliases (auto, medium, big, huge). Backend names are not accepted.

Example 1 — Basic chat completion (Python)

from openai import OpenAI

client = OpenAI(
    base_url="https://llm.cloud.eumetsat.int/models/v1",
    api_key="sk-your-api-key-here"
)

response = client.chat.completions.create(
    model="medium",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What is the MTG satellite mission?"}
    ]
)
print(response.choices[0].message.content)

Example 2 — Streaming response

stream = client.chat.completions.create(
    model="medium",
    messages=[{"role": "user", "content": "Explain radiometric calibration."}],
    stream=True
)
for chunk in stream:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="")

Example 3 — curl

curl https://llm.cloud.eumetsat.int/models/v1/chat/completions \
  -H "Authorization: Bearer sk-your-api-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "medium",
    "messages": [{"role": "user", "content": "Hello!"}]
  }'
Note: Replace sk-your-api-key-here with your actual API key. Never commit API keys to version control.
↑ Back to top

5. VS Code & OpenCode

What is OpenCode

OpenCode is an AI coding assistant — similar to GitHub Copilot — that runs in the terminal and connects directly to the EUMETSAT LLM infrastructure. It gives you full control over which models are used for which tasks, and supports custom subagents with dedicated system prompts.

Configuration files

OpenCode reads its configuration from two locations:

  • Global: ~/.config/opencode/opencode.jsonc — provider, models, primary agent, built-in agent overrides
  • Project-level: .opencode/agent/*.md — custom subagent definitions (one Markdown file per subagent)

Provider configuration

The global config defines the LLM Gateway provider, available models, and the primary agent. It also overrides the built-in explore subagent to use the cheaper medium model instead of inheriting the primary agent's expensive model:

{
  "$schema": "https://opencode.ai/config.json",
  "model": "litellm/big",
  "agent": {
    "build": {
      "model": "litellm/big",
      "permission": {
        "task": { "*": "allow", "general": "deny" }
      }
    },
    "explore": {
      "model": "litellm/medium"
    }
  },
  "provider": {
    "litellm": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "EUMETSAT Cloud LLM",
      "options": {
        "baseURL": "https://llm.cloud.eumetsat.int/models/v1",
        "apiKey": "sk-your-api-key-here"
      },
      "models": {
        "medium": { "name": "medium", "limit": { "context": 131072, "output": 32768 } },
        "big":    { "name": "big",    "limit": { "context": 160000, "output": 32768 } },
        "huge":   { "name": "huge",   "limit": { "context": 200000, "output": 40000 } }
      }
    }
  }
}
Why override explore and deny general?
  • The built-in explore subagent has no model field, so it inherits the primary agent's model (big, $0.60/1M). Overriding it to medium ($0.25/1M) makes it 2.4× cheaper — delegation now saves real money.
  • The built-in general subagent overlaps with research and explore and also inherits the expensive model. Denying it from the Task tool ("general": "deny") removes it from automatic routing, simplifying the model's choice.

Subagents: what they are and why they matter

A subagent is a specialized AI assistant that the main agent (running on big, $0.60/1M tokens) can delegate work to. Each subagent runs in a fresh context — large file reads it makes do not enter the main agent's context. Only the subagent's summary comes back. This has two benefits:

  • Cost: read-only investigation delegated to research ($0.25/1M) is 2.4× cheaper than doing it on the main agent.
  • Context hygiene: a 30K-token file read by a subagent costs 30K × $0.25/1M = $0.0075 and returns a ~2K summary. Doing it directly costs 30K × $0.60/1M = $0.018 and the 30K stays in context for every subsequent turn, compounding costs.

Subagent lineup

Four subagents are available for automatic delegation, plus one hidden agent for manual use:

SubagentModelContextCost/inRole
explore (built-in)medium131K$0.25Quick codebase lookups, single-file Q&A, pattern searches
researchmedium131K$0.25Multi-file investigation, git history, summaries (has bash)
codebig160K$0.60Writing/editing code, refactoring, testing
experthuge200K$2.00Complex reasoning, long docs, architecture decisions
fast (hidden)medium131K$0.25Manual-only batch trivial lookups via @fast

Delegation policy: when to delegate vs. do directly

The main agent decides when to delegate based on subagent descriptions and the delegation policy in AGENTS.md. The policy is tuned to maximize savings without adding overhead for trivial tasks:

ScenarioActionWhy
Multi-file investigation (3+ files, >10K tokens, 5+ tool calls) Delegate to research 2.4× cheaper per token + context isolation keeps main context lean
Git history analysis across files, comparing implementations Delegate to research Research has bash access for git log/diff/blame; explore does not
Quick lookup, single-file Q&A, pattern search Delegate to explore Now on medium ($0.25), 2.4× cheaper than main agent
Task exceeds main model's capability or >130K token documents Delegate to expert 200K context, deepest reasoning; expensive but necessary for hard problems
Single file you will edit next Read directly Delegating then re-reading doubles the work
Single Grep/Glob that answers the question Do it directly Delegation overhead (~500 tokens) exceeds the saving (~$0.0003)
One trivial command like git status Run it directly Overhead of describing the task + parsing result > cost of just doing it
Why was fast hidden?
The fast subagent (medium model, $0.25/1M) was designed for trivial lookups, but that's exactly the case where delegation overhead exceeds the saving. A single git status costs ~$0.0003 on the main agent — spawning a subagent to save that fraction of a cent adds latency and context-transfer overhead. After overriding explore to medium, explore covers quick lookups better and at the same $0.25/1M. fast is kept as hidden: true for manual @fast batch use only.

Why "Use PROACTIVELY" matters

OpenCode's Task tool has a built-in rule: if a subagent's description contains the phrase "use proactively" (or equivalent), the main agent will try to invoke it without the user asking. Without this trigger phrase, the main agent defaults to doing everything itself — which is exactly what was happening before.

The research and expert subagent descriptions now include this trigger. The research description also includes explicit boundary text ("Do NOT use for a single file read or a single grep") to avoid conflicting with OpenCode's hardcoded guidance that says to do simple reads directly.

Subagent configuration files

Each subagent is defined by a Markdown file in .opencode/agent/. The filename (minus .md) becomes the agent name. Here are the actual configurations:

.opencode/agent/research.md — multi-file investigation (medium, $0.25/1M)
---
description: >
  Read-only investigation agent on the medium model (2.4x cheaper than the main agent).
  Use PROACTIVELY for: multi-file investigations (3+ files), explaining how a feature
  works across modules, git history analysis (git log/diff across files), summarizing
  or comparing implementations, and any exploration that will read more than ~10K tokens
  of source. Returns a structured summary so the main context stays lean. Do NOT use for
  a single file read or a single grep — do those directly with Read/Grep.
mode: subagent
model: litellm/medium
permission:
  edit: deny
  bash:
    "git status": allow
    "git log*": allow
    "git diff*": allow
    "git show*": allow
    "git blame*": allow
    "ls*": allow
    "cat*": allow
    "grep*": allow
    "find*": allow
    "wc*": allow
    "tree*": allow
    "rg*": allow
    "*": ask
---

You are the Research subagent, powered by the medium model (Qwen3.8-27B, 131K context).

You are invoked for research and investigation tasks:
- Answering complex questions about the codebase
- Multi-step research across multiple files
- Git history analysis (log, diff, blame across files)
- Summarizing findings and producing reports
- Comparing approaches and trade-off analysis
- Any task that needs thorough exploration without making changes

You are read-only. You cannot edit files.
Be thorough and structured in your responses.
Return a concise summary — the main agent only needs your findings, not raw file contents.
.opencode/agent/expert.md — escalation for hard problems (huge, $2.00/1M)
---
description: >
  Expert agent on the largest model (200K context, deepest reasoning). Use PROACTIVELY
  when the task requires reasoning beyond the main model's capability, when processing
  documents over 130K tokens, or during multi-step debugging where the main model is
  stuck or going in circles. Expensive — reserve for genuinely hard problems the main
  agent cannot resolve.
mode: subagent
model: litellm/huge
permission:
  edit: allow
  bash: allow
---

You are the Expert subagent, powered by the largest available model (GLM-5.2-FP8, 200K context).

You are invoked when the main agent encounters tasks that require:
- Deep reasoning or complex analysis
- Long document processing (up to 200K tokens)
- Multi-step architectural decisions
- Debugging complex issues across multiple files
- Tasks that exceed the medium model's capability

You have full read/write/bash permissions. Be thorough and deliberate.
Always explain your reasoning before taking action.
.opencode/agent/code.md — code generation (big, $0.60/1M)
---
description: Code agent for code generation, editing, refactoring, and implementation tasks. Uses the big model optimized for coding.
mode: subagent
model: litellm/big
permission:
  edit: allow
  bash:
    "npm*": allow
    "npx*": allow
    "python*": allow
    "pip*": allow
    "git add*": allow
    "git commit*": allow
    "*": ask
---

You are the Code subagent, powered by the big model (GLM-5.2-W4A16, 160K context).

You are invoked for coding tasks:
- Writing new code or components
- Editing existing files
- Refactoring code
- Running tests and linting
- Implementing features described by the main agent

Follow existing code conventions. Check neighboring files for patterns
before writing. Use existing libraries — never assume a library is available
without checking package.json or equivalent.

Do not add comments unless asked. Keep code clean and idiomatic.
.opencode/agent/fast.md — hidden, manual-only (medium, $0.25/1M)
---
description: Fast agent for quick lookups, simple file reads, git status, formatting, and other lightweight tasks. Uses the medium model for speed. Invoke manually with @fast for batch trivial lookups.
mode: subagent
model: litellm/medium
hidden: true
permission:
  edit: deny
  bash:
    "git status": allow
    "git log*": allow
    "git diff*": allow
    "ls*": allow
    "cat*": allow
    "*": ask
---

You are the Fast subagent, powered by the medium model (Qwen3.8-27B, 131K context).

You are invoked for quick, simple tasks:
- Git status, log, diff lookups
- File listing and reading
- Simple string searches
- Formatting outputs
- Any task that doesn't require deep reasoning

You are read-only. You cannot edit files or run complex commands.
Keep responses short and factual. Do not explain — just return the result.

Worked examples

Example 1: Investigating how authentication works across the codebase

The user asks: "How does the nginx auth_request proxy work in this project?"

This requires reading nginx.conf, docker-compose.yaml, and the dashboard's auth handler — 3+ files, likely >10K tokens. The main agent delegates to research:

Main agent (big, $0.60/1M)
  └─ delegates to research (medium, $0.25/1M)
       ├─ reads nginx.conf (8K tokens)
       ├─ reads docker-compose.yaml (5K tokens)
       ├─ reads live-dashboard.py auth section (3K tokens)
       ├─ runs git log --oneline nginx.conf
       └─ returns 2K summary to main agent

Cost: ~18K tokens × $0.25/1M = $0.0045 (research)
    + 2K summary × $0.60/1M = $0.0012 (main agent re-reads summary)
    = $0.0057 total

Without delegation: 18K × $0.60/1M = $0.0108, plus 18K stays
in context for every subsequent turn (10 turns × $0.0108 = $0.108).

Saving: 47% per turn, 95% over a 10-turn session.

Example 2: Single grep — do it directly

The user asks: "Where is the LLM Gateway URL defined?"

This is a single grep — the main agent does it directly:

Main agent (big, $0.60/1M)
  └─ runs grep "LITELLM_URL" → 3 matches in 1 file

Cost: ~500 tokens × $0.60/1M = $0.0003

Delegating to research would cost: task-description (~300 tokens
at $0.25/1M) + grep (~500 tokens at $0.25/1M) + summary (~200
tokens at $0.60/1M) = $0.00032 + overhead. Delegation now costs
slightly more than direct ($0.00002) AND adds latency — not worth it.

Example 3: Stuck on a complex bug — escalate to expert

The main agent has tried 3 approaches to fix a Docker networking issue and keeps going in circles. It escalates to expert:

Main agent (big, $0.60/1M)
  └─ delegates to expert (huge, $2.00/1M)
       ├─ reads docker-compose.yaml, nginx.conf, network configs
       ├─ analyzes 50K of logs and source
       └─ returns diagnosis + fix

Expert cost: 50K × $2.00/1M = $0.10
Main agent savings: doesn't burn 50K of its own context
($0.03) and gets a correct answer instead of looping.

VS Code Copilot

VS Code Copilot can also be configured to use the EUMETSAT endpoint via the GitHub Copilot custom model settings. However, OpenCode is the recommended approach for full control over models and subagents.

Note: Install OpenCode with npm install -g opencode or visit https://opencode.ai for installation instructions.
↑ Back to top

6. Available Models

All models are served on self-hosted vLLM backends — no external API calls are made. Use the alias names in your client or chat; only aliases are callable.

AliasBackendMax ContextMax ParallelIn/Out per 1M
autoCost-based routing (medium + huge)131K (200K via fallback)Cheapest eligible
hugeglm-5.2-fp8200K8$2.00 / $8.00
bigglm-5.2-w4a16160K16$0.60 / $3.00
mediumqwen3.8-27b131K20$0.25 / $1.00
qwen-vl-mediumqwen3.8-27b (vision)131K20$0.25 / $1.00
ragflow-kbRAGflow chat assistantFree
Note: Pricing is for internal accounting and budget tracking only — not real costs.

Auto-routing

When you use the auto model, the system routes your request to the cheapest model that fits your prompt size:

  • Prompt < 131K tokens → medium ($0.25 / $1.00)
  • Prompt 131K–200K tokens → huge ($2.00 / $8.00)

Context window fallbacks

If a prompt exceeds a model's context window, the system automatically falls back to a larger model instead of returning an error:

  • auto (131K) → big (160K) → huge (200K)
  • medium (131K) → big (160K) → huge (200K)
  • qwen-vl-medium (131K) → big (160K) → huge (200K)
  • big (160K) → huge (200K)

Backend names (not callable)

Backend model names — qwen3.8-27b, glm-5.2-w4a16, glm-5.2-fp8 — are shown in the table above for reference only. They are not accepted by the API. Use the corresponding alias.

↑ Back to top

7. RAGflow / Knowledge Base

RAGflow provides retrieval-augmented generation (RAG) for the platform. It is integrated directly into LibreChat — you interact with it through the chat interface, not a separate UI.

Uploading documents

To analyse a document with RAG, simply upload it in a LibreChat conversation (using the attachment button or drag-and-drop). The AI assistant will parse the document and answer questions about its contents. Documents are processed per-user and are not shared with other users.

Supported formats: PDF, Word (.docx), plain text, and most text-bearing files. Scanned documents and images are handled by built-in DeepDOC OCR.

Shared knowledge base

The platform has a shared corporate knowledge base called “Public Documents”. Documents added by administrators are searchable by all users through the ragflow-kb model in LibreChat or via the API. Contact borys.saulyak@eumetsat.int if you need a document added to the shared knowledge base.

API access

Query the shared knowledge base through the standard LLM Gateway API:

response = client.chat.completions.create(
    model="ragflow-kb",
    messages=[{"role": "user", "content": "What does the MTG IRS instrument do?"}]
)
↑ Back to top

8. MCP Tools

MCP (Model Context Protocol) tools are available directly in LibreChat chat. The AI assistant can invoke them on your behalf to interact with external systems. The following tools are available:

ToolIconDescription
web-fetch🌐Fetch and read content from web URLs
email📧Send emails to @eumetsat.int addresses (send_email, send_summary_email)
code💻Execute Python or Bash code in isolated Docker containers
ragflow📚Search the corporate knowledge base, upload and parse documents
ocr📝Extract text from PDFs and images (scanned documents, figures)
jira🎟Read and write Jira issues and Confluence pages (OAuth 2.0)
Notes:
  • Tools are pinned to the prompt bar by default in LibreChat.
  • Jira/Confluence requires one-time OAuth authentication — click the tool icon in the prompt bar to authorize.
  • Code execution runs in isolated containers — there is no persistent filesystem between runs.
  • Email recipients are restricted to @eumetsat.int domains.
↑ Back to top

9. Architecture

Infrastructure overview

The platform spans three public-facing hosts and five internal-only VMs on the 192.168.168.0/24 network. All inference runs on NVIDIA H200 GPUs — two full 8-GPU nodes for the largest models, and one full H200 for smaller models.

flowchart TB USER(["End Users
(browser)"]) API(["API Clients
(curl, OpenCode)"]) subgraph EXT["External Services"] ATL[("Atlassian Cloud
Jira + Confluence")] OUTLOOK[("EUMETSAT Outlook
SMTP")] HF[("HuggingFace
model weights")] LE[("Let's Encrypt")] end subgraph PUB["Public Hosts"] WEBHOST["web-stack host
185.52.194.25
llm.cloud.eumetsat.int
LLM Gateway + LibreChat + MCP servers"] R1["llmvm-r1 (PUBLIC)
199.195.56.160
8× H200 · TP=8
glm-5.2-fp8 (huge) · 200K
:85 → :8000"] RAGHOST["ragflow host
185.52.194.194
ragflow.cloud.eumetsat.int
RAGflow · CPU mode"] end subgraph INT["Internal VMs — 192.168.168.0/24"] R2["llmvm-r2
192.168.168.202
8× H200 · TP=8
glm-5.2-w4a16 (big) · 160K"] MED["llmvm-medium
192.168.168.27
Full H200 (141 GB)
qwen3.8-27b (medium) · 131K · vision"] MCPVM["MCP VM
192.168.168.196
mcp-atlassian :9000
73 Jira/Confluence tools"] end USER --> WEBHOST API --> WEBHOST WEBHOST ==>|"huge"| R1 WEBHOST ==>|"big"| R2 WEBHOST ==>|"medium"| MED WEBHOST -->|"proxy"| MCPVM MCPVM -.->|"OAuth"| ATL WEBHOST -.->|"email"| OUTLOOK R1 -.-> HF WEBHOST -.-> LE RAGHOST -.-> LE

Software deployment

Traffic enters through nginx (TLS termination), which routes to LibreChat (chat UI) and LLM Gateway (model gateway). The LLM Gateway routes inference requests to the appropriate vLLM backend using cost-based routing with automatic context-window fallbacks. Six MCP servers provide tool capabilities (email, code execution, RAG, OCR, web fetch, Jira/Confluence) to both LibreChat and API clients.

flowchart TB USER(["End User"]) API(["API Client"]) subgraph WS["web-stack — 185.52.194.25"] NGX["nginx :443
/chat/ /models/ /atlassian/ /dashboard/"] subgraph LLG["LLM Gateway"] LIT["LLM Gateway :4000
cost-based router
context-window fallbacks"] PG[("postgres :5432")] RED[("redis :6379")] end subgraph LCG["LibreChat UI"] LIB["librechat :3080
4 agents · memory · web search"] MGO[("mongodb :27017")] end EM["email-mcp :8000 → postfix → Outlook"] CODE["code-mcp :8001"] RAGM["ragflow-mcp :8002"] OCR["ocr-mcp :8003"] WF["web-fetch-mcp :8004"] end subgraph VLLM["vLLM backends"] V1["r1: glm-5.2-fp8 · 200K"] V2["r2: glm-5.2-w4a16 · TP=8 · 160K"] V3["medium: qwen3.8-27b · 131K"] end subgraph RAGG["ragflow — 185.52.194.194"] RAGF["ragflow :80
KB + chat assistant"] ES[("elasticsearch")] EMB["embeddings
bge-small-en-v1.5"] end subgraph MCPG["MCP VM — 192.168.168.196"] MCPA["mcp-atlassian :9000
Jira + Confluence"] end USER --> NGX API --> NGX NGX -->|"/chat/"| LIB NGX -->|"/models/"| LIT NGX -->|"/atlassian/"| MCPA LIB -->|"inference"| LIT LIT --> PG LIT --> RED LIT ==>|"routing"| VLLM LIB --> EM LIB --> CODE LIB --> RAGM LIB --> OCR LIB --> WF RAGM -->|"https"| RAGF RAGF --> ES RAGF --> EMB MCPA -.->|"OAuth"| ATL2[("Atlassian Cloud")]

How to render these diagrams

These diagrams use Mermaid syntax. You can copy the diagram source and paste it into the Mermaid Live Editor to export as PNG or SVG. In VS Code, install the "Markdown Preview Mermaid Support" extension to preview diagrams in any .md file.

↑ Back to top