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 AI | Reason |
|---|---|
| IPR-restricted source code | EUMETSAT may not have redistribution rights to share with external AI providers |
| Export-controlled code | Export-controlled source code cannot be transmitted to external/cloud services |
| EUM-exclusive licensed code | Code licensed exclusively for EUMETSAT cannot be exposed to third-party AI platforms |
| Confidential or restricted information | AUP Section 5: must only be used with EUMETSAT-approved and issued information systems |
| Sensitive corporate data | Information 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 case | Cloud AI | Local 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 concern | How local hosting resolves it |
|---|---|
| Data exfiltration to external AI providers | No 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 exposure | Source code and licensed materials never leave EUMETSAT-controlled systems. No external party gains access. |
| Export control violations | Export-controlled code is processed entirely within EUMETSAT premises on EUMETSAT-owned hardware. |
| Cloud Act / foreign government access | No cloud provider involvement. No foreign jurisdiction applies. |
| Unclear data retention by AI providers | No external data retention. Context windows are cleared after each session. No model training on EUMETSAT data. |
| AUP Section 5 — confidential/restricted info | Locally 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.
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 top3. Using LibreChat
LibreChat is the primary chat interface for the platform. To get started:
- Navigate to https://llm.cloud.eumetsat.int/chat/
- Register an account using your EUMETSAT email. Registration is limited to
@eumetsat.intand@external.eumetsat.intdomains. - 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
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:
| Agent | Model | Context | Purpose |
|---|---|---|---|
| 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.intaddresses - 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
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!"}]
}'
sk-your-api-key-here with your actual API key. Never commit API keys to version control.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 } }
}
}
}
}
explore and deny general?
- The built-in
exploresubagent has nomodelfield, so it inherits the primary agent's model (big, $0.60/1M). Overriding it tomedium($0.25/1M) makes it 2.4× cheaper — delegation now saves real money. - The built-in
generalsubagent overlaps withresearchandexploreand 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:
| Subagent | Model | Context | Cost/in | Role |
|---|---|---|---|---|
explore (built-in) | medium | 131K | $0.25 | Quick codebase lookups, single-file Q&A, pattern searches |
research | medium | 131K | $0.25 | Multi-file investigation, git history, summaries (has bash) |
code | big | 160K | $0.60 | Writing/editing code, refactoring, testing |
expert | huge | 200K | $2.00 | Complex reasoning, long docs, architecture decisions |
fast (hidden) | medium | 131K | $0.25 | Manual-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:
| Scenario | Action | Why |
|---|---|---|
| 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 |
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.
npm install -g opencode or visit https://opencode.ai for installation instructions.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.
| Alias | Backend | Max Context | Max Parallel | In/Out per 1M |
|---|---|---|---|---|
auto | Cost-based routing (medium + huge) | 131K (200K via fallback) | — | Cheapest eligible |
huge | glm-5.2-fp8 | 200K | 8 | $2.00 / $8.00 |
big | glm-5.2-w4a16 | 160K | 16 | $0.60 / $3.00 |
medium | qwen3.8-27b | 131K | 20 | $0.25 / $1.00 |
qwen-vl-medium | qwen3.8-27b (vision) | 131K | 20 | $0.25 / $1.00 |
ragflow-kb | RAGflow chat assistant | — | — | Free |
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.
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.
.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:
| Tool | Icon | Description |
|---|---|---|
| web-fetch | 🌐 | Fetch and read content from web URLs |
| 📧 | 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) |
- 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.intdomains.
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.
(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.
/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.