AI Fundamentals
Knowledge Wiki
A visual reference covering AI API formats, model serving, token economics, MCP protocol, and building model-agnostic applications.
API Payload Formats
OpenAI, Claude, and Gemini payload formats side-by-side.
Message Roles
system, user, and assistant roles — how conversation state works.
Temperature
0.0 to 2.0 — when to use deterministic vs creative output.
Tokens & Cost
Context windows, input/output pricing, and cost math.
vLLM vs Ollama
Dev-friendly vs production-grade local model servers.
LiteLLM
One Python library to talk to any AI provider.
Multiple Models
Run 4–6 models in parallel on your GPU server.
Model-Agnostic App
Swap models with one string change — LiteLLM router pattern.
API Keys
.env for local, K8s Secrets for production, OAuth for services.
Claude.ai vs Code
Browser chat vs terminal agent — when to use each.
What is MCP
Open standard for connecting AI to external tools and data.
MCP Server
The middleman that translates MCP calls to real service APIs.
Tools, Resources & Prompts
Tools (actions), Resources (data), Prompts (templates).
Who Hosts What
Vendor-hosted vs self-hosted — who owns the data decides.
Connecting to MCP
Claude.ai connectors, Desktop config, or programmatic client.
MCP Credentials
Credential storage patterns for local dev and production.
Writing MCP Servers
pip install mcp — three decorators, done.
MCP & Token Cost
Tool definitions cost tokens on every call — optimise early.
API Payload Formats
Each AI provider has its own API structure. OpenAI's format became the de facto standard — most providers copied it. Gemini is the most different. Claude is close but has one key quirk.
🤖 OpenAI — De Facto Standard
POST /v1/chat/completions · system prompt lives inside messages array
POST api.openai.com/v1/chat/completions
{
"model": "gpt-4o",
"messages": [
{"role":"system", "content":"..."},
{"role":"user", "content":"..."}
],
"temperature": 0.7,
"max_tokens": 1000
}
🧠 Claude — Key Difference
POST /v1/messages · system prompt is a TOP-LEVEL field, not inside messages
POST api.anthropic.com/v1/messages
{
"model": "claude-sonnet-4...",
"max_tokens": 1000, ← required!
"system": "...", ← top level ⚠️
"messages": [
{"role":"user", "content":"..."}
]
}
🌐 Gemini — Most Different
POST /v1beta/models/gemini:generateContent · uses "contents" not "messages", "parts" not "content", "model" not "assistant"
{
"contents": [ ← NOT "messages"
{ "role": "user", "parts": [{"text": "Hello"}] }, ← "parts" NOT "content"
{ "role": "model", "parts": [{"text": "Hi!"}] } ← "model" NOT "assistant"
],
"generationConfig": { "temperature": 0.7, "maxOutputTokens": 1000 }
}
| Provider | Endpoint | Messages Key | System Prompt | AI Role Name | Compatibility |
|---|---|---|---|---|---|
| OpenAI | /v1/chat/completions | messages[] | Inside messages | assistant | Standard |
| Claude | /v1/messages | messages[] | Top-level field | assistant | Has adapter |
| Gemini | /v1beta/…:generateContent | contents[] | systemInstruction | model | Most different |
| Mistral | /v1/chat/completions | messages[] | Inside messages | assistant | OpenAI clone |
| Grok | /v1/chat/completions | messages[] | Inside messages | assistant | OpenAI clone |
| Ollama | /api/chat | messages[] | Inside messages | assistant | OpenAI clone |
Message Roles
Every message has a role — who is speaking. The AI reads all messages in order on every call. There is no memory between calls — you must resend the full history every time.
system — The Director
Sets rules, personality, and constraints before conversation starts. User never sees this. Runs first on every call. Think of it as the AI's job description.
Be concise. Always include bay location." }
user — The Human
The actual human input — questions, requests, commands. What the person types.
assistant — The AI's Past Replies
The AI's own previous responses. You include these to give the AI conversation memory — because each call is stateless. No history = no context.
Temperature
Controls how creative or deterministic the AI's response is. Range: 0.0 to 2.0. Low = focused and consistent. High = creative and unpredictable.
Tokens & Cost
A token is roughly ¾ of a word (English). Everything sent and received is counted. Input and output tokens are billed separately — output costs more.
📏 What is a Token
1 token ≈ 4 characters ≈ ¾ of a word. Non-English (Bahasa, Arabic, Chinese) uses more tokens per word than English.
📥 Input Tokens
System prompt + all message history + tool definitions + attached documents. Counted and billed per call.
📤 Output Tokens
Only the AI's response. Billed separately — typically 3–5× more expensive than input tokens.
Context Window — Everything Must Fit
| Model | Context Window | Input Price | Output Price |
|---|---|---|---|
| Claude Sonnet 4 | 200,000 tokens | $3 / 1M tokens | $15 / 1M tokens |
| GPT-4o | 128,000 tokens | $2.50 / 1M tokens | $10 / 1M tokens |
| Gemini 2.0 Flash | 1,000,000 tokens | $0.10 / 1M tokens | $0.40 / 1M tokens |
| Llama 3 (Ollama/vLLM) | 8K–128K tokens | FREE | FREE |
vLLM vs Ollama
Both are model servers — they run AI models locally on your GPU and serve them via API. Same job, different target audience. Think Nginx vs Apache.
Apache
Easy setup
Ollama
Dev friendly
Nginx
Production grade
vLLM
High performance
Ollama
localhost:11434
vLLM
localhost:8000
OpenAI API
api.openai.com
| Feature | Ollama | vLLM |
|---|---|---|
| Setup | 2 commands, done | Multiple steps, GPU config |
| Target | Dev / Learning | Production / Scale |
| Concurrent requests | Limited, queued | Optimized batching |
| GPU utilization | Basic | Maximum (paged attention) |
| Multi-model | Swaps in/out | True parallel, multiple ports |
| Model format | GGUF (quantized) | Full precision or quantized |
| Docker feel | ollama pull / run / list | Manual, more control |
| API keys needed | None | None |
| Cost | Free | Free (your hardware) |
| GB10 recommendation | Dev & demos | Production workloads |
curl -fsSL https://ollama.com/install.sh | sh
ollama pull llama3
ollama run llama3 # API ready at localhost:11434
pip install vllm
vllm serve meta-llama/Llama-3-8B-Instruct --port 8000 # API ready at localhost:8000
LiteLLM
A client-side Python library that translates between all AI provider APIs. You write code once in OpenAI format — LiteLLM routes to any provider. It does NOT run models itself.
✅ What LiteLLM Does
Translates API formats between providers. Manages API keys per provider. Handles retries and fallbacks. Tracks token usage and cost. Routes to cheapest/fastest model.
❌ What LiteLLM Does NOT Do
Does not run any model itself. Does not host anything. Does not replace actual AI providers. It is just a library in your code — nothing to deploy.
# Same code — just change the model string
litellm.completion(model="claude-sonnet-4-20250514", messages=msgs) # → Anthropic
litellm.completion(model="gpt-4o", messages=msgs) # → OpenAI
litellm.completion(model="gemini/gemini-2.0-flash", messages=msgs) # → Google
litellm.completion(model="ollama/llama3", messages=msgs) # → Local GB10
Running Multiple Models
Just like Docker — you run multiple containers on different ports. Your GB10 with 128GB unified memory can run 4–6 models simultaneously with no swapping.
🐳 Docker vs Model Servers
docker pull nginx = ollama pull llama3
docker run -p 8001 = vllm serve --port 8001
docker ps = ollama list
docker stats = nvidia-smi
docker-compose = multiple vLLM instances
🖥️ Your GB10 Memory Budget
llama3 8B = ~8GB
mistral 7B = ~8GB
qwen2.5 7B = ~8GB
codellama 7B = ~8GB
─────────────────────
Total used = 32GB
Remaining = 96GB free ✅
vllm serve meta-llama/Llama-3-8B-Instruct --port 8001
# Terminal 2 — coding tasks
vllm serve mistralai/Mistral-7B-Instruct --port 8002
# Terminal 3 — multilingual (Bahasa friendly)
vllm serve Qwen/Qwen2.5-7B-Instruct --port 8003
Model-Agnostic Architecture
Build your app so the model is a pluggable component. Your tools, prompts, and business logic stay fixed. Only one string changes when you swap providers.
Your Application
MCP Client + Business Logic
LiteLLM Router
Unified interface
Claude
Anthropic API
GPT-4o
OpenAI API
Llama3
Local GB10
Mistral
Mistral API
📧 Gmail
Pre-built MCP
🗄️ Warehouse
Custom MCP
👁️ YOLO
Custom MCP
📹 Cameras
Custom MCP
ACTIVE_MODEL = "ollama/llama3"
# Production — paid cloud
ACTIVE_MODEL = "claude-sonnet-4-20250514"
# Everything else stays identical ↓
response = litellm.completion(
model=ACTIVE_MODEL, # ← only this changes
tools=your_mcp_tools, # ← stays the same
messages=history # ← stays the same
)
API Keys Management
You only set up keys for models you actually use. Never hardcode credentials in code. Store in environment variables locally, Kubernetes Secrets in production.
🖥️ Local Dev
.env file
ANTHROPIC_API_KEY=sk-ant-xxx
OPENAI_API_KEY=sk-xxx
# Ollama = no key needed
☸️ Production
K8s Secret
metadata:
name: ai-credentials
stringData:
anthropic_key: "xxx"
🔐 OAuth
Best practice
You → OAuth → Google
Google → Token → You
# Password never exposed
# Token revocable anytime
❌ Never hardcode keys in source code · ❌ Never commit .env to Git
✅ Environment variables for local · ✅ K8s Secrets for production · ✅ OAuth where possible
Claude.ai vs Claude Code
Two different tools for two different jobs. Claude.ai is for thinking and planning. Claude Code runs on your machine and can actually touch your systems.
💬 Claude.ai (this conversation)
Runs in the browser. No access to your local machine or network. Good for learning, planning, writing code and configs.
✅ Search the web
✅ Plan architecture
✅ Explain concepts
❌ Cannot SSH to GB10
❌ Cannot run commands
❌ Cannot access 192.168.x.x
⌨️ Claude Code (terminal tool)
Runs inside your terminal on your machine. Has access to your filesystem, local network, and can execute commands.
✅ Run vLLM / Ollama commands
✅ Edit files directly
✅ Debug live errors
✅ Access local network
✅ Deploy to Kubernetes
npm install -g @anthropic-ai/claude-code
What is MCP
Model Context Protocol — an open standard that defines how AI models connect to external tools and data sources. Started by Anthropic in Nov 2024. Now governed by the Linux Foundation with backing from OpenAI, Google, and Microsoft.
🔌 MCP is a Protocol
An agreed set of rules for how two parties communicate — just like HTTP, SMTP, HDMI, or USB. MCP defines how AI models talk to tools.
SMTP → Email ↔ Email Server
HDMI → Display ↔ Device
MCP → AI Model ↔ Tools/Data
🏛️ Standardization
MCP started at Anthropic, then the whole industry joined. Now it belongs to nobody — and everybody.
Mar 2025 OpenAI adopts MCP
May 2025 Microsoft + GitHub join
Dec 2025 Donated to Linux Foundation
→ Neutral, vendor-independent
🔑 The Key Insight — Two Separate Problems
Layer 1 — Calling the AI
Each vendor has own API format. NOT standardized. Claude=/v1/messages, OpenAI=/v1/chat/completions
Layer 2 — Connecting Tools
THIS is standardized by MCP. Any AI discovers and calls Gmail, Postgres, cameras — same protocol regardless of AI model.
MCP Server
The MCP Server does all the dirty work — just like Nginx serves HTTP. Claude speaks MCP. The MCP Server translates that into whatever the actual service needs (Gmail API, Postgres queries, RTSP streams).
Browser
HTTP Client
Nginx / Apache
HTTP Server — dirty work
Your App / DB
Actual service
Claude
MCP Client
MCP Server
MCP Server — dirty work
Gmail / Postgres / YOLO
Actual service
📋 Wire Format
JSON-RPC 2.0 over transport layer. Every message is a structured JSON envelope with a defined schema.
🚌 Transports
STDIO — local process, Claude spawns it. Simple, good for local/lab use.
HTTP/SSE — runs as web server. Better for production and Kubernetes.
🔍 Discovery
Claude asks the MCP server "what tools do you have?" on connection. The server lists all available tools, resources, and prompts automatically.
Tools, Resources & Prompts
An MCP Server can expose three types of capabilities. Tools are the most common — they let the AI execute actions and query data.
⚙️ Tools
Functions the AI can call — execute actions, query data, trigger events. Most commonly used.
def query_stock(sku: str):
"""Get stock level for SKU"""
# hit your Postgres
return result
📂 Resources
Data the AI can read — files, feeds, live records, camera streams.
"camera://{cam_id}")
def get_feed(cam_id: str):
"""Get RTSP stream info"""
return rtsp_info
💬 Prompts
Reusable prompt templates the AI can load for specific tasks.
def defect_report(sku):
"""Analysis template"""
return f"Analyse defects
for {sku} last 7d"
🏭 Your Manufacturing Stack as MCP Tools
@mcp.tool() def get_defect_rate(line_id: str) → float: """Get YOLO defect rate for line"""
@mcp.tool() def get_camera_status(cam_id: str) → str: """Check RTSP feed health"""
# Now any AI model can call all of this just by talking naturally
Who Hosts What
Only self-host when the data is private to you. Pre-built MCP servers exist for most common cloud services — install and configure, no coding needed.
☁️ You DON'T Host
Vendor hosts the MCP server. You just connect and authenticate.
🏭 You DO Host (Your Lab)
Your private data lives inside your network. You write and host the MCP server.
Connecting to MCP
Three ways to connect — depends on where you're running Claude. The pattern is always the same: get the server, give it credentials, point your client at it.
Claude.ai — Zero Code
Settings → Connectors → Gmail → Connect → OAuth with Google. Anthropic hosts the MCP server. You never touch credentials.
Claude Desktop — Local Config
Install MCP server via npm, edit claude_desktop_config.json with credentials, restart.
"gmail": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-gmail"],
"env": { "GMAIL_CLIENT_ID": "xxx" }
} }}
Your Own App — Full Control
Your app acts as the MCP client. Point it to MCP server endpoints. Route tool calls through the AI API programmatically. Model agnostic.
MCP Credentials
Where you store credentials depends on where your MCP server runs. The golden rule never changes — never in code, always in environment.
🖥️ Local Dev
.env file
GMAIL_CLIENT_ID=xxx
GMAIL_CLIENT_SECRET=xxx
GMAIL_REFRESH_TOKEN=xxx
☸️ Production
K8s Secret
metadata:
name: gmail-credentials
stringData:
client_id: "xxx"
🔐 OAuth
Best practice
Google → Token → You
# Password never exposed
# Token revocable anytime
✅ Environment variables for local · ✅ K8s Secrets for production · ✅ OAuth where possible
Writing MCP Servers
You only write a custom MCP server for things that are unique to you. Pre-built servers already exist for Gmail, Drive, GitHub, Slack, Postgres. Use pip/npm to install those. Write only what nobody else has.
📦 Pre-built — Just Install
npm install @modelcontextprotocol/server-gmail
npm install @modelcontextprotocol/server-gdrive
npm install @modelcontextprotocol/server-github
# Then just configure credentials
✏️ Custom — You Write This
# Your YOLO inference engine
# Your RTSP camera feeds
# Your custom business logic
# Step 1 — Create the server
mcp = FastMCP("WarehouseServer")
# Step 2 — Decorate your functions as tools
@mcp.tool()
def query_stock(sku: str) → dict:
"""Query warehouse stock by SKU. Returns units, bay, last updated."""
# your Postgres query here
return {"units": 450, "bay": "Bay-3"}
# Step 3 — Run it
mcp.run() # listening for MCP connections
| Language | SDK | Install |
|---|---|---|
| Python | mcp + FastMCP | pip install mcp |
| TypeScript/JS | @modelcontextprotocol/sdk | npm install @modelcontextprotocol/sdk |
| Java/Kotlin | Official MCP SDK | Maven / Gradle |
| C# (.NET) | Microsoft.McpServer | NuGet |
MCP & Token Cost
Every tool definition in your MCP server gets sent as part of the input on every API call — even if the tool is never used. This is important to manage at scale.
Every API Call Carries ALL Tool Definitions
Even if Claude answers "What is 2+2?" — it still reads all your Gmail, Warehouse, YOLO, and Camera tool definitions first. You paid for those tokens.
20 MCP tool defs ~4,000 tokens ← always loaded
Conversation history ~2,000 tokens
User message ~50 tokens
─────────────────────────────────
Total input ~6,550 tokens per call
At 1,000 calls/day ≈ $0.027/day ≈ $0.81/month ← cheap
At 1M calls/day ≈ $27/day ← worth optimising
🎯 Strategy 1
Load selectively
if task == "inventory":
tools = [warehouse, sku]
elif task == "email":
tools = [gmail, calendar]
✂️ Strategy 2
Short descriptions
"""Query the warehouse mgmt
system to retrieve current
stock, history, defects..."""
# Good — concise, ~30 tokens
"""Get stock, bay, defects."""
🔗 Strategy 3
Group related tools
get_stock(sku)
get_bay(sku)
get_defects(sku)
# 1 tool = 1× token cost
query_sku(sku, fields=[...])