cgfixit

https://sider.ai/share/d11cf2c90f07a03f9514d33af688eb80 (Option D Hybrid Ideally)

Jan 1st, 2026
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
CSS 13.86 KB | Software | 0 0
  1.  
  2. # Offline MCP Multi-Model Project
  3. ## Primary Source Reference Document
  4. **Version**: 1.0 | **Date**: December 2024 | **Author**: CG
  5.  
  6. ---
  7.  
  8. ## Project Vision
  9.  
  10. Build an offline-first AI assistant using:
  11. - **RAG database**: Curated `.md` files with vector embeddings
  12. - **Local LLM**: Ollama running open-source models
  13. - **MCP Protocol**: Standardized client-host-server communication
  14. - **Optional Online**: Multi-model routing via Groq/OpenRouter when enabled
  15.  
  16. ---
  17.  
  18. ## Core Architecture
  19.  
  20. ```
  21. ┌─────────────────────────────────────────────────────────────────────────┐
  22. │                         HOST (Orchestrator)                              │
  23. │   - LangChain or custom Python                                          │
  24. │   - RAG retrieval from .md corpus                                       │
  25. │   - Routing logic (offline vs online, simple vs complex)                │
  26. │   - Security: sanitize context before sending to cloud                  │
  27. ├─────────────────────────────────────────────────────────────────────────┤
  28. │                                                                          │
  29. │   ┌──────────────────┐  ┌──────────────────┐  ┌──────────────────┐      │
  30. │   │  MCP CLIENT 1    │  │  MCP CLIENT 2    │  │  MCP CLIENT 3    │      │
  31. │   │  (Ollama)        │  │  (Groq)          │  │  (OpenRouter)    │      │
  32. │   │  Transport:stdio │  │  Transport:HTTP  │  │  Transport:HTTP  │      │
  33. │   └────────┬─────────┘  └────────┬─────────┘  └────────┬─────────┘      │
  34. │            │                     │                     │                 │
  35. │   ┌────────▼─────────┐  ┌────────▼─────────┐  ┌────────▼─────────┐      │
  36. │   │  MCP SERVER 1    │  │  MCP SERVER 2    │  │  MCP SERVER 3    │      │
  37. │   │  Ollama Wrapper  │  │  Groq API        │  │  Claude/Grok     │      │
  38. │   │  (Local)         │  │  (Cloud)         │  │  (Cloud)         │      │
  39. │   └──────────────────┘  └──────────────────┘  └──────────────────┘      │
  40. │                                                                          │
  41. └─────────────────────────────────────────────────────────────────────────┘
  42. ```
  43.  
  44. ---
  45.  
  46. ## MCP Protocol Fundamentals
  47.  
  48. ### Source: modelcontextprotocol.io/specification/2025-11-25
  49.  
  50. **Core Principles**:
  51. 1. JSON-RPC 2.0 message format over any transport
  52. 2. Stateful sessions with capability negotiation
  53. 3. Host controls security; servers are isolated
  54. 4. Servers cannot see full conversation or other servers
  55.  
  56. ### Transport Options
  57.  
  58. | Transport | Use Case | Key Requirements |
  59. |-----------|----------|------------------|
  60. | **stdio** | Local/offline | Newline-delimited JSON, no embedded newlines, stderr for logs |
  61. | **Streamable HTTP** | Cloud/remote | Single endpoint, SSE for streaming, session management via headers |
  62.  
  63. ### stdio Transport Rules (MUST follow)
  64. ```
  65. - Messages: Single-line JSON-RPC, terminated by \n
  66. - stdout: ONLY valid MCP messages
  67. - stderr: Logging/debug output
  68. - Client spawns server as subprocess
  69. ```
  70.  
  71. ### Capability Negotiation
  72. ```json
  73. // Client → Server
  74. {
  75.   "jsonrpc": "2.0",
  76.   "id": 1,
  77.   "method": "initialize",
  78.   "params": {
  79.     "protocolVersion": "2025-11-25",
  80.     "capabilities": {"sampling": {}},
  81.     "clientInfo": {"name": "my-host", "version": "1.0"}
  82.   }
  83. }
  84.  
  85. // Server → Client
  86. {
  87.   "jsonrpc": "2.0",
  88.   "id": 1,
  89.   "result": {
  90.     "protocolVersion": "2025-11-25",
  91.     "capabilities": {"tools": {}, "resources": {"subscribe": true}},
  92.     "serverInfo": {"name": "ollama-mcp", "version": "1.0"}
  93.   }
  94. }
  95. ```
  96.  
  97. ---
  98.  
  99. ## Ollama MCP Wrapper Implementation
  100.  
  101. ### Why Needed
  102. Ollama exposes REST API at `http://localhost:11434`, not MCP JSON-RPC over stdio.
  103. Wrapper translates between protocols.
  104.  
  105. ### Minimal Implementation
  106. ```python
  107. # ollama_mcp_server.py
  108. import sys
  109. import json
  110. import requests
  111.  
  112. OLLAMA_URL = "http://localhost:11434"
  113. DEFAULT_MODEL = "llama3.2"
  114.  
  115. def handle_message(msg: dict) -> dict:
  116.     method = msg.get("method")
  117.     msg_id = msg.get("id")
  118.    
  119.     if method == "initialize":
  120.         return {
  121.             "jsonrpc": "2.0",
  122.             "id": msg_id,
  123.             "result": {
  124.                 "protocolVersion": "2025-11-25",
  125.                 "capabilities": {"tools": {}, "sampling": {}},
  126.                 "serverInfo": {"name": "ollama-mcp", "version": "1.0"}
  127.             }
  128.         }
  129.    
  130.     elif method == "sampling/createMessage":
  131.         # Extract prompt from MCP params
  132.         messages = msg.get("params", {}).get("messages", [])
  133.         prompt = "\n".join([m.get("content", "") for m in messages])
  134.        
  135.         # Call Ollama REST API
  136.         response = requests.post(
  137.             f"{OLLAMA_URL}/api/generate",
  138.             json={"model": DEFAULT_MODEL, "prompt": prompt, "stream": False}
  139.         )
  140.         result = response.json()
  141.        
  142.         return {
  143.             "jsonrpc": "2.0",
  144.             "id": msg_id,
  145.             "result": {
  146.                 "content": {"type": "text", "text": result.get("response", "")},
  147.                 "model": DEFAULT_MODEL,
  148.                 "stopReason": "endTurn"
  149.             }
  150.         }
  151.    
  152.     else:
  153.         return {
  154.             "jsonrpc": "2.0",
  155.             "id": msg_id,
  156.             "error": {"code": -32601, "message": f"Method not found: {method}"}
  157.         }
  158.  
  159. # Main stdio loop
  160. for line in sys.stdin:
  161.     try:
  162.         msg = json.loads(line.strip())
  163.         response = handle_message(msg)
  164.         sys.stdout.write(json.dumps(response) + "\n")
  165.         sys.stdout.flush()
  166.     except Exception as e:
  167.         sys.stderr.write(f"Error: {e}\n")
  168. ```
  169.  
  170. ### Config for MCP Client (e.g., Claude Desktop, Dive)
  171. ```json
  172. {
  173.   "mcpServers": {
  174.     "ollama-local": {
  175.       "command": "python",
  176.       "args": ["/path/to/ollama_mcp_server.py"]
  177.     }
  178.   }
  179. }
  180. ```
  181.  
  182. ---
  183.  
  184. ## LangChain Integration (Current API - Dec 2024)
  185.  
  186. ### Source: python.langchain.com
  187.  
  188. **Note**: API has evolved. Old `RouterChain` deprecated. Current pattern:
  189.  
  190. ```python
  191. # Install: pip install langchain langchain-ollama langchain-openai
  192.  
  193. from langchain_ollama import ChatOllama
  194. from langchain_openai import ChatOpenAI
  195. from langchain.agents import create_agent
  196.  
  197. # Local model (offline)
  198. local_llm = ChatOllama(model="llama3.2", base_url="http://localhost:11434")
  199.  
  200. # Cloud model via OpenRouter (online)
  201. cloud_llm = ChatOpenAI(
  202.     base_url="https://openrouter.ai/api/v1",
  203.     api_key="sk-or-...",
  204.     model="x-ai/grok-beta"
  205. )
  206.  
  207. # Simple routing function
  208. def route_query(query: str, offline_mode: bool = False):
  209.     if offline_mode:
  210.         return local_llm.invoke(query)
  211.    
  212.     # Complexity-based routing
  213.     if len(query) < 200:
  214.         return local_llm.invoke(query)  # Simple → local
  215.     else:
  216.         return cloud_llm.invoke(query)  # Complex → cloud
  217. ```
  218.  
  219. ### Agent Pattern (Current)
  220. ```python
  221. from langchain.agents import create_agent
  222.  
  223. def search_docs(query: str) -> str:
  224.     """Search local .md documentation"""
  225.     # RAG retrieval logic here
  226.     return "Retrieved context..."
  227.  
  228. agent = create_agent(
  229.     model="llama3.2",  # or cloud model
  230.     tools=[search_docs],
  231.     system_prompt="You are a helpful IT assistant with access to documentation."
  232. )
  233.  
  234. result = agent.invoke({"messages": [{"role": "user", "content": "How do I configure backups?"}]})
  235. ```
  236.  
  237. ---
  238.  
  239. ## RAG with .md Files
  240.  
  241. ### Vector Store Options (Local)
  242.  
  243. | Store | Pros | Cons |
  244. |-------|------|------|
  245. | **Chroma** | Easy setup, persistent | Moderate performance |
  246. | **FAISS** | Fast, Facebook-backed | More setup |
  247. | **LanceDB** | Serverless, efficient | Newer, less docs |
  248.  
  249. ### Basic RAG Pipeline
  250. ```python
  251. from langchain_community.document_loaders import DirectoryLoader, TextLoader
  252. from langchain_text_splitters import MarkdownHeaderTextSplitter
  253. from langchain_community.vectorstores import Chroma
  254. from langchain_ollama import OllamaEmbeddings
  255.  
  256. # 1. Load .md files
  257. loader = DirectoryLoader("./docs", glob="**/*.md", loader_cls=TextLoader)
  258. docs = loader.load()
  259.  
  260. # 2. Split by headers (preserves structure)
  261. splitter = MarkdownHeaderTextSplitter(
  262.     headers_to_split_on=[("#", "h1"), ("##", "h2"), ("###", "h3")]
  263. )
  264. chunks = []
  265. for doc in docs:
  266.     chunks.extend(splitter.split_text(doc.page_content))
  267.  
  268. # 3. Embed locally
  269. embeddings = OllamaEmbeddings(model="nomic-embed-text")
  270.  
  271. # 4. Store in Chroma
  272. vectorstore = Chroma.from_documents(chunks, embeddings, persist_directory="./chroma_db")
  273.  
  274. # 5. Query
  275. retriever = vectorstore.as_retriever(search_kwargs={"k": 5})
  276. relevant_docs = retriever.invoke("backup configuration")
  277. ```
  278.  
  279. ---
  280.  
  281. ## OpenRouter Integration
  282.  
  283. ### Source: openrouter.ai/docs
  284.  
  285. **Key Features**:
  286. - Unified API for 100+ models
  287. - OpenAI-compatible format
  288. - Automatic prompt caching (Grok, OpenAI, Gemini)
  289. - Token usage tracking
  290.  
  291. ### Prompt Caching (Verified)
  292.  
  293. | Provider | Cache Write Cost | Cache Read Cost |
  294. |----------|------------------|-----------------|
  295. | Grok | Free | 0.25x input price |
  296. | OpenAI | Free | 0.25-0.50x input price |
  297. | Claude | 1.25x input price | 0.10x input price |
  298. | Gemini | Free + 5min storage | 0.25x input price |
  299.  
  300. ### Usage Example
  301. ```python
  302. import openai
  303.  
  304. client = openai.OpenAI(
  305.     base_url="https://openrouter.ai/api/v1",
  306.     api_key="sk-or-..."
  307. )
  308.  
  309. response = client.chat.completions.create(
  310.     model="x-ai/grok-beta",  # or "anthropic/claude-3-haiku"
  311.     messages=[{"role": "user", "content": "Your query"}]
  312. )
  313. ```
  314.  
  315. ---
  316.  
  317. ## xAI Grok Pricing & Tiers
  318.  
  319. ### Subscription Tiers (as of Dec 2024)
  320. | Tier | Price | Includes |
  321. |------|-------|----------|
  322. | Free | $0 | Limited Grok 3 access on X |
  323. | SuperGrok | $30/mo | Expanded Grok 3, some Grok 4 |
  324. | SuperGrok Heavy | $300/mo | Full Grok 4 Heavy access |
  325.  
  326. **⚠️ Subscriptions ≠ API access**. API requires separate xAI developer account.
  327.  
  328. ### API Pricing
  329. | Model | Input | Output |
  330. |-------|-------|--------|
  331. | grok-4-fast | $0.20/M | $0.50/M |
  332. | grok-4 | $3/M | $15/M |
  333. | grok-4-heavy | Higher | Higher |
  334.  
  335. ---
  336.  
  337. ## LoRAX Alternative (Advanced)
  338.  
  339. ### Source: github.com/predibase/lorax
  340.  
  341. **What it is**: Multi-LoRA inference server. Serves thousands of fine-tuned adapters from single GPU.
  342.  
  343. **When relevant**: If you fine-tune multiple LoRA adapters on different subsets of your .md corpus (e.g., networking docs, security docs, Veeam docs), LoRAX lets you dynamically load the right adapter per query.
  344.  
  345. **Trade-off**: Higher complexity than RAG-only approach. Only justified if fine-tuning provides measurably better results than prompt injection.
  346.  
  347. ---
  348.  
  349. ## Learning Path
  350.  
  351. ### Phase 1: Foundations (Current)
  352. 1. ✅ MCP Protocol (Architecture, Transports)
  353. 2. → **LangChain** (agents, chains, RAG)
  354. 3. → Ollama local setup
  355.  
  356. ### Phase 2: Implementation
  357. 4. Build Ollama MCP wrapper
  358. 5. Implement RAG pipeline with .md files
  359. 6. Test offline-only mode
  360.  
  361. ### Phase 3: Hybrid
  362. 7. Add OpenRouter/Groq for online fallback
  363. 8. Implement routing logic
  364. 9. Add caching layer
  365.  
  366. ### Phase 4: Advanced (Optional)
  367. 10. Fine-tune LoRA adapters (if RAG insufficient)
  368. 11. LoRAX for multi-adapter serving
  369. 12. PyTorch fundamentals (for custom model work)
  370.  
  371. ---
  372.  
  373. ## Key Resources
  374.  
  375. ### Official Documentation
  376. | Resource | URL | Notes |
  377. |----------|-----|-------|
  378. | MCP Spec | modelcontextprotocol.io/specification/2025-11-25 | Authoritative protocol reference |
  379. | LangChain | python.langchain.com/docs | Current API docs |
  380. | Ollama | github.com/ollama/ollama | API reference in /docs |
  381. | OpenRouter | openrouter.ai/docs | Pricing, caching, routing |
  382. | LoRAX | github.com/predibase/lorax | Multi-LoRA serving |
  383. | Hugging Face | huggingface.co | Models, PEFT, Transformers |
  384.  
  385. ### Tutorials & Guides
  386. | Topic | Source | Status |
  387. |-------|--------|--------|
  388. | Local MCP Server | stainless.com/mcp/local-mcp-server | ✅ Fetched |
  389. | MCP + Ollama | Medium (kpetropavlov) | ✅ Fetched |
  390. | MCP Tool Use + Ollama | Medium (Renaissance Learning) | ✅ Fetched |
  391. | IBM RAG with .md | developer.ibm.com | ❌ 404 (find alternative) |
  392. | Improved RAG with Markdown | Medium (Data Science) | Not fetched |
  393.  
  394. ### Community
  395. | Topic | Source |
  396. |-------|--------|
  397. | MCP Servers | github.com/modelcontextprotocol (official repos) |
  398. | Ollama Discord | discord.gg/ollama |
  399. | LangChain Discord | discord.gg/langchain |
  400.  
  401. ---
  402.  
  403. ## Grok Voice Agent API (Future Integration)
  404.  
  405. ### Source: x.ai/news/grok-voice-agent-api (blocked during fetch)
  406.  
  407. **Announced capabilities** (from your quote):
  408. > "With our API, developers can effortlessly integrate their own custom tools or tap into xAI's powerful real-time search capabilities across X and the web."
  409.  
  410. **Potential project integration**:
  411. - Voice interface for your RAG assistant
  412. - Real-time X/web search as fallback when local docs insufficient
  413. - Custom tool registration (similar to MCP tools concept)
  414.  
  415. **Action item**: Monitor xAI developer portal for API availability.
  416.  
  417. ---
  418.  
  419. ## Version History
  420.  
  421. | Version | Date | Changes |
  422. |---------|------|---------|
  423. | 1.0 | 2024-12-20 | Initial reference document |
  424.  
  425.  
Tags: mcp
Advertisement
Add Comment
Please, Sign In to add comment