├── cli
├── __init__.py
└── commands.py
├── core
├── __init__.py
└── calendar.py
├── rag
├── __init__.py
└── embeddings.py
├── scraper
└── __init__.py
├── data_analysis
└── __init__.py
├── api
└── __init__.py
├── mcp_gateway
├── __init__.py
├── claude_config.json
├── test_server.py
├── client_config.json
└── README.md
├── app
├── favicon.ico
├── globals.css
├── layout.tsx
├── JRVS APP.tsx
└── components
│ └── AISchedulingPlatform.tsx
├── data
├── jarvis.db
├── faiss_index.map
└── faiss_index.index
├── __init__.py
├── postcss.config.mjs
├── public
├── vercel.svg
├── window.svg
├── file.svg
├── globe.svg
└── next.svg
├── next.config.ts
├── llm
└── __init__.py
├── .dockerignore
├── .claude
└── settings.local.json
├── requirements.txt
├── jrvs-web.service
├── eslint.config.mjs
├── docker-compose.yml
├── Dockerfile
├── start-api.sh
├── start_jrvs.sh
├── package.json
├── tsconfig.json
├── issues
└── 1.md
├── start_web_server.sh
├── .gitignore
├── mcp
├── config.json
├── shutdown.py
├── logging_config.py
└── exceptions.py
├── push_to_github.sh
├── add_event.py
├── docs
├── START_HERE.md
├── TAILSCALE_QUICKSTART.md
├── COMMANDS_FIXED.md
├── WHATS_NEW.md
├── JARCORE_QUICKSTART.md
├── MCP_QUICKSTART.md
├── BRAVE_SEARCH_SETUP.md
├── MCP_CLIENT_GUIDE.md
├── SETUP_COMPLETE.md
├── README_FRONTEND.md
├── QUICKSTART.md
├── NEW_WEB_UI.md
├── SECURITY_HARDENING_SUMMARY.md
└── JARCORE_UPDATE.md
├── tests
├── test_mcp_client.py
├── test_coding_agent.py
├── test_calendar_api.py
└── test_lmstudio_client.py
├── Dockerfile.mcp
├── scripts
└── start_mcp_enhanced.sh
├── lib
├── firebase.ts
├── firebase-utils.ts
└── jarvis-api.ts
├── config.py
├── docker-compose.mcp.yml
├── setup_windows.bat
├── ENTERPRISE.md
└── setup_mac.sh
/cli/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/core/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/rag/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/scraper/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/data_analysis/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/api/__init__.py:
--------------------------------------------------------------------------------
1 | """API module for Jarvis AI Agent"""
2 |
--------------------------------------------------------------------------------
/mcp_gateway/__init__.py:
--------------------------------------------------------------------------------
1 | """MCP (Model Context Protocol) server for JRVS"""
2 |
--------------------------------------------------------------------------------
/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Xthebuilder/JRVS/HEAD/app/favicon.ico
--------------------------------------------------------------------------------
/data/jarvis.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Xthebuilder/JRVS/HEAD/data/jarvis.db
--------------------------------------------------------------------------------
/data/faiss_index.map:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Xthebuilder/JRVS/HEAD/data/faiss_index.map
--------------------------------------------------------------------------------
/__init__.py:
--------------------------------------------------------------------------------
1 | """Jarvis AI Agent - Advanced RAG-powered CLI assistant"""
2 | __version__ = "1.0.0"
--------------------------------------------------------------------------------
/data/faiss_index.index:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Xthebuilder/JRVS/HEAD/data/faiss_index.index
--------------------------------------------------------------------------------
/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | const config = {
2 | plugins: {
3 | "@tailwindcss/postcss": {},
4 | },
5 | };
6 |
7 | export default config;
8 |
--------------------------------------------------------------------------------
/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/next.config.ts:
--------------------------------------------------------------------------------
1 | import type { NextConfig } from "next";
2 |
3 | const nextConfig: NextConfig = {
4 | /* config options here */
5 | };
6 |
7 | export default nextConfig;
8 |
--------------------------------------------------------------------------------
/llm/__init__.py:
--------------------------------------------------------------------------------
1 | from llm.ollama_client import OllamaClient, ollama_client
2 | from llm.lmstudio_client import LMStudioClient, lmstudio_client
3 |
4 | __all__ = ['OllamaClient', 'ollama_client', 'LMStudioClient', 'lmstudio_client']
5 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | __pycache__
2 | *.pyc
3 | *.pyo
4 | *.pyd
5 | .Python
6 | *.so
7 | *.egg
8 | *.egg-info
9 | dist
10 | build
11 | .git
12 | .gitignore
13 | .dockerignore
14 | *.md
15 | data/faiss_index
16 | data/*.db
17 | .venv
18 | venv
19 | ENV
20 |
--------------------------------------------------------------------------------
/mcp_gateway/claude_config.json:
--------------------------------------------------------------------------------
1 | {
2 | "mcpServers": {
3 | "jrvs": {
4 | "command": "python",
5 | "args": [
6 | "/home/xmanz/JRVS/mcp/server.py"
7 | ],
8 | "env": {
9 | "PYTHONPATH": "/home/xmanz/JRVS"
10 | }
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/.claude/settings.local.json:
--------------------------------------------------------------------------------
1 | {
2 | "permissions": {
3 | "allow": [
4 | "Bash(python:*)",
5 | "Bash(curl:*)",
6 | "Bash(cat:*)",
7 | "Bash(pip install:*)",
8 | "Bash(timeout:*)",
9 | "Bash(tree:*)",
10 | "Bash(python3:*)",
11 | "Bash(tailscale:*)",
12 | "Bash(chmod:*)"
13 | ],
14 | "deny": [],
15 | "ask": []
16 | }
17 | }
--------------------------------------------------------------------------------
/public/window.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/file.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | rich>=13.0.0
2 | requests>=2.28.0
3 | beautifulsoup4>=4.11.0
4 | faiss-cpu>=1.7.0
5 | sentence-transformers>=2.2.0
6 | aiohttp>=3.8.0
7 | aiosqlite>=0.19.0
8 | numpy>=1.24.0
9 | torch>=2.0.0
10 | transformers>=4.30.0
11 | psutil>=5.9.0
12 | fastapi>=0.104.0
13 | uvicorn>=0.24.0
14 | pydantic>=2.0.0
15 | websockets>=12.0
16 | mcp>=1.2.0
17 | httpx>=0.25.0
18 | anyio>=4.0.0
19 | slowapi>=0.1.9
--------------------------------------------------------------------------------
/jrvs-web.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=JRVS AI Agent Web Server (Tailscale Only)
3 | After=network.target tailscaled.service
4 | Wants=tailscaled.service
5 |
6 | [Service]
7 | Type=simple
8 | User=xmanz
9 | WorkingDirectory=/home/xmanz/JRVS
10 | Environment="PATH=/usr/bin:/usr/local/bin"
11 | ExecStart=/usr/bin/python3 /home/xmanz/JRVS/web_server.py
12 | Restart=on-failure
13 | RestartSec=10
14 |
15 | # Security
16 | PrivateTmp=yes
17 | NoNewPrivileges=true
18 |
19 | [Install]
20 | WantedBy=multi-user.target
21 |
--------------------------------------------------------------------------------
/eslint.config.mjs:
--------------------------------------------------------------------------------
1 | import { defineConfig, globalIgnores } from "eslint/config";
2 | import nextVitals from "eslint-config-next/core-web-vitals";
3 | import nextTs from "eslint-config-next/typescript";
4 |
5 | const eslintConfig = defineConfig([
6 | ...nextVitals,
7 | ...nextTs,
8 | // Override default ignores of eslint-config-next.
9 | globalIgnores([
10 | // Default ignores of eslint-config-next:
11 | ".next/**",
12 | "out/**",
13 | "build/**",
14 | "next-env.d.ts",
15 | ]),
16 | ]);
17 |
18 | export default eslintConfig;
19 |
--------------------------------------------------------------------------------
/app/globals.css:
--------------------------------------------------------------------------------
1 | @import "tailwindcss";
2 |
3 | :root {
4 | --background: #ffffff;
5 | --foreground: #171717;
6 | }
7 |
8 | @theme inline {
9 | --color-background: var(--background);
10 | --color-foreground: var(--foreground);
11 | --font-sans: var(--font-geist-sans);
12 | --font-mono: var(--font-geist-mono);
13 | }
14 |
15 | @media (prefers-color-scheme: dark) {
16 | :root {
17 | --background: #0a0a0a;
18 | --foreground: #ededed;
19 | }
20 | }
21 |
22 | body {
23 | background: var(--background);
24 | color: var(--foreground);
25 | font-family: Arial, Helvetica, sans-serif;
26 | }
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.8'
2 |
3 | services:
4 | jarvis:
5 | build: .
6 | container_name: jarvis_ai_agent
7 | stdin_open: true
8 | tty: true
9 | volumes:
10 | - ./data:/app/data
11 | network_mode: "host"
12 | environment:
13 | - OLLAMA_BASE_URL=http://localhost:11434
14 | depends_on:
15 | - ollama
16 |
17 | ollama:
18 | image: ollama/ollama:latest
19 | container_name: ollama
20 | ports:
21 | - "11434:11434"
22 | volumes:
23 | - ollama_data:/root/.ollama
24 | restart: unless-stopped
25 |
26 | volumes:
27 | ollama_data:
28 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.11-slim
2 |
3 | # Set working directory
4 | WORKDIR /app
5 |
6 | # Install system dependencies
7 | RUN apt-get update && apt-get install -y \
8 | curl \
9 | && rm -rf /var/lib/apt/lists/*
10 |
11 | # Copy requirements first for better caching
12 | COPY requirements.txt .
13 |
14 | # Install Python dependencies
15 | RUN pip install --no-cache-dir -r requirements.txt
16 |
17 | # Copy application code
18 | COPY . .
19 |
20 | # Create data directory
21 | RUN mkdir -p /app/data
22 |
23 | # Set environment variables
24 | ENV PYTHONUNBUFFERED=1
25 |
26 | # Run the application
27 | CMD ["python", "main.py"]
28 |
--------------------------------------------------------------------------------
/start-api.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Start Jarvis API Server
3 |
4 | echo "🚀 Starting Jarvis API Server..."
5 | cd "$(dirname "$0")"
6 |
7 | # Check if Ollama is running
8 | if ! curl -s http://localhost:11434/api/tags > /dev/null 2>&1; then
9 | echo "❌ Ollama is not running!"
10 | echo "Start it with: ollama serve"
11 | exit 1
12 | fi
13 |
14 | # Install dependencies if needed
15 | if ! python -c "import fastapi" 2>/dev/null; then
16 | echo "📦 Installing API dependencies..."
17 | pip install fastapi uvicorn websockets pydantic
18 | fi
19 |
20 | # Start the API server
21 | echo "✅ Starting API on http://localhost:8000"
22 | python api/server.py
23 |
--------------------------------------------------------------------------------
/start_jrvs.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Quick start script for JRVS
3 |
4 | echo "🤖 Starting JRVS AI Agent..."
5 | echo ""
6 |
7 | # Check Ollama
8 | if ! systemctl is-active --quiet ollama && ! pgrep -f "ollama serve" > /dev/null; then
9 | echo "⚠️ Warning: Ollama doesn't appear to be running"
10 | echo " Start it with: ollama serve"
11 | echo ""
12 | fi
13 |
14 | # Check Node.js for MCP servers
15 | if ! command -v node &> /dev/null; then
16 | echo "⚠️ Warning: Node.js not found - MCP servers won't work"
17 | echo " Install from: https://nodejs.org/"
18 | echo ""
19 | fi
20 |
21 | # Start JRVS
22 | cd "$(dirname "$0")"
23 | python main.py "$@"
24 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jrvs",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "eslint"
10 | },
11 | "dependencies": {
12 | "firebase": "^12.5.0",
13 | "lucide-react": "^0.553.0",
14 | "next": "16.0.1",
15 | "react": "^19.2.0",
16 | "react-dom": "19.2.0"
17 | },
18 | "devDependencies": {
19 | "@tailwindcss/postcss": "^4",
20 | "@types/node": "^20",
21 | "@types/react": "^19",
22 | "@types/react-dom": "^19",
23 | "eslint": "^9",
24 | "eslint-config-next": "16.0.1",
25 | "tailwindcss": "^4",
26 | "typescript": "^5"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2017",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "noEmit": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "bundler",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "react-jsx",
15 | "incremental": true,
16 | "plugins": [
17 | {
18 | "name": "next"
19 | }
20 | ],
21 | "paths": {
22 | "@/*": ["./*"]
23 | }
24 | },
25 | "include": [
26 | "next-env.d.ts",
27 | "**/*.ts",
28 | "**/*.tsx",
29 | ".next/types/**/*.ts",
30 | ".next/dev/types/**/*.ts",
31 | "**/*.mts"
32 | ],
33 | "exclude": ["node_modules"]
34 | }
35 |
--------------------------------------------------------------------------------
/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from "next";
2 | import { Geist, Geist_Mono } from "next/font/google";
3 | import "./globals.css";
4 |
5 | const geistSans = Geist({
6 | variable: "--font-geist-sans",
7 | subsets: ["latin"],
8 | });
9 |
10 | const geistMono = Geist_Mono({
11 | variable: "--font-geist-mono",
12 | subsets: ["latin"],
13 | });
14 |
15 | export const metadata: Metadata = {
16 | title: "Create Next App",
17 | description: "Generated by create next app",
18 | };
19 |
20 | export default function RootLayout({
21 | children,
22 | }: Readonly<{
23 | children: React.ReactNode;
24 | }>) {
25 | return (
26 |
27 |
30 | {children}
31 |
32 |
33 | );
34 | }
--------------------------------------------------------------------------------
/issues/1.md:
--------------------------------------------------------------------------------
1 | ### Title
2 | Migrate Tool Calling Protocol to UTCP
3 |
4 | ### Body
5 | The current tool calling implementation relies on the Model Context Protocol (MCP). This issue proposes migrating to the [Universal Tool Calling Protocol (UTCP)](https://github.com/universal-tool-calling-protocol) to enhance interoperability and standardization.
6 |
7 | **Tasks:**
8 | - [ ] Research UTCP specification and integration requirements.
9 | - [ ] Refactor `mcp/agent.py` and `mcp/client.py` to support UTCP.
10 | - [ ] Update configuration schemas in `mcp/client_config.json`.
11 | - [ ] Verify tool discovery and execution with the new protocol.
12 |
13 | ---
14 |
15 | **Note**: File paths updated from `mcp/` to `mcp_gateway/` due to namespace collision resolution. The directory was renamed to avoid conflicts with the pip-installed `mcp` package. Current tasks should reference `mcp_gateway/` paths.
--------------------------------------------------------------------------------
/start_web_server.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Start JRVS Web Server on Tailscale network
3 |
4 | cd "$(dirname "$0")"
5 |
6 | # Check Tailscale
7 | if ! tailscale status &>/dev/null; then
8 | echo "❌ Error: Tailscale is not running"
9 | echo " Start it with: sudo systemctl start tailscaled"
10 | exit 1
11 | fi
12 |
13 | TAILSCALE_IP=$(tailscale ip -4)
14 | if [ -z "$TAILSCALE_IP" ]; then
15 | echo "❌ Error: Could not get Tailscale IP"
16 | exit 1
17 | fi
18 |
19 | echo "🚀 Starting JRVS Web Server..."
20 | echo " Tailscale IP: $TAILSCALE_IP"
21 | echo " Port: 8080"
22 | echo ""
23 | echo "🔒 Access JRVS at: http://$TAILSCALE_IP:8080/"
24 | echo ""
25 | echo " From any Tailscale device:"
26 | echo " - Desktop browsers"
27 | echo " - Mobile devices"
28 | echo " - Tablets"
29 | echo ""
30 | echo "Press Ctrl+C to stop"
31 | echo ""
32 |
33 | python3 web_server.py
34 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # Python
4 | __pycache__/
5 | *.py[cod]
6 | *$py.class
7 | *.so
8 | .Python
9 | *.egg-info/
10 | .eggs/
11 | dist/
12 | build/
13 | *.egg
14 |
15 | # Virtual environments
16 | venv/
17 | .venv/
18 | ENV/
19 | env/
20 |
21 | # dependencies
22 | /node_modules
23 | /.pnp
24 | .pnp.*
25 | .yarn/*
26 | !.yarn/patches
27 | !.yarn/plugins
28 | !.yarn/releases
29 | !.yarn/versions
30 |
31 | # testing
32 | /coverage
33 |
34 | # next.js
35 | /.next/
36 | /out/
37 |
38 | # production
39 | /build
40 |
41 | # misc
42 | .DS_Store
43 | *.pem
44 |
45 | # debug
46 | npm-debug.log*
47 | yarn-debug.log*
48 | yarn-error.log*
49 | .pnpm-debug.log*
50 |
51 | # env files (can opt-in for committing if needed)
52 | .env*
53 |
54 | # vercel
55 | .vercel
56 |
57 | # typescript
58 | *.tsbuildinfo
59 | next-env.d.ts
60 |
--------------------------------------------------------------------------------
/public/globe.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/mcp/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "server": {
3 | "host": "localhost",
4 | "port": 3000,
5 | "log_level": "INFO",
6 | "log_file": "logs/jrvs-mcp.log",
7 | "json_logs": true
8 | },
9 | "ollama": {
10 | "base_url": "http://localhost:11434",
11 | "default_model": "deepseek-r1:14b",
12 | "timeout_seconds": 300,
13 | "max_retries": 3
14 | },
15 | "database": {
16 | "path": "data/jarvis.db",
17 | "max_connections": 10,
18 | "timeout_seconds": 30
19 | },
20 | "rag": {
21 | "vector_index_path": "data/faiss_index",
22 | "embedding_model": "all-MiniLM-L6-v2",
23 | "max_context_length": 4000,
24 | "max_retrieved_chunks": 5,
25 | "chunk_size": 512,
26 | "chunk_overlap": 50,
27 | "embedding_batch_size": 64
28 | },
29 | "cache": {
30 | "enabled": true,
31 | "max_size": 1000,
32 | "default_ttl_seconds": 300,
33 | "cleanup_interval_seconds": 60
34 | },
35 | "rate_limit": {
36 | "enabled": true,
37 | "default_rate_per_minute": 60,
38 | "default_burst": 10,
39 | "per_client_limits": {}
40 | },
41 | "resource": {
42 | "max_memory_mb": 2048,
43 | "max_concurrent_requests": 100,
44 | "max_request_duration_seconds": 300
45 | },
46 | "auth": {
47 | "enabled": false,
48 | "require_api_key": false,
49 | "development_mode": true
50 | },
51 | "monitoring": {
52 | "enabled": true,
53 | "metrics_interval_seconds": 30,
54 | "health_check_interval_seconds": 60
55 | }
56 | }
--------------------------------------------------------------------------------
/push_to_github.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Script to push JRVS with JARCORE to GitHub
3 |
4 | cd /home/xmanz/JRVS
5 |
6 | echo "Initializing git repository..."
7 | git init
8 |
9 | echo "Configuring git..."
10 | git config user.email "your-email@example.com"
11 | git config user.name "Xthebuilder"
12 |
13 | echo "Staging all files..."
14 | git add -A
15 |
16 | echo "Creating commit..."
17 | git commit -m "feat: Add JARCORE - JARVIS Autonomous Reasoning & Coding Engine
18 |
19 | - AI-powered coding assistant using local Ollama models
20 | - 11 new MCP tools for code generation, analysis, execution
21 | - CLI interface with 7 commands (jarcore_cli.py)
22 | - Interactive demo showcasing all features
23 | - Support for 10+ programming languages
24 | - Comprehensive documentation
25 |
26 | Features:
27 | - Code generation from natural language
28 | - Comprehensive code analysis (bugs, security, performance)
29 | - AI-powered refactoring
30 | - Automatic test generation
31 | - Safe code execution
32 | - Intelligent error fixing
33 | - File operations with auto-backup
34 | - Code explanations in natural language
35 |
36 | 100% local, private, and free using Ollama models."
37 |
38 | echo "Setting remote..."
39 | git remote add origin https://github.com/Xthebuilder/JRVS.git || git remote set-url origin https://github.com/Xthebuilder/JRVS.git
40 |
41 | echo "Setting up GitHub authentication..."
42 | gh auth setup-git
43 |
44 | echo "Pushing to GitHub (force to replace old JRVS)..."
45 | git push -u origin main --force
46 |
47 | echo "Done! JRVS with JARCORE pushed to GitHub."
48 |
--------------------------------------------------------------------------------
/add_event.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | """Quick script to add calendar events to JRVS"""
3 | import asyncio
4 | import aiosqlite
5 | from datetime import datetime
6 | import sys
7 |
8 | async def add_event(title: str, date_str: str, time_str: str = "09:00", description: str = ""):
9 | """Add event to JRVS calendar
10 |
11 | Args:
12 | title: Event title
13 | date_str: Date in format YYYY-MM-DD
14 | time_str: Time in format HH:MM (default: 09:00)
15 | description: Optional event description
16 | """
17 | db_path = 'data/jarvis.db'
18 |
19 | # Parse datetime
20 | dt_str = f"{date_str} {time_str}"
21 | event_date = datetime.strptime(dt_str, "%Y-%m-%d %H:%M")
22 |
23 | async with aiosqlite.connect(db_path) as db:
24 | cursor = await db.execute('''
25 | INSERT INTO events (title, description, event_date, reminder_minutes, completed)
26 | VALUES (?, ?, ?, ?, ?)
27 | ''', (title, description, event_date.isoformat(), 0, False))
28 | await db.commit()
29 | event_id = cursor.lastrowid
30 | print(f"✓ Event added (ID: {event_id})")
31 | print(f" Title: {title}")
32 | print(f" Date: {event_date.strftime('%Y-%m-%d %H:%M')}")
33 |
34 | if __name__ == "__main__":
35 | if len(sys.argv) < 3:
36 | print("Usage: python add_event.py [time] [description]")
37 | print("Example: python add_event.py 'Team meeting' 2025-11-15 14:30 'Discuss project'")
38 | sys.exit(1)
39 |
40 | title = sys.argv[1]
41 | date = sys.argv[2]
42 | time = sys.argv[3] if len(sys.argv) > 3 else "09:00"
43 | desc = sys.argv[4] if len(sys.argv) > 4 else ""
44 |
45 | asyncio.run(add_event(title, date, time, desc))
46 |
--------------------------------------------------------------------------------
/docs/START_HERE.md:
--------------------------------------------------------------------------------
1 | # 🚀 START HERE - JRVS Quick Launch
2 |
3 | ## ✅ Setup Status: COMPLETE
4 |
5 | Everything is configured and ready to go!
6 |
7 | ## Launch JRVS Now
8 |
9 | ```bash
10 | ./start_jrvs.sh
11 | ```
12 |
13 | Or:
14 |
15 | ```bash
16 | python main.py
17 | ```
18 |
19 | ## What's Configured
20 |
21 | ✅ **Python & Dependencies** - All installed
22 | ✅ **Database** - Initialized
23 | ✅ **Ollama** - Running with 12 models
24 | ✅ **MCP Servers** - Filesystem + Memory ready
25 | ✅ **Calendar** - With your event tomorrow at 10am
26 | ✅ **Intelligent Agent** - Auto tool selection active
27 |
28 | ## First Commands to Try
29 |
30 | ```bash
31 | # See what's available
32 | /help
33 |
34 | # View your calendar
35 | /month
36 |
37 | # Check MCP tools
38 | /mcp-servers
39 |
40 | # Just chat naturally!
41 | what is async programming?
42 | remember that I like Python
43 | read the file README.md
44 | ```
45 |
46 | ## Key Features
47 |
48 | 🤖 **Intelligent Agent** - JRVS automatically uses tools when needed
49 | 📅 **Smart Calendar** - "add meeting tomorrow at 2pm"
50 | 🔧 **MCP Tools** - File access, memory, web search (w/ API key)
51 | 🧠 **RAG System** - Context-aware responses
52 | 📊 **Reports** - `/report` shows what JRVS did
53 |
54 | ## Documentation
55 |
56 | - **SETUP_COMPLETE.md** - Full setup details
57 | - **README.md** - Main documentation
58 | - **MCP_CLIENT_GUIDE.md** - MCP usage
59 | - **BRAVE_SEARCH_SETUP.md** - Enable web search
60 |
61 | ## Quick Tips
62 |
63 | 💡 **Chat naturally** - JRVS figures out what tools to use
64 | 💡 **Use /report** - See what tools were called and why
65 | 💡 **Add Brave API key** - Enable web search (optional)
66 | 💡 **Check /help** - See all commands
67 |
68 | ---
69 |
70 | **Ready to go! Launch JRVS and start chatting! 🎉**
71 |
72 | ```bash
73 | ./start_jrvs.sh
74 | ```
75 |
--------------------------------------------------------------------------------
/tests/test_mcp_client.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | """
3 | Test script for JRVS MCP Client
4 |
5 | This script demonstrates connecting to MCP servers and calling tools.
6 | """
7 |
8 | import asyncio
9 | from mcp_gateway.client import mcp_client
10 |
11 | async def main():
12 | print("🔌 Testing JRVS MCP Client\n")
13 |
14 | # Initialize
15 | print("Initializing MCP client...")
16 | success = await mcp_client.initialize()
17 |
18 | if not success:
19 | print("❌ Failed to initialize MCP client")
20 | return
21 |
22 | # List servers
23 | servers = await mcp_client.list_servers()
24 | print(f"\n✓ Connected to {len(servers)} server(s):")
25 | for server in servers:
26 | print(f" • {server}")
27 |
28 | # List all tools
29 | print("\n📋 Available tools:")
30 | all_tools = await mcp_client.list_all_tools()
31 | for server, tools in all_tools.items():
32 | print(f"\n {server}:")
33 | for tool in tools[:3]: # Show first 3 tools
34 | print(f" • {tool['name']} - {tool.get('description', 'No description')}")
35 | if len(tools) > 3:
36 | print(f" ... and {len(tools) - 3} more")
37 |
38 | # Example tool call (if filesystem server is available)
39 | if "filesystem" in servers:
40 | print("\n🔧 Testing filesystem tool...")
41 | try:
42 | # List files in current directory
43 | result = await mcp_client.call_tool(
44 | "filesystem",
45 | "list_directory",
46 | {"path": "."}
47 | )
48 | print(f"✓ Listed directory successfully")
49 | except Exception as e:
50 | print(f"⚠️ Tool call failed: {e}")
51 |
52 | # Cleanup
53 | print("\n🧹 Cleaning up...")
54 | await mcp_client.cleanup()
55 | print("✓ Done!")
56 |
57 | if __name__ == "__main__":
58 | asyncio.run(main())
59 |
--------------------------------------------------------------------------------
/Dockerfile.mcp:
--------------------------------------------------------------------------------
1 | # Multi-stage Dockerfile for JRVS Enhanced MCP Server
2 | # Optimized for production deployment
3 |
4 | # ============================================================================
5 | # Stage 1: Builder - Install dependencies
6 | # ============================================================================
7 | FROM python:3.11-slim as builder
8 |
9 | WORKDIR /build
10 |
11 | # Install build dependencies
12 | RUN apt-get update && apt-get install -y --no-install-recommends \
13 | gcc \
14 | g++ \
15 | build-essential \
16 | && rm -rf /var/lib/apt/lists/*
17 |
18 | # Copy requirements
19 | COPY requirements.txt .
20 |
21 | # Install Python dependencies
22 | RUN pip install --no-cache-dir --user -r requirements.txt
23 |
24 | # ============================================================================
25 | # Stage 2: Runtime - Minimal production image
26 | # ============================================================================
27 | FROM python:3.11-slim
28 |
29 | LABEL maintainer="JRVS Team"
30 | LABEL description="JRVS Enhanced MCP Server - Production Ready"
31 | LABEL version="1.0.0"
32 |
33 | # Create non-root user
34 | RUN groupadd -r jrvs && useradd -r -g jrvs jrvs
35 |
36 | # Set working directory
37 | WORKDIR /app
38 |
39 | # Install runtime dependencies only
40 | RUN apt-get update && apt-get install -y --no-install-recommends \
41 | curl \
42 | && rm -rf /var/lib/apt/lists/*
43 |
44 | # Copy Python packages from builder
45 | COPY --from=builder /root/.local /home/jrvs/.local
46 |
47 | # Copy application code
48 | COPY --chown=jrvs:jrvs . .
49 |
50 | # Create necessary directories
51 | RUN mkdir -p /app/data /app/logs && \
52 | chown -R jrvs:jrvs /app/data /app/logs
53 |
54 | # Set environment variables
55 | ENV PATH=/home/jrvs/.local/bin:$PATH \
56 | PYTHONUNBUFFERED=1 \
57 | PYTHONDONTWRITEBYTECODE=1 \
58 | JRVS_LOG_LEVEL=INFO \
59 | OLLAMA_BASE_URL=http://ollama:11434
60 |
61 | # Switch to non-root user
62 | USER jrvs
63 |
64 | # Health check
65 | HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
66 | CMD python -c "import sys; sys.exit(0)"
67 |
68 | # Expose port (if needed for HTTP interface)
69 | EXPOSE 3000
70 |
71 | # Run the enhanced MCP server
72 | CMD ["python", "mcp/server_enhanced.py"]
73 |
--------------------------------------------------------------------------------
/tests/test_coding_agent.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | """Test script for JRVS Coding Agent"""
3 |
4 | import sys
5 | import asyncio
6 | from pathlib import Path
7 |
8 | # Add project root to path
9 | sys.path.insert(0, str(Path(__file__).parent))
10 |
11 | async def test_coding_agent():
12 | """Test the coding agent functionality"""
13 | try:
14 | from mcp_gateway.coding_agent import coding_agent
15 | print("✓ Coding agent imported successfully")
16 |
17 | # Test code generation
18 | print("\n=== Testing Code Generation ===")
19 | result = await coding_agent.generate_code(
20 | task="Create a function that calculates fibonacci numbers",
21 | language="python",
22 | include_tests=False
23 | )
24 |
25 | if "error" not in result:
26 | print("✓ Code generation successful")
27 | print(f"Generated code:\n{result.get('code', 'N/A')[:200]}...")
28 | else:
29 | print(f"✗ Code generation failed: {result['error']}")
30 |
31 | # Test code explanation
32 | print("\n=== Testing Code Explanation ===")
33 | test_code = """
34 | def fibonacci(n):
35 | if n <= 1:
36 | return n
37 | return fibonacci(n-1) + fibonacci(n-2)
38 | """
39 | explanation = await coding_agent.explain_code(test_code, "python", "brief")
40 | print(f"✓ Explanation: {explanation[:200]}...")
41 |
42 | # Test file operations
43 | print("\n=== Testing File Operations ===")
44 | test_file = "/tmp/jrvs_test.py"
45 | write_result = await coding_agent.write_file(
46 | test_file,
47 | test_code,
48 | create_dirs=True,
49 | backup=False
50 | )
51 |
52 | if write_result.get("success"):
53 | print(f"✓ File written: {test_file}")
54 |
55 | read_result = await coding_agent.read_file(test_file)
56 | if not read_result.get("error"):
57 | print(f"✓ File read: {read_result.get('lines')} lines")
58 | else:
59 | print(f"✗ File read failed: {read_result.get('error')}")
60 | else:
61 | print(f"✗ File write failed: {write_result.get('error')}")
62 |
63 | print("\n=== All Tests Complete ===")
64 |
65 | except Exception as e:
66 | print(f"✗ Test failed: {e}")
67 | import traceback
68 | traceback.print_exc()
69 |
70 | if __name__ == "__main__":
71 | asyncio.run(test_coding_agent())
72 |
--------------------------------------------------------------------------------
/scripts/start_mcp_enhanced.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Quick start script for JRVS Enhanced MCP Server
3 |
4 | set -e
5 |
6 | echo "================================================================"
7 | echo " JRVS Enhanced MCP Server - Quick Start"
8 | echo "================================================================"
9 | echo ""
10 |
11 | # Colors
12 | GREEN='\033[0;32m'
13 | YELLOW='\033[1;33m'
14 | RED='\033[0;31m'
15 | NC='\033[0m' # No Color
16 |
17 | # Check Python version
18 | echo -n "Checking Python version... "
19 | PYTHON_VERSION=$(python --version 2>&1 | awk '{print $2}')
20 | if python -c "import sys; exit(0 if sys.version_info >= (3, 11) else 1)"; then
21 | echo -e "${GREEN}✓${NC} Python $PYTHON_VERSION"
22 | else
23 | echo -e "${RED}✗${NC} Python 3.11+ required, found $PYTHON_VERSION"
24 | exit 1
25 | fi
26 |
27 | # Check if Ollama is running
28 | echo -n "Checking Ollama service... "
29 | if curl -s http://localhost:11434/api/tags > /dev/null 2>&1; then
30 | echo -e "${GREEN}✓${NC} Ollama is running"
31 | else
32 | echo -e "${YELLOW}⚠${NC} Ollama not detected"
33 | echo " Start Ollama with: ollama serve"
34 | echo " Then pull a model: ollama pull deepseek-r1:14b"
35 | fi
36 |
37 | # Check dependencies
38 | echo -n "Checking dependencies... "
39 | if python -c "import mcp, faiss, sentence_transformers, aiohttp" > /dev/null 2>&1; then
40 | echo -e "${GREEN}✓${NC} All dependencies installed"
41 | else
42 | echo -e "${YELLOW}⚠${NC} Missing dependencies"
43 | echo " Installing dependencies..."
44 | pip install -r requirements.txt
45 | fi
46 |
47 | # Create required directories
48 | echo -n "Creating directories... "
49 | mkdir -p data logs mcp/tests
50 | echo -e "${GREEN}✓${NC}"
51 |
52 | # Create default config if doesn't exist
53 | if [ ! -f "mcp/config.json" ]; then
54 | echo -n "Creating default configuration... "
55 | python -c "from mcp.config_manager import create_default_config; create_default_config('mcp/config.json')"
56 | echo -e "${GREEN}✓${NC}"
57 | else
58 | echo -e "${GREEN}✓${NC} Configuration exists"
59 | fi
60 |
61 | echo ""
62 | echo "================================================================"
63 | echo " Starting JRVS Enhanced MCP Server"
64 | echo "================================================================"
65 | echo ""
66 | echo " Config: mcp/config.json"
67 | echo " Logs: logs/jrvs-mcp-enhanced.log"
68 | echo ""
69 | echo " Press Ctrl+C to stop the server"
70 | echo ""
71 | echo "================================================================"
72 | echo ""
73 |
74 | # Start the server
75 | python mcp/server_enhanced.py
76 |
--------------------------------------------------------------------------------
/tests/test_calendar_api.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | """Test calendar API endpoint"""
3 |
4 | import asyncio
5 | import httpx
6 | from datetime import datetime
7 |
8 | async def test_calendar():
9 | """Test adding calendar event via API"""
10 |
11 | # Start by testing the calendar module directly
12 | print("1. Testing calendar module directly...")
13 | from core.calendar import calendar
14 | from datetime import datetime
15 |
16 | try:
17 | await calendar.initialize()
18 | event_id = await calendar.add_event(
19 | title="Direct Test Event",
20 | event_date=datetime.now(),
21 | description="Testing calendar directly"
22 | )
23 | print(f"✓ Direct calendar test passed! Event ID: {event_id}")
24 |
25 | # Get events
26 | events = await calendar.get_today_events()
27 | print(f"✓ Today's events: {len(events)}")
28 | for event in events:
29 | print(f" - {event['title']} at {event['event_date']}")
30 | except Exception as e:
31 | print(f"✗ Direct calendar test failed: {e}")
32 | import traceback
33 | traceback.print_exc()
34 |
35 | # Now test via HTTP API
36 | print("\n2. Testing via HTTP API...")
37 | try:
38 | async with httpx.AsyncClient() as client:
39 | # Get Tailscale IP
40 | import subprocess
41 | result = subprocess.run(
42 | ["tailscale", "ip", "-4"],
43 | capture_output=True,
44 | text=True
45 | )
46 | tailscale_ip = result.stdout.strip() if result.returncode == 0 else "localhost"
47 |
48 | url = f"http://{tailscale_ip}:8080/api/calendar/event"
49 |
50 | data = {
51 | "title": "API Test Event",
52 | "date": datetime.now().strftime("%Y-%m-%d"),
53 | "time": "14:30",
54 | "description": "Testing via HTTP API"
55 | }
56 |
57 | print(f"Posting to: {url}")
58 | print(f"Data: {data}")
59 |
60 | response = await client.post(url, data=data)
61 | print(f"Status: {response.status_code}")
62 | print(f"Response: {response.text}")
63 |
64 | if response.status_code == 200:
65 | print("✓ API test passed!")
66 | else:
67 | print(f"✗ API test failed with status {response.status_code}")
68 |
69 | except Exception as e:
70 | print(f"✗ API test failed: {e}")
71 | import traceback
72 | traceback.print_exc()
73 |
74 | if __name__ == "__main__":
75 | asyncio.run(test_calendar())
76 |
--------------------------------------------------------------------------------
/lib/firebase.ts:
--------------------------------------------------------------------------------
1 | import { initializeApp, getApps, getApp, FirebaseApp } from 'firebase/app';
2 | import { getAuth, Auth } from 'firebase/auth';
3 | import { getFirestore, Firestore } from 'firebase/firestore';
4 | import { getStorage, FirebaseStorage } from 'firebase/storage';
5 |
6 | // Firebase configuration
7 | const firebaseConfig = {
8 | apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
9 | authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
10 | projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
11 | storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
12 | messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
13 | appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
14 | measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID
15 | };
16 |
17 | // Validate Firebase configuration
18 | const validateFirebaseConfig = () => {
19 | const requiredEnvVars = [
20 | 'NEXT_PUBLIC_FIREBASE_API_KEY',
21 | 'NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN',
22 | 'NEXT_PUBLIC_FIREBASE_PROJECT_ID',
23 | 'NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET',
24 | 'NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID',
25 | 'NEXT_PUBLIC_FIREBASE_APP_ID'
26 | ];
27 |
28 | const missingVars = requiredEnvVars.filter((varName) => {
29 | const value = process.env[varName];
30 | return !value ||
31 | value.includes('your-') ||
32 | value.includes('here') ||
33 | value.trim() === '';
34 | });
35 |
36 | if (missingVars.length > 0) {
37 | console.warn(
38 | '⚠️ Firebase configuration is incomplete. Missing or invalid environment variables:',
39 | missingVars.join(', ')
40 | );
41 | console.warn(
42 | 'Please create a .env.local file with your Firebase credentials. See .env.local.example for reference.'
43 | );
44 | console.warn(
45 | '📖 Setup guide: Check README.md for detailed Firebase setup instructions.'
46 | );
47 | } else {
48 | console.log('✅ Firebase configuration loaded successfully');
49 | }
50 | };
51 |
52 | // Validate configuration (only in browser/client)
53 | if (typeof window !== 'undefined') {
54 | validateFirebaseConfig();
55 | }
56 |
57 | // Initialize Firebase
58 | let app: FirebaseApp;
59 | try {
60 | app = getApps().length === 0 ? initializeApp(firebaseConfig) : getApp();
61 | } catch (error) {
62 | console.error('❌ Firebase initialization error:', error);
63 | throw new Error(
64 | 'Failed to initialize Firebase. Please check your environment variables.'
65 | );
66 | }
67 |
68 | // Initialize Firebase services
69 | export const auth: Auth = getAuth(app);
70 | export const db: Firestore = getFirestore(app);
71 | export const storage: FirebaseStorage = getStorage(app);
72 |
73 | export default app;
74 |
--------------------------------------------------------------------------------
/mcp_gateway/test_server.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | """Quick test to verify MCP server tools are working"""
3 |
4 | import sys
5 | import asyncio
6 | from pathlib import Path
7 |
8 | # Add project root
9 | project_root = Path(__file__).parent.parent
10 | sys.path.insert(0, str(project_root))
11 |
12 | async def test_tools():
13 | """Test basic MCP tool functionality"""
14 | print("Testing JRVS MCP Server Tools...\n")
15 |
16 | # Import after path setup
17 | from llm.ollama_client import ollama_client
18 | from rag.retriever import rag_retriever
19 | from core.database import db
20 | from core.calendar import calendar
21 |
22 | results = []
23 |
24 | # Test 1: Database initialization
25 | try:
26 | await db.initialize()
27 | results.append(("✓", "Database initialized"))
28 | except Exception as e:
29 | results.append(("✗", f"Database failed: {e}"))
30 |
31 | # Test 2: RAG system
32 | try:
33 | await rag_retriever.initialize()
34 | stats = await rag_retriever.get_stats()
35 | results.append(("✓", f"RAG initialized (vectors: {stats.get('vector_store', {}).get('total_vectors', 0)})"))
36 | except Exception as e:
37 | results.append(("✗", f"RAG failed: {e}"))
38 |
39 | # Test 3: Calendar
40 | try:
41 | await calendar.initialize()
42 | events = await calendar.get_upcoming_events(days=7)
43 | results.append(("✓", f"Calendar initialized ({len(events)} events)"))
44 | except Exception as e:
45 | results.append(("✗", f"Calendar failed: {e}"))
46 |
47 | # Test 4: Ollama connection
48 | try:
49 | models = await ollama_client.discover_models()
50 | if models:
51 | results.append(("✓", f"Ollama connected ({len(models)} models)"))
52 | else:
53 | results.append(("⚠", "Ollama connected but no models found"))
54 | except Exception as e:
55 | results.append(("⚠", f"Ollama not available: {e}"))
56 |
57 | # Print results
58 | print("\nTest Results:")
59 | print("-" * 60)
60 | for status, message in results:
61 | print(f"{status} {message}")
62 |
63 | # Summary
64 | passed = sum(1 for s, _ in results if s == "✓")
65 | failed = sum(1 for s, _ in results if s == "✗")
66 | warnings = sum(1 for s, _ in results if s == "⚠")
67 |
68 | print("-" * 60)
69 | print(f"Passed: {passed} | Failed: {failed} | Warnings: {warnings}")
70 |
71 | if failed == 0:
72 | print("\n✓ MCP server components are ready!")
73 | return True
74 | else:
75 | print("\n✗ Some components failed. Check errors above.")
76 | return False
77 |
78 | if __name__ == "__main__":
79 | success = asyncio.run(test_tools())
80 | sys.exit(0 if success else 1)
81 |
--------------------------------------------------------------------------------
/config.py:
--------------------------------------------------------------------------------
1 | """Configuration settings for Jarvis AI Agent"""
2 | import os
3 | from pathlib import Path
4 |
5 | # Base paths
6 | BASE_DIR = Path(__file__).parent
7 | DATA_DIR = BASE_DIR / "data"
8 | MODELS_DIR = DATA_DIR / "models"
9 |
10 | # JARCORE workspace settings
11 | JARCORE_WORKSPACE = Path(os.environ.get("JARCORE_WORKSPACE", Path.cwd()))
12 |
13 | # Ensure directories exist
14 | DATA_DIR.mkdir(exist_ok=True)
15 | MODELS_DIR.mkdir(exist_ok=True)
16 |
17 | # Database settings
18 | DATABASE_PATH = DATA_DIR / "jarvis.db"
19 | VECTOR_INDEX_PATH = DATA_DIR / "faiss_index"
20 |
21 | # Ollama settings
22 | OLLAMA_BASE_URL = os.environ.get("OLLAMA_BASE_URL", "http://localhost:11434")
23 | DEFAULT_MODEL = os.environ.get("OLLAMA_DEFAULT_MODEL", "deepseek-r1:14b")
24 |
25 | # LM Studio settings (OpenAI-compatible API)
26 | LMSTUDIO_BASE_URL = os.environ.get("LMSTUDIO_BASE_URL", "http://127.0.0.1:1234/v1")
27 | LMSTUDIO_DEFAULT_MODEL = os.environ.get("LMSTUDIO_DEFAULT_MODEL", "")
28 |
29 | # Timeout settings (in seconds)
30 | TIMEOUTS = {
31 | "embedding_generation": 60,
32 | "vector_search": 10,
33 | "context_building": 60,
34 | "ollama_response": 300, # 5 minutes
35 | "llm_response": 300, # Generic LLM response timeout (5 minutes)
36 | "web_scraping": 45
37 | }
38 |
39 | # RAG settings
40 | MAX_CONTEXT_LENGTH = 4000
41 | MAX_RETRIEVED_CHUNKS = 5
42 | CHUNK_SIZE = 512
43 | CHUNK_OVERLAP = 50
44 |
45 | # Performance settings
46 | MAX_MEMORY_MB = 2024
47 | EMBEDDING_BATCH_SIZE = 64
48 | VECTOR_CACHE_SIZE = 2000
49 |
50 | # CLI Theme settings
51 | THEMES = {
52 | "matrix": {
53 | "primary": "bright_green",
54 | "secondary": "green",
55 | "accent": "bright_cyan",
56 | "error": "bright_red",
57 | "warning": "bright_yellow",
58 | "prompt": "bright_green",
59 | "response": "white"
60 | },
61 | "cyberpunk": {
62 | "primary": "bright_magenta",
63 | "secondary": "magenta",
64 | "accent": "bright_cyan",
65 | "error": "bright_red",
66 | "warning": "bright_yellow",
67 | "prompt": "bright_magenta",
68 | "response": "bright_white"
69 | },
70 | "minimal": {
71 | "primary": "white",
72 | "secondary": "bright_black",
73 | "accent": "blue",
74 | "error": "red",
75 | "warning": "yellow",
76 | "prompt": "blue",
77 | "response": "white"
78 | }
79 | }
80 |
81 | DEFAULT_THEME = "matrix"
82 |
83 | # ASCII Art
84 | JARVIS_ASCII = """
85 | ██╗ █████╗ ██████╗ ██╗ ██╗██╗███████╗
86 | ██║██╔══██╗██╔══██╗██║ ██║██║██╔════╝
87 | ██║███████║██████╔╝██║ ██║██║███████╗
88 | ██ ██║██╔══██║██╔══██╗╚██╗ ██╔╝██║╚════██║
89 | ╚█████╔╝██║ ██║██║ ██║ ╚████╔╝ ██║███████║
90 | ╚════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═══╝ ╚═╝╚══════╝
91 | Advanced RAG-Powered AI Assistant
92 | """
93 |
--------------------------------------------------------------------------------
/docker-compose.mcp.yml:
--------------------------------------------------------------------------------
1 | version: '3.8'
2 |
3 | services:
4 | # ============================================================================
5 | # Ollama Service
6 | # ============================================================================
7 | ollama:
8 | image: ollama/ollama:latest
9 | container_name: jrvs-ollama
10 | ports:
11 | - "11434:11434"
12 | volumes:
13 | - ollama_data:/root/.ollama
14 | environment:
15 | - OLLAMA_ORIGINS=*
16 | healthcheck:
17 | test: ["CMD", "curl", "-f", "http://localhost:11434/api/tags"]
18 | interval: 30s
19 | timeout: 10s
20 | retries: 3
21 | start_period: 40s
22 | restart: unless-stopped
23 | networks:
24 | - jrvs-network
25 |
26 | # ============================================================================
27 | # JRVS Enhanced MCP Server
28 | # ============================================================================
29 | jrvs-mcp:
30 | build:
31 | context: .
32 | dockerfile: Dockerfile.mcp
33 | container_name: jrvs-mcp-server
34 | depends_on:
35 | ollama:
36 | condition: service_healthy
37 | environment:
38 | # Server config
39 | - JRVS_LOG_LEVEL=INFO
40 | - JRVS_HOST=0.0.0.0
41 | - JRVS_PORT=3000
42 |
43 | # Ollama config
44 | - OLLAMA_BASE_URL=http://ollama:11434
45 | - OLLAMA_DEFAULT_MODEL=deepseek-r1:14b
46 |
47 | # Database
48 | - JRVS_DB_PATH=/app/data/jarvis.db
49 |
50 | # Cache
51 | - JRVS_CACHE_ENABLED=true
52 |
53 | # Rate limiting
54 | - JRVS_RATE_LIMIT_ENABLED=true
55 | - JRVS_RATE_LIMIT_PER_MINUTE=60
56 |
57 | # Authentication (disable in production with real auth)
58 | - JRVS_AUTH_ENABLED=false
59 | - JRVS_REQUIRE_API_KEY=false
60 | volumes:
61 | # Persistent data
62 | - jrvs_data:/app/data
63 | - jrvs_logs:/app/logs
64 |
65 | # Mount code for development (comment out for production)
66 | # - ./:/app
67 | ports:
68 | - "3000:3000"
69 | healthcheck:
70 | test: ["CMD", "python", "-c", "import sys; sys.exit(0)"]
71 | interval: 30s
72 | timeout: 10s
73 | retries: 3
74 | start_period: 60s
75 | restart: unless-stopped
76 | networks:
77 | - jrvs-network
78 | stdin_open: true
79 | tty: true
80 |
81 | # ============================================================================
82 | # Volumes
83 | # ============================================================================
84 | volumes:
85 | ollama_data:
86 | driver: local
87 | jrvs_data:
88 | driver: local
89 | jrvs_logs:
90 | driver: local
91 |
92 | # ============================================================================
93 | # Networks
94 | # ============================================================================
95 | networks:
96 | jrvs-network:
97 | driver: bridge
98 |
--------------------------------------------------------------------------------
/mcp_gateway/client_config.json:
--------------------------------------------------------------------------------
1 | {
2 | "mcpServers": {
3 | "filesystem": {
4 | "command": "npx",
5 | "args": [
6 | "-y",
7 | "@modelcontextprotocol/server-filesystem",
8 | "/tmp"
9 | ],
10 | "description": "File operations - JRVS can read, write, search, and manage files in allowed directories. Add your own paths to the 'args' array above."
11 | },
12 | "memory": {
13 | "command": "npx",
14 | "args": ["-y", "@modelcontextprotocol/server-memory"],
15 | "description": "Persistent memory - JRVS remembers facts, notes, and preferences across sessions"
16 | },
17 | "brave-search": {
18 | "command": "npx",
19 | "args": ["-y", "@modelcontextprotocol/server-brave-search"],
20 | "env": {
21 | "BRAVE_API_KEY": ""
22 | },
23 | "description": "Web search via Brave - ADD YOUR API KEY ABOVE (get from https://brave.com/search/api/)"
24 | }
25 | },
26 | "_disabled_servers": {},
27 | "_comment": "Active MCP Servers for JRVS",
28 | "_setup_instructions": {
29 | "filesystem": {
30 | "status": "READY TO USE",
31 | "description": "Filesystem server allows JRVS to access files in specified directories",
32 | "allowed_paths": [
33 | "/tmp - Temporary files (default, always available)"
34 | ],
35 | "setup_note": "Add your own directories to the 'args' array in the filesystem server config above. Example: add '/home/yourusername/Documents' to allow access to your Documents folder.",
36 | "security": "Only directories listed in 'args' are accessible. Add/remove paths as needed. Paths are validated before connection - invalid paths are filtered out with warnings.",
37 | "tools": [
38 | "read_file - Read file contents",
39 | "write_file - Write to files",
40 | "list_directory - List directory contents",
41 | "create_directory - Create new directories",
42 | "move_file - Move/rename files",
43 | "search_files - Search for files",
44 | "get_file_info - Get file metadata"
45 | ]
46 | },
47 | "memory": {
48 | "status": "READY TO USE",
49 | "description": "Memory server gives JRVS persistent memory across sessions",
50 | "storage": "~/.memory-server/ (automatically created)",
51 | "tools": [
52 | "create_memory - Store a new memory/note",
53 | "search_memories - Search stored memories",
54 | "list_memories - List all memories",
55 | "delete_memory - Remove a memory"
56 | ],
57 | "examples": [
58 | "Remember: User prefers Python 3.11",
59 | "Remember: Daily standup at 9am every Monday",
60 | "Remember: Database password is in ~/.secrets/db.txt"
61 | ]
62 | },
63 | "brave-search": {
64 | "status": "DISABLED - NEEDS API KEY",
65 | "description": "Brave Search gives JRVS web search capabilities",
66 | "setup_steps": [
67 | "1. Get API key from: https://brave.com/search/api/",
68 | "2. Replace 'GET_YOUR_KEY_FROM_...' with your actual key",
69 | "3. Move this config from '_disabled_servers' to 'mcpServers'",
70 | "4. Restart JRVS"
71 | ],
72 | "pricing": "Free tier: 2,000 queries/month",
73 | "tools": [
74 | "brave_web_search - Search the web",
75 | "brave_local_search - Search for local businesses/places"
76 | ]
77 | }
78 | },
79 | "_notes": {
80 | "security": "Be careful with filesystem paths - only add directories you trust JRVS to access",
81 | "performance": "Each connected server uses some resources. Disable unused servers by moving them to _disabled_servers",
82 | "more_servers": "See available servers at: https://github.com/modelcontextprotocol/servers"
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/docs/TAILSCALE_QUICKSTART.md:
--------------------------------------------------------------------------------
1 | # 🚀 JRVS on Tailscale - Quick Start
2 |
3 | ## ✅ Setup Complete!
4 |
5 | JRVS is now configured to run as a **private web server** on your Tailscale network.
6 |
7 | ## 🔒 Your Tailscale IP
8 |
9 | ```
10 | 100.113.61.115
11 | ```
12 |
13 | ## 🌐 Start the Web Server
14 |
15 | ```bash
16 | ./start_web_server.sh
17 | ```
18 |
19 | ## 📱 Access JRVS
20 |
21 | From **any device** on your Tailscale network:
22 |
23 | ### In Your Browser
24 | ```
25 | http://100.113.61.115:8080/
26 | ```
27 |
28 | ### From Your Devices
29 | - ✅ **Desktop** - Any browser
30 | - ✅ **Laptop** - Any browser
31 | - ✅ **iPhone/iPad** - Safari/Chrome (install Tailscale app first)
32 | - ✅ **Android** - Chrome/Firefox (install Tailscale app first)
33 | - ✅ **Tablet** - Any browser
34 |
35 | ## 🎯 What You Get
36 |
37 | ### Modern Web Interface
38 | - Real-time chat with JRVS
39 | - Tool usage indicators
40 | - Mobile-friendly design
41 | - Auto-reconnect
42 |
43 | ### All JRVS Features
44 | - 🤖 Intelligent agent (auto tool selection)
45 | - 📅 Calendar
46 | - 🔧 MCP tools (filesystem, memory, brave-search*)
47 | - 🧠 RAG system
48 | - 📊 Activity reports
49 |
50 | ### Secure Access
51 | - 🔒 **Only on Tailscale** - Not public internet
52 | - 🔒 **Encrypted** - All traffic encrypted by Tailscale
53 | - 🔒 **Authenticated** - Only your devices
54 |
55 | ## ⚡ Quick Test
56 |
57 | 1. **Start server:**
58 | ```bash
59 | ./start_web_server.sh
60 | ```
61 |
62 | 2. **Open browser on any Tailscale device:**
63 | ```
64 | http://100.113.61.115:8080/
65 | ```
66 |
67 | 3. **Chat with JRVS:**
68 | - "what files are in my JRVS directory?"
69 | - "remember that I prefer Python 3.11"
70 | - "add event tomorrow at 2pm"
71 |
72 | ## 📱 Mobile Setup
73 |
74 | ### iPhone/iPad
75 | 1. Install **Tailscale** from App Store
76 | 2. Login with your account
77 | 3. Open **Safari** or **Chrome**
78 | 4. Go to `http://100.113.61.115:8080/`
79 | 5. **Bookmark it** or Add to Home Screen
80 |
81 | ### Android
82 | 1. Install **Tailscale** from Play Store
83 | 2. Login with your account
84 | 3. Open **Chrome** or **Firefox**
85 | 4. Go to `http://100.113.61.115:8080/`
86 | 5. **Bookmark it** or Add to Home Screen
87 |
88 | ## 🔄 Auto-Start (Optional)
89 |
90 | To start JRVS web server on boot:
91 |
92 | ```bash
93 | sudo cp jrvs-web.service /etc/systemd/system/
94 | sudo systemctl daemon-reload
95 | sudo systemctl enable jrvs-web
96 | sudo systemctl start jrvs-web
97 | ```
98 |
99 | Check status:
100 | ```bash
101 | sudo systemctl status jrvs-web
102 | ```
103 |
104 | ## 🎮 Both Interfaces Available
105 |
106 | ### CLI (Terminal)
107 | ```bash
108 | python main.py
109 | ```
110 | - Traditional command-line interface
111 | - All slash commands (/help, /month, etc.)
112 |
113 | ### Web (Browser)
114 | ```bash
115 | ./start_web_server.sh
116 | ```
117 | - Modern web interface
118 | - Access from any device
119 | - Same features, better UX
120 |
121 | **Use whichever you prefer!** 🎉
122 |
123 | ## 📚 Documentation
124 |
125 | - **TAILSCALE_WEB_SETUP.md** - Full web server guide
126 | - **SETUP_COMPLETE.md** - Initial setup
127 | - **README.md** - Main documentation
128 |
129 | ## 🐛 Troubleshooting
130 |
131 | ### Can't access web interface
132 |
133 | **Check Tailscale:**
134 | ```bash
135 | tailscale status
136 | ```
137 |
138 | **Check server is running:**
139 | ```bash
140 | ps aux | grep web_server
141 | ```
142 |
143 | **Restart server:**
144 | ```bash
145 | ./start_web_server.sh
146 | ```
147 |
148 | ### Different devices
149 |
150 | Each device needs:
151 | 1. ✅ Tailscale app installed
152 | 2. ✅ Logged into your Tailnet
153 | 3. ✅ Connected (not paused)
154 |
155 | ## 🎉 You're Ready!
156 |
157 | Start JRVS web server and access from any device:
158 |
159 | ```bash
160 | ./start_web_server.sh
161 | ```
162 |
163 | Then open `http://100.113.61.115:8080/`
164 |
165 | **Private. Secure. Accessible everywhere.** 🔒
166 |
167 | ---
168 |
169 | For detailed information, see **TAILSCALE_WEB_SETUP.md**
170 |
--------------------------------------------------------------------------------
/mcp_gateway/README.md:
--------------------------------------------------------------------------------
1 | # JRVS MCP Server
2 |
3 | This directory contains the Model Context Protocol (MCP) server implementation for JRVS.
4 |
5 | ## Quick Start
6 |
7 | ### 1. Install Dependencies
8 | ```bash
9 | pip install -r ../requirements.txt
10 | ```
11 |
12 | ### 2. Test the Server
13 | ```bash
14 | python test_server.py
15 | ```
16 |
17 | ### 3. Run the MCP Server
18 | ```bash
19 | python server.py
20 | ```
21 |
22 | The server will start and wait for MCP client connections via stdio.
23 |
24 | ## Files
25 |
26 | - `server.py` - Main MCP server with all JRVS tools
27 | - `test_server.py` - Component test script
28 | - `claude_config.json` - Example Claude Code configuration
29 | - `README.md` - This file
30 |
31 | ## Available Tools
32 |
33 | ### Knowledge Base (17 tools total)
34 | - `search_knowledge_base` - Semantic search
35 | - `get_context_for_query` - Get RAG context
36 | - `add_document_to_knowledge_base` - Index documents
37 | - `scrape_and_index_url` - Web scraping
38 | - `get_rag_stats` - System statistics
39 | - `list_ollama_models` - List LLM models
40 | - `get_current_model` - Current model info
41 | - `switch_ollama_model` - Switch models
42 | - `generate_with_ollama` - Generate with RAG
43 | - `get_calendar_events` - Upcoming events
44 | - `get_today_events` - Today's events
45 | - `create_calendar_event` - Create events
46 | - `delete_calendar_event` - Delete events
47 | - `mark_event_completed` - Complete events
48 | - `get_conversation_history` - Chat history
49 |
50 | ### Resources
51 | - `jrvs://config` - Configuration info
52 | - `jrvs://status` - System status
53 |
54 | ## Integration with Claude Code
55 |
56 | ### Method 1: Environment Variable (Recommended for Testing)
57 |
58 | ```bash
59 | export CLAUDE_MCP_SERVER='{"jrvs": {"command": "python", "args": ["/home/xmanz/JRVS/mcp/server.py"], "env": {"PYTHONPATH": "/home/xmanz/JRVS"}}}'
60 | ```
61 |
62 | ### Method 2: Configuration File
63 |
64 | Create or edit `~/.config/claude/mcp_servers.json`:
65 |
66 | ```json
67 | {
68 | "mcpServers": {
69 | "jrvs": {
70 | "command": "python",
71 | "args": ["/home/xmanz/JRVS/mcp/server.py"],
72 | "env": {
73 | "PYTHONPATH": "/home/xmanz/JRVS"
74 | }
75 | }
76 | }
77 | }
78 | ```
79 |
80 | Then restart Claude Code.
81 |
82 | ## Testing
83 |
84 | Test individual components:
85 | ```bash
86 | python test_server.py
87 | ```
88 |
89 | Test with MCP inspector (requires Node.js):
90 | ```bash
91 | npx @modelcontextprotocol/inspector python server.py
92 | ```
93 |
94 | ## Troubleshooting
95 |
96 | **Import Error**: Make sure `mcp` package is installed:
97 | ```bash
98 | pip install 'mcp[cli]'
99 | ```
100 |
101 | **Ollama Not Available**: Start Ollama service:
102 | ```bash
103 | ollama serve
104 | ```
105 |
106 | **Database Not Found**: Run JRVS normally first:
107 | ```bash
108 | cd .. && python main.py
109 | ```
110 |
111 | ## Architecture
112 |
113 | ```
114 | MCP Client (Claude Code)
115 | ↓ stdio/JSON-RPC
116 | MCP Server (server.py)
117 | ↓
118 | FastMCP (@tool decorators)
119 | ↓
120 | JRVS Components
121 | ├─ rag_retriever (RAG/Vector Search)
122 | ├─ ollama_client (LLM Interface)
123 | ├─ calendar (Event Management)
124 | ├─ db (SQLite Storage)
125 | └─ web_scraper (Content Ingestion)
126 | ```
127 |
128 | ## Development
129 |
130 | To add new tools, use the `@mcp.tool()` decorator in `server.py`:
131 |
132 | ```python
133 | @mcp.tool()
134 | async def my_new_tool(param: str) -> dict:
135 | """Tool description for Claude"""
136 | # Your implementation
137 | return {"result": "value"}
138 | ```
139 |
140 | For resources (read-only data), use `@mcp.resource()`:
141 |
142 | ```python
143 | @mcp.resource("jrvs://my-resource")
144 | def my_resource() -> str:
145 | """Resource description"""
146 | return "Resource data"
147 | ```
148 |
149 | ## See Also
150 |
151 | - [MCP_SETUP.md](../MCP_SETUP.md) - Complete setup guide
152 | - [README.md](../README.md) - JRVS documentation
153 | - [Model Context Protocol](https://modelcontextprotocol.io) - Official MCP docs
154 |
--------------------------------------------------------------------------------
/tests/test_lmstudio_client.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | """
3 | Test script for JRVS LM Studio Client
4 |
5 | This script tests the LM Studio client functionality.
6 | """
7 |
8 | import sys
9 | import asyncio
10 | from pathlib import Path
11 |
12 | # Add project root to path
13 | sys.path.insert(0, str(Path(__file__).parent.parent))
14 |
15 |
16 | async def test_lmstudio_client():
17 | """Test the LM Studio client functionality"""
18 | from llm.lmstudio_client import LMStudioClient
19 |
20 | print("🔌 Testing JRVS LM Studio Client\n")
21 |
22 | # Create client with test URL
23 | client = LMStudioClient(base_url="http://127.0.0.1:1234/v1")
24 |
25 | # Test 1: Try to discover models (will return empty list if LM Studio is not running)
26 | print("1. Testing model discovery (connection check)...")
27 | models = await client.discover_models()
28 | if models:
29 | print(f" ✓ Connected to LM Studio, found {len(models)} model(s)")
30 | else:
31 | print(" ✗ LM Studio not running (expected if not installed)")
32 | print(" Skipping further tests as LM Studio is not available")
33 | await client.cleanup()
34 | return True # Not a failure, just not available
35 |
36 | # Test 2: List models with details
37 | print("\n2. Testing list_models...")
38 | model_list = await client.list_models()
39 | if model_list:
40 | print(f" ✓ Got model list with {len(model_list)} items")
41 | for model in model_list[:2]:
42 | print(f" • {model['name']} (current: {model['current']})")
43 | else:
44 | print(" ⚠ Empty model list")
45 |
46 | # Test 3: Test generate (non-streaming)
47 | if models:
48 | print("\n3. Testing text generation...")
49 | response = await client.generate(
50 | prompt="Say 'hello' and nothing else.",
51 | stream=False
52 | )
53 | if response:
54 | print(f" ✓ Generated response: {response[:100]}...")
55 | else:
56 | print(" ✗ Failed to generate response")
57 |
58 | # Test 4: Test set_base_url
59 | print("\n4. Testing set_base_url...")
60 | await client.set_base_url("http://localhost:1234/v1")
61 | assert client.base_url == "http://localhost:1234/v1"
62 | print(" ✓ Base URL updated successfully")
63 |
64 | # Cleanup
65 | print("\n🧹 Cleaning up...")
66 | await client.cleanup()
67 | print("✓ All tests passed!")
68 |
69 | return True
70 |
71 |
72 | async def test_client_initialization():
73 | """Test client initialization and configuration"""
74 | from llm.lmstudio_client import lmstudio_client
75 | from config import LMSTUDIO_BASE_URL
76 |
77 | print("\n📋 Testing client initialization...\n")
78 |
79 | # Test that global instance exists
80 | assert lmstudio_client is not None
81 | print(" ✓ Global lmstudio_client instance exists")
82 |
83 | # Test that it uses the configured base URL
84 | assert lmstudio_client.base_url == LMSTUDIO_BASE_URL.rstrip('/')
85 | print(f" ✓ Base URL is configured: {lmstudio_client.base_url}")
86 |
87 | # Test session starts as None
88 | assert lmstudio_client.session is None
89 | print(" ✓ Session is None initially")
90 |
91 | print("\n✓ Initialization tests passed!")
92 | return True
93 |
94 |
95 | async def main():
96 | """Run all tests"""
97 | print("=" * 50)
98 | print("LM Studio Client Test Suite")
99 | print("=" * 50)
100 |
101 | try:
102 | # Run initialization tests
103 | await test_client_initialization()
104 |
105 | # Run client tests
106 | await test_lmstudio_client()
107 |
108 | print("\n" + "=" * 50)
109 | print("All tests completed!")
110 | print("=" * 50)
111 |
112 | except Exception as e:
113 | print(f"\n❌ Test failed with error: {e}")
114 | import traceback
115 | traceback.print_exc()
116 | return 1
117 |
118 | return 0
119 |
120 |
121 | if __name__ == "__main__":
122 | exit_code = asyncio.run(main())
123 | sys.exit(exit_code)
124 |
--------------------------------------------------------------------------------
/docs/COMMANDS_FIXED.md:
--------------------------------------------------------------------------------
1 | # ✅ Slash Commands Fixed!
2 |
3 | ## What Was Wrong
4 |
5 | When you typed `/stats` or clicked the "System Stats" button, JRVS was:
6 | - ❌ Sending the command to the AI model
7 | - ❌ Getting general world statistics instead of JRVS stats
8 | - ❌ Not recognizing it as a command
9 |
10 | ## What I Fixed
11 |
12 | Added **command detection** to the WebSocket handler:
13 |
14 | 1. **Detects slash commands** - Checks if message starts with `/`
15 | 2. **Intercepts them** - Doesn't send to AI
16 | 3. **Handles properly** - Calls `handle_command()` function
17 | 4. **Returns correct data** - JRVS system stats, not AI-generated content
18 |
19 | ## Now All Commands Work!
20 |
21 | ### ✅ `/stats` - System Statistics
22 | Shows:
23 | - Current AI model
24 | - Available Ollama models
25 | - Connected MCP servers
26 | - RAG database stats (documents, chunks, embeddings)
27 | - Session info
28 |
29 | ### ✅ `/help` - Command List
30 | Shows all available commands organized by category
31 |
32 | ### ✅ `/models` - List AI Models
33 | Shows all Ollama models with current one marked
34 |
35 | ### ✅ `/mcp-servers` - MCP Servers
36 | Lists connected servers with tool counts
37 |
38 | ### ✅ `/mcp-tools` - MCP Tools
39 | Shows all available tools from all servers
40 |
41 | ### ✅ `/report` - Activity Report
42 | Displays MCP agent activity log with timestamps
43 |
44 | ### ✅ `/calendar` - Upcoming Events
45 | Shows next 7 days of events
46 |
47 | ### ✅ `/month` - Monthly Calendar
48 | ASCII calendar + event list for current month
49 |
50 | ### ✅ `/today` - Today's Events
51 | Lists all events for today
52 |
53 | ### ✅ `/history` - Conversation History
54 | Shows recent conversations from this session
55 |
56 | ## How It Works Now
57 |
58 | ### Typing a Command
59 | ```
60 | You type: /stats
61 | ↓
62 | WebSocket detects "/" prefix
63 | ↓
64 | Calls handle_command("stats")
65 | ↓
66 | Returns JRVS system statistics
67 | ↓
68 | Displays in chat
69 | ```
70 |
71 | ### Clicking a Button
72 | ```
73 | You click: "📊 System Stats"
74 | ↓
75 | Calls quickCommand('/stats')
76 | ↓
77 | Sends "/stats" via WebSocket
78 | ↓
79 | Same flow as above
80 | ```
81 |
82 | ### Regular Chat
83 | ```
84 | You type: "What is Python?"
85 | ↓
86 | No "/" prefix
87 | ↓
88 | Goes to AI + MCP agent
89 | ↓
90 | Normal response
91 | ```
92 |
93 | ## Test It Now!
94 |
95 | ### Try These Commands:
96 |
97 | **In the chat:**
98 | ```
99 | /stats
100 | /help
101 | /models
102 | /mcp-servers
103 | /calendar
104 | /month
105 | /report
106 | ```
107 |
108 | **Or click the sidebar buttons:**
109 | - 📊 System Stats
110 | - 📚 Help & Commands
111 | - 🔌 Connected Servers
112 | - 📅 View Calendar
113 | - 📝 Activity Report
114 |
115 | ## What You'll See
116 |
117 | ### `/stats` now shows:
118 | ```
119 | JRVS System Statistics
120 |
121 | AI Model:
122 | • Current: gemma3:12b
123 | • Available: 12 Ollama models
124 |
125 | MCP Integration:
126 | • Connected Servers: 2
127 | • Servers: filesystem, memory
128 |
129 | RAG System:
130 | • Documents: X
131 | • Chunks: Y
132 | • Embeddings: Z
133 |
134 | Calendar:
135 | • Events in database: (check /calendar)
136 |
137 | Session:
138 | • Session ID: abc12345...
139 | • WebSocket: Connected ✓
140 | ```
141 |
142 | ### Instead of:
143 | ```
144 | ❌ General world population statistics
145 | ❌ CO2 emissions data
146 | ❌ Random facts
147 | ```
148 |
149 | ## All Commands Implemented
150 |
151 | ✅ `/help` - Command list
152 | ✅ `/stats` - System statistics
153 | ✅ `/models` - Ollama models
154 | ✅ `/mcp-servers` - MCP servers
155 | ✅ `/mcp-tools` - MCP tools
156 | ✅ `/report` - Activity report
157 | ✅ `/calendar` - Upcoming events
158 | ✅ `/month` - Monthly calendar
159 | ✅ `/today` - Today's events
160 | ✅ `/history` - Chat history
161 |
162 | ## Buttons Work Too!
163 |
164 | All sidebar buttons now send the correct commands:
165 | - 📚 Help & Commands → `/help`
166 | - 📊 System Stats → `/stats`
167 | - 📝 Activity Report → `/report`
168 | - 📅 View Calendar → Opens modal (special handling)
169 | - 📆 Today's Events → `/today`
170 | - 🔌 Connected Servers → Opens modal (special handling)
171 | - 🔧 Available Tools → Opens modal (special handling)
172 |
173 | ## Try It!
174 |
175 | ```bash
176 | ./start_web_server.sh
177 | ```
178 |
179 | Then:
180 | 1. Type `/stats` in chat
181 | 2. Or click "📊 System Stats" button
182 | 3. Get actual JRVS system information!
183 |
184 | **All commands now work correctly!** ✅
185 |
--------------------------------------------------------------------------------
/docs/WHATS_NEW.md:
--------------------------------------------------------------------------------
1 | # What's New in JRVS 🎉
2 |
3 | ## Recent Updates
4 |
5 | ### 🔌 MCP Client Integration (NEW!)
6 |
7 | JRVS can now **use external tools** by connecting to MCP servers! This is a game-changer.
8 |
9 | **What this means:**
10 | - JRVS was already an MCP **server** (others can use JRVS as a tool)
11 | - Now JRVS is also an MCP **client** (JRVS can use external tools)
12 | - Think of it like giving JRVS superpowers from other services!
13 |
14 | **Examples of what JRVS can now do:**
15 | - 📁 Read/write files on your system (via filesystem server)
16 | - 🐙 Create GitHub issues and PRs (via github server)
17 | - 🔍 Search the web (via brave-search server)
18 | - 💾 Access databases (via postgres/sqlite servers)
19 | - 📝 Keep persistent notes across sessions (via memory server)
20 | - 💬 Send Slack messages (via slack server)
21 |
22 | **Quick Start:**
23 | 1. Edit `mcp_gateway/client_config.json` to add servers
24 | 2. Start JRVS - it auto-connects
25 | 3. Use `/mcp-servers` and `/mcp-tools` to explore
26 | 4. Call tools with `/mcp-call `
27 |
28 | 📖 Full guide: [MCP_CLIENT_GUIDE.md](MCP_CLIENT_GUIDE.md)
29 |
30 | ---
31 |
32 | ### 📅 Smart Calendar with ASCII View
33 |
34 | **Interactive monthly calendar:**
35 | ```
36 | ╔══════════════════════════════════════════════════════════════╗
37 | ║ November 2025 ║
38 | ╠══════════════════════════════════════════════════════════════╣
39 | ║ Sun Mon Tue Wed Thu Fri Sat ║
40 | ╠══════════════════════════════════════════════════════════════╣
41 | ║ 2 3 4 5 6 7 8 ║
42 | ║ 9 10 [11] 12* 13 14 15 ║
43 | ║ 16 17 18 19 20 21 22 ║
44 | ║ 23 24 25 26 27 28 29 ║
45 | ║ 30 ║
46 | ╚══════════════════════════════════════════════════════════════╝
47 |
48 | Legend: [DD] = Today | DD* = Has Events | [DD]* = Today + Events
49 | ```
50 |
51 | **Natural language event creation:**
52 | - "add event study time tomorrow at 10 am"
53 | - "meeting with team today at 3pm"
54 | - "schedule dentist 2025-11-20 at 2:30 pm"
55 |
56 | **Commands:**
57 | - `/month` - Show current month calendar
58 | - `/month 12 2025` - Show specific month
59 | - `/calendar` - Upcoming events (7 days)
60 | - `/today` - Today's events
61 |
62 | ---
63 |
64 | ### 🎨 Enhanced CLI Experience
65 |
66 | **New commands:**
67 | - `/mcp-servers` - List connected MCP servers
68 | - `/mcp-tools` - Browse available tools
69 | - `/month` - ASCII calendar view
70 | - `/today` - Today's events
71 |
72 | **Improved help:**
73 | - Organized by category
74 | - Examples for complex commands
75 | - Tips for natural language features
76 |
77 | ---
78 |
79 | ## Previous Features
80 |
81 | ### 🧠 RAG Pipeline
82 | - FAISS vector search with BERT embeddings
83 | - Automatic context injection for better responses
84 | - Web scraping and document indexing
85 |
86 | ### 🔄 Dynamic Model Switching
87 | - Hot-swap between Ollama models
88 | - Multiple model support
89 | - No restart needed
90 |
91 | ### 🎨 Beautiful Themes
92 | - Matrix (green hacker style)
93 | - Cyberpunk (magenta/cyan)
94 | - Minimal (clean B&W)
95 |
96 | ### 💾 Persistent Storage
97 | - SQLite database for conversations
98 | - Document and embedding storage
99 | - Session history
100 |
101 | ### ⚡ Performance
102 | - Lazy loading
103 | - Async operations
104 | - Connection pooling
105 | - Caching
106 |
107 | ---
108 |
109 | ## Coming Soon
110 |
111 | - 🤖 AI-powered MCP tool selection (JRVS automatically picks the right tool)
112 | - 🗣️ Voice input/output
113 | - 🌐 Web UI alongside CLI
114 | - 📊 Analytics dashboard
115 | - 🔐 Better auth/security for MCP connections
116 | - 📱 Mobile companion app
117 |
118 | ---
119 |
120 | ## Migration Notes
121 |
122 | **For existing users:**
123 | - No breaking changes!
124 | - MCP client is optional - JRVS works fine without it
125 | - Calendar feature uses existing database
126 | - All old commands still work
127 |
128 | **New dependencies:**
129 | - MCP client libraries (already in requirements.txt)
130 | - Node.js (only if using MCP servers that need it)
131 |
132 | ---
133 |
134 | ## Support
135 |
136 | - 📖 Docs: See README.md and MCP_CLIENT_GUIDE.md
137 | - 🐛 Issues: Create an issue on GitHub
138 | - 💡 Ideas: Open a discussion
139 |
140 | Enjoy the new features! 🚀
141 |
--------------------------------------------------------------------------------
/docs/JARCORE_QUICKSTART.md:
--------------------------------------------------------------------------------
1 | # JARCORE Quick Start
2 |
3 | **JARCORE** = **J**ARVIS **A**utonomous **R**easoning & **C**oding **E**ngine
4 |
5 | ## 🚀 Quick Start
6 |
7 | ### 1. Make sure Ollama is running
8 |
9 | ```bash
10 | # Check Ollama
11 | curl http://localhost:11434/api/tags
12 |
13 | # Install a coding model if needed
14 | ollama pull deepseek-coder:6.7b
15 | ```
16 |
17 | ### 2. Run the Demo
18 |
19 | ```bash
20 | cd /home/xmanz/JRVS
21 | python3 demo_jarcore.py
22 | ```
23 |
24 | The demo shows all 8 JARCORE capabilities:
25 | - ✓ Code Generation
26 | - ✓ Code Analysis
27 | - ✓ Code Refactoring
28 | - ✓ Test Generation
29 | - ✓ Code Execution
30 | - ✓ Error Fixing
31 | - ✓ File Operations
32 | - ✓ Code Explanation
33 |
34 | ### 3. Use the CLI
35 |
36 | ```bash
37 | # Generate code
38 | python3 jarcore_cli.py generate "create a binary search function" -l python -o search.py
39 |
40 | # Analyze code for security issues
41 | python3 jarcore_cli.py analyze myfile.py --type security
42 |
43 | # Fix code errors
44 | python3 jarcore_cli.py fix broken.py "NameError: name 'x' is not defined" --write
45 |
46 | # Generate tests
47 | python3 jarcore_cli.py test mycode.py -o test_mycode.py
48 |
49 | # Explain code
50 | python3 jarcore_cli.py explain complex.py --detail detailed
51 |
52 | # Refactor code
53 | python3 jarcore_cli.py refactor messy.py --write
54 |
55 | # Run code
56 | python3 jarcore_cli.py run script.py
57 | ```
58 |
59 | ### 4. Use via MCP
60 |
61 | Add to your MCP client configuration:
62 |
63 | ```json
64 | {
65 | "mcpServers": {
66 | "jrvs": {
67 | "command": "python3",
68 | "args": ["/home/xmanz/JRVS/mcp_gateway/server.py"]
69 | }
70 | }
71 | }
72 | ```
73 |
74 | Then in your MCP client:
75 | ```
76 | > Use JARCORE to create a REST API for user authentication
77 | > Analyze this code for security issues
78 | > Fix the error in my Python script
79 | ```
80 |
81 | ### 5. Use in Python
82 |
83 | ```python
84 | import asyncio
85 | from mcp_gateway.coding_agent import jarcore
86 |
87 | async def main():
88 | # Generate code
89 | result = await jarcore.generate_code(
90 | task="Create a function to validate email addresses",
91 | language="python"
92 | )
93 | print(result["code"])
94 |
95 | # Analyze it
96 | analysis = await jarcore.analyze_code(
97 | code=result["code"],
98 | language="python",
99 | analysis_type="security"
100 | )
101 | print(analysis)
102 |
103 | asyncio.run(main())
104 | ```
105 |
106 | ## 🎯 Common Tasks
107 |
108 | ### Generate a complete module
109 | ```bash
110 | python3 jarcore_cli.py generate "Create a user authentication system with password hashing" \
111 | --language python \
112 | --tests \
113 | --output auth.py
114 | ```
115 |
116 | ### Debug and fix code
117 | ```bash
118 | # Run code and capture error
119 | python3 mycode.py 2> error.txt
120 |
121 | # Fix it
122 | python3 jarcore_cli.py fix mycode.py "$(cat error.txt)" --write
123 | ```
124 |
125 | ### Complete workflow
126 | ```bash
127 | # 1. Generate
128 | python3 jarcore_cli.py generate "REST API for TODO items" -l python -o api.py
129 |
130 | # 2. Analyze
131 | python3 jarcore_cli.py analyze api.py --type comprehensive
132 |
133 | # 3. Refactor if needed
134 | python3 jarcore_cli.py refactor api.py --write
135 |
136 | # 4. Generate tests
137 | python3 jarcore_cli.py test api.py -o test_api.py
138 |
139 | # 5. Run tests
140 | python3 jarcore_cli.py run test_api.py
141 | ```
142 |
143 | ## 📚 Documentation
144 |
145 | Full documentation: `docs/CODING_AGENT.md`
146 |
147 | ## 🔧 Troubleshooting
148 |
149 | **Ollama not responding:**
150 | ```bash
151 | systemctl status ollama
152 | # or
153 | ollama serve
154 | ```
155 |
156 | **Import errors:**
157 | ```bash
158 | cd /home/xmanz/JRVS
159 | pip install -r requirements.txt
160 | pip install rich # For CLI colors
161 | ```
162 |
163 | **Slow generation:**
164 | - Use smaller models (7B instead of 13B+)
165 | - Check `config.py` for model settings
166 |
167 | ## 🌟 Features
168 |
169 | - **100% Local** - All code runs on your machine
170 | - **Multi-Language** - Python, JS, Go, Rust, Java, C/C++, Bash
171 | - **Context-Aware** - Uses RAG for project understanding
172 | - **Safe Execution** - Sandboxed with timeout protection
173 | - **Auto-Backup** - Files backed up before editing
174 | - **Test Generation** - Automatic unit test creation
175 | - **Error Fixing** - AI-powered debugging
176 | - **Code Analysis** - Security, performance, style checks
177 |
178 | ## 🎓 Examples
179 |
180 | See `demo_jarcore.py` for comprehensive examples of all features.
181 |
182 | ---
183 |
184 | **JARCORE** - AI-Powered Coding with Local Ollama Models
185 |
--------------------------------------------------------------------------------
/docs/MCP_QUICKSTART.md:
--------------------------------------------------------------------------------
1 | # JRVS MCP Integration - Quick Start
2 |
3 | Your JRVS AI assistant now has full MCP (Model Context Protocol) support! 🚀
4 |
5 | ## What You Get
6 |
7 | Claude Code can now directly:
8 | - 🔍 Search your JRVS knowledge base semantically
9 | - 🌐 Scrape websites and add them to JRVS
10 | - 📅 Manage your calendar events
11 | - 🤖 Switch between Ollama models
12 | - 💬 Access conversation history
13 | - 📊 Get system statistics
14 |
15 | ## Installation (Already Done!)
16 |
17 | ✅ MCP server created at `mcp_gateway/server.py`
18 | ✅ 17 tools + 2 resources implemented
19 | ✅ Dependencies added to requirements.txt
20 | ✅ Test suite passed (4/4 components working)
21 |
22 | ## Usage
23 |
24 | ### Option 1: Test Locally First
25 |
26 | ```bash
27 | # Test components
28 | python mcp_gateway/test_server.py
29 |
30 | # Run server (will wait for stdio connection)
31 | python mcp_gateway/server.py
32 | ```
33 |
34 | ### Option 2: Connect to Claude Code
35 |
36 | **Edit your Claude Code MCP config** (`~/.config/claude/mcp_servers.json` or similar):
37 |
38 | ```json
39 | {
40 | "mcpServers": {
41 | "jrvs": {
42 | "command": "python",
43 | "args": ["/home/xmanz/JRVS/mcp_gateway/server.py"],
44 | "env": {
45 | "PYTHONPATH": "/home/xmanz/JRVS"
46 | }
47 | }
48 | }
49 | }
50 | ```
51 |
52 | **Then restart Claude Code.**
53 |
54 | ## Example Usage in Claude Code
55 |
56 | Once connected, you can ask:
57 |
58 | ```
59 | "Search JRVS for information about Python best practices"
60 | → Uses: search_knowledge_base(query="Python best practices")
61 |
62 | "Add https://docs.python.org to JRVS knowledge base"
63 | → Uses: scrape_and_index_url(url="https://docs.python.org")
64 |
65 | "What's on my calendar this week?"
66 | → Uses: get_calendar_events(days=7)
67 |
68 | "Switch JRVS to llama3.1 model"
69 | → Uses: switch_ollama_model(model_name="llama3.1")
70 |
71 | "Ask JRVS about machine learning with context"
72 | → Uses: generate_with_ollama(prompt="...", context=)
73 | ```
74 |
75 | ## Available Tools (17 total)
76 |
77 | ### 🧠 RAG & Knowledge Base
78 | - `search_knowledge_base` - Semantic vector search
79 | - `get_context_for_query` - Get enriched RAG context
80 | - `add_document_to_knowledge_base` - Index documents
81 | - `scrape_and_index_url` - Web scraping
82 | - `get_rag_stats` - System statistics
83 |
84 | ### 🤖 Ollama LLM
85 | - `list_ollama_models` - Available models
86 | - `get_current_model` - Current model info
87 | - `switch_ollama_model` - Change models
88 | - `generate_with_ollama` - Generate with RAG
89 |
90 | ### 📅 Calendar
91 | - `get_calendar_events` - Upcoming events
92 | - `get_today_events` - Today's schedule
93 | - `create_calendar_event` - New events
94 | - `delete_calendar_event` - Remove events
95 | - `mark_event_completed` - Complete events
96 |
97 | ### 💬 Conversation
98 | - `get_conversation_history` - Past conversations
99 |
100 | ### 📊 Resources (Read-Only)
101 | - `jrvs://config` - Configuration
102 | - `jrvs://status` - System status
103 |
104 | ## Test Results
105 |
106 | ```
107 | ✓ Database initialized
108 | ✓ RAG initialized (vectors: 0)
109 | ✓ Calendar initialized (0 events)
110 | ✓ Ollama connected (12 models)
111 | ```
112 |
113 | All systems ready!
114 |
115 | ## Next Steps
116 |
117 | 1. **Add Content**: Scrape some websites to build your knowledge base
118 | ```bash
119 | # Via CLI
120 | python main.py
121 | /scrape https://example.com
122 | ```
123 |
124 | 2. **Try MCP**: Connect Claude Code and start using JRVS tools
125 |
126 | 3. **Explore**: Check `MCP_SETUP.md` for detailed documentation
127 |
128 | ## Files Created
129 |
130 | ```
131 | mcp_gateway/
132 | ├── __init__.py # Package init
133 | ├── server.py # MCP server (17 tools)
134 | ├── test_server.py # Component tests
135 | ├── claude_config.json # Example config
136 | └── README.md # MCP gateway directory docs
137 |
138 | MCP_SETUP.md # Complete setup guide (this file)
139 | MCP_QUICKSTART.md # Quick reference
140 | ```
141 |
142 | ## Troubleshooting
143 |
144 | **"MCP package not found"**
145 | ```bash
146 | pip install 'mcp[cli]'
147 | ```
148 |
149 | **"Cannot connect to Ollama"**
150 | ```bash
151 | ollama serve
152 | ```
153 |
154 | **"Database not found"**
155 | ```bash
156 | python main.py # Run JRVS once to initialize
157 | ```
158 |
159 | ## Documentation
160 |
161 | - **Full Guide**: See `MCP_SETUP.md`
162 | - **MCP Gateway Dir**: See `mcp_gateway/README.md`
163 | - **JRVS Docs**: See `README.md`
164 | - **Official MCP**: https://modelcontextprotocol.io
165 |
166 | ---
167 |
168 | **Your JRVS is now MCP-enabled!** 🎉
169 |
170 | Use it with Claude Code to supercharge your AI workflows with persistent knowledge, RAG-enhanced responses, and calendar management.
171 |
--------------------------------------------------------------------------------
/setup_windows.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | REM JRVS Windows Setup Script
3 | REM This script installs and configures prerequisites for running JRVS on Windows
4 |
5 | echo ========================================
6 | echo JRVS Windows Setup Script
7 | echo ========================================
8 | echo.
9 |
10 | REM Check for Administrator privileges
11 | net session >nul 2>&1
12 | if %errorLevel% neq 0 (
13 | echo [WARNING] Not running as Administrator. Some installations may require elevated privileges.
14 | echo [INFO] Right-click this script and select "Run as administrator" if you encounter issues.
15 | echo.
16 | )
17 |
18 | REM Check Python installation
19 | echo [1/6] Checking Python installation...
20 | python --version >nul 2>&1
21 | if %errorLevel% neq 0 (
22 | echo [ERROR] Python is not installed or not in PATH.
23 | echo [INFO] Please install Python 3.8+ from https://python.org/downloads/
24 | echo [INFO] Make sure to check "Add Python to PATH" during installation.
25 | echo.
26 | pause
27 | exit /b 1
28 | ) else (
29 | for /f "tokens=*" %%i in ('python --version 2^>^&1') do set PYTHON_VERSION_STR=%%i
30 | echo [OK] %PYTHON_VERSION_STR% found
31 | )
32 | echo.
33 |
34 | REM Check pip installation
35 | echo [2/6] Checking pip installation...
36 | pip --version >nul 2>&1
37 | if %errorLevel% neq 0 (
38 | echo [ERROR] pip is not installed.
39 | echo [INFO] Installing pip...
40 | python -m ensurepip --upgrade
41 | ) else (
42 | echo [OK] pip is available
43 | )
44 | echo.
45 |
46 | REM Check Node.js installation (required for MCP servers)
47 | echo [3/6] Checking Node.js installation...
48 | node --version >nul 2>&1
49 | if %errorLevel% neq 0 (
50 | echo [WARNING] Node.js is not installed.
51 | echo [INFO] Node.js is required for MCP server functionality.
52 | echo [INFO] Please install Node.js from https://nodejs.org/
53 | echo.
54 | ) else (
55 | for /f "tokens=*" %%i in ('node --version 2^>^&1') do set NODE_VERSION=%%i
56 | echo [OK] Node.js %NODE_VERSION% found
57 | )
58 | echo.
59 |
60 | REM Install Python dependencies
61 | echo [4/6] Installing Python dependencies...
62 | if not exist requirements.txt (
63 | echo [ERROR] requirements.txt not found!
64 | echo [INFO] Make sure you are running this script from the JRVS directory.
65 | pause
66 | exit /b 1
67 | )
68 | echo [INFO] This may take a few minutes...
69 | pip install -r requirements.txt
70 | if %errorLevel% neq 0 (
71 | echo [ERROR] Failed to install Python dependencies.
72 | echo [INFO] Try running: pip install -r requirements.txt manually
73 | pause
74 | exit /b 1
75 | ) else (
76 | echo [OK] Python dependencies installed successfully
77 | )
78 | echo.
79 |
80 | REM Check for Ollama
81 | echo [5/6] Checking Ollama installation...
82 | ollama --version >nul 2>&1
83 | if %errorLevel% neq 0 (
84 | echo [WARNING] Ollama is not installed or not in PATH.
85 | echo [INFO] Ollama is required to run AI models locally.
86 | echo [INFO] Please install Ollama from https://ollama.ai/download
87 | echo.
88 | echo [INFO] After installing Ollama, run these commands to get started:
89 | echo ollama serve
90 | echo ollama pull llama3.1
91 | echo.
92 | ) else (
93 | echo [OK] Ollama is installed
94 | echo [INFO] Make sure Ollama is running with: ollama serve
95 | )
96 | echo.
97 |
98 | REM Install npm dependencies (if package.json exists)
99 | echo [6/6] Installing npm dependencies for frontend...
100 | if exist package.json (
101 | npm --version >nul 2>&1
102 | if %errorLevel% neq 0 (
103 | echo [WARNING] npm is not available. Skipping frontend dependencies.
104 | echo [INFO] Install Node.js to enable frontend features.
105 | ) else (
106 | npm install
107 | if %errorLevel% neq 0 (
108 | echo [WARNING] Failed to install npm dependencies.
109 | ) else (
110 | echo [OK] npm dependencies installed successfully
111 | )
112 | )
113 | ) else (
114 | echo [INFO] No package.json found. Skipping npm dependencies.
115 | )
116 | echo.
117 |
118 | REM Create data directory if it doesn't exist
119 | if not exist data mkdir data
120 | echo [OK] Data directory ready
121 | echo.
122 |
123 | echo ========================================
124 | echo Setup Complete!
125 | echo ========================================
126 | echo.
127 | echo Next steps:
128 | echo 1. Start Ollama: ollama serve
129 | echo 2. Pull a model: ollama pull llama3.1
130 | echo 3. Run JRVS: python main.py
131 | echo.
132 | echo For the web interface:
133 | echo 1. Start API: python api\server.py
134 | echo 2. Start frontend: npm run dev
135 | echo 3. Open browser: http://localhost:3000
136 | echo.
137 | echo See README.md for more information.
138 | echo.
139 | pause
140 |
--------------------------------------------------------------------------------
/docs/BRAVE_SEARCH_SETUP.md:
--------------------------------------------------------------------------------
1 | # Brave Search API Setup for JRVS
2 |
3 | This guide will help you enable web search capabilities in JRVS using the Brave Search API.
4 |
5 | ## Why Brave Search?
6 |
7 | - **Privacy-focused**: Brave doesn't track your searches
8 | - **Free tier**: 2,000 queries per month (plenty for personal use)
9 | - **Fast**: Direct API access without rate limiting issues
10 | - **Quality**: Brave has its own independent search index
11 |
12 | ## Step-by-Step Setup
13 |
14 | ### 1. Get Your Brave Search API Key
15 |
16 | 1. **Visit** https://brave.com/search/api/
17 | 2. **Sign up** for a free account or log in
18 | 3. **Subscribe** to the free tier (Data for AI):
19 | - Go to your dashboard
20 | - Select "Data for AI" plan
21 | - It's FREE for up to 2,000 queries/month
22 | 4. **Copy your API key** from the dashboard
23 |
24 | ### 2. Add API Key to JRVS
25 |
26 | 1. **Open** `mcp_gateway/client_config.json`
27 |
28 | 2. **Find** the brave-search config in `_disabled_servers`:
29 | ```json
30 | "brave-search": {
31 | "command": "npx",
32 | "args": ["-y", "@modelcontextprotocol/server-brave-search"],
33 | "env": {
34 | "BRAVE_API_KEY": "GET_YOUR_KEY_FROM_https://brave.com/search/api/"
35 | },
36 | "description": "Web search - DISABLED until you add your Brave API key"
37 | }
38 | ```
39 |
40 | 3. **Replace** `GET_YOUR_KEY_FROM_...` with your actual API key:
41 | ```json
42 | "BRAVE_API_KEY": "BSA1234567890abcdef..."
43 | ```
44 |
45 | 4. **Move** the entire brave-search config from `_disabled_servers` to `mcpServers`:
46 |
47 | **Before:**
48 | ```json
49 | {
50 | "mcpServers": {
51 | "filesystem": {...},
52 | "memory": {...}
53 | },
54 | "_disabled_servers": {
55 | "brave-search": {...} ← Move this
56 | }
57 | }
58 | ```
59 |
60 | **After:**
61 | ```json
62 | {
63 | "mcpServers": {
64 | "filesystem": {...},
65 | "memory": {...},
66 | "brave-search": {...} ← Now active!
67 | },
68 | "_disabled_servers": {}
69 | }
70 | ```
71 |
72 | ### 3. Restart JRVS
73 |
74 | ```bash
75 | python main.py
76 | ```
77 |
78 | You should see:
79 | ```
80 | Connected to 3 MCP server(s): filesystem, memory, brave-search
81 | ```
82 |
83 | ### 4. Test Web Search
84 |
85 | In JRVS, try:
86 |
87 | ```bash
88 | # List tools to confirm brave-search is connected
89 | /mcp-tools brave-search
90 |
91 | # Search the web
92 | /mcp-call brave-search brave_web_search '{"q": "Python async programming", "count": 5}'
93 |
94 | # Local business search
95 | /mcp-call brave-search brave_local_search '{"q": "pizza near me", "count": 3}'
96 | ```
97 |
98 | ## Usage Examples
99 |
100 | ### Web Search
101 | ```bash
102 | /mcp-call brave-search brave_web_search '{"q": "latest AI news", "count": 10}'
103 | ```
104 |
105 | Returns: Title, URL, description, and snippet for each result
106 |
107 | ### Local Search
108 | ```bash
109 | /mcp-call brave-search brave_local_search '{"q": "coffee shops in San Francisco", "count": 5}'
110 | ```
111 |
112 | Returns: Business name, address, phone, rating, hours
113 |
114 | ## API Limits
115 |
116 | **Free Tier (Data for AI):**
117 | - 2,000 queries/month
118 | - No credit card required
119 | - Rate limit: ~1 request/second
120 | - Perfect for personal JRVS usage
121 |
122 | **If you exceed the limit:**
123 | - Upgrade to paid plan (starts at $5/month for 15k queries)
124 | - Or wait until next month for free tier reset
125 |
126 | ## Monitoring Usage
127 |
128 | 1. Visit https://brave.com/search/api/dashboard
129 | 2. Check your usage stats
130 | 3. Set up alerts if needed
131 |
132 | ## Troubleshooting
133 |
134 | ### "API key invalid" error
135 | - Double-check your API key is correct
136 | - Make sure you're subscribed to the Data for AI plan
137 | - API key might take a few minutes to activate after signup
138 |
139 | ### Connection timeout
140 | - Check your internet connection
141 | - Brave API might be temporarily down (rare)
142 | - Try again in a few minutes
143 |
144 | ### No results returned
145 | - Check your search query format
146 | - Some queries might not return results
147 | - Try a more general search term
148 |
149 | ## Alternative: Use Without Brave Search
150 |
151 | JRVS works great without web search! You already have:
152 | - ✅ **Filesystem** - File operations
153 | - ✅ **Memory** - Persistent notes
154 | - ✅ **Web scraping** - Built-in scraper with `/scrape` command
155 | - ✅ **RAG** - Search your scraped documents
156 |
157 | The built-in web scraper can handle most needs:
158 | ```bash
159 | /scrape https://example.com
160 | /search "topic I'm interested in"
161 | ```
162 |
163 | ## Security Notes
164 |
165 | - **Keep your API key private** - Don't share it or commit to Git
166 | - API key is stored locally in `mcp_gateway/client_config.json`
167 | - Consider using environment variables for production use
168 | - Brave doesn't track or log your searches (privacy-focused)
169 |
170 | ## Additional Resources
171 |
172 | - [Brave Search API Docs](https://brave.com/search/api/)
173 | - [Brave Search API GitHub](https://github.com/brave/brave-search-api)
174 | - [MCP Brave Search Server](https://github.com/modelcontextprotocol/servers/tree/main/src/brave-search)
175 |
176 | ---
177 |
178 | **Ready to search!** 🔍 Once configured, JRVS can search the web on demand for real-time information.
179 |
--------------------------------------------------------------------------------
/cli/commands.py:
--------------------------------------------------------------------------------
1 | """Command handler for CLI interface"""
2 | import shlex
3 | from typing import List, Optional
4 | from .themes import theme
5 |
6 | class CommandHandler:
7 | def __init__(self, cli_instance):
8 | self.cli = cli_instance
9 |
10 | async def handle_command(self, command_line: str):
11 | """Parse and handle CLI commands"""
12 | try:
13 | args = shlex.split(command_line)
14 | if not args:
15 | return
16 |
17 | command = args[0].lower()
18 | command_args = args[1:] if len(args) > 1 else []
19 |
20 | # Route commands
21 | if command == "help":
22 | self.cli.show_help()
23 |
24 | elif command == "models":
25 | await self.cli.list_models()
26 |
27 | elif command == "model":
28 | if command_args:
29 | await self.cli.switch_model(command_args[0])
30 | else:
31 | await self.cli.list_models()
32 |
33 | elif command == "switch":
34 | if command_args:
35 | await self.cli.switch_model(command_args[0])
36 | else:
37 | theme.print_error("Usage: /switch ")
38 |
39 | elif command == "scrape":
40 | if command_args:
41 | await self.cli.scrape_url(command_args[0])
42 | else:
43 | theme.print_error("Usage: /scrape ")
44 |
45 | elif command == "search":
46 | if command_args:
47 | query = " ".join(command_args)
48 | await self.cli.search_documents(query)
49 | else:
50 | theme.print_error("Usage: /search ")
51 |
52 | elif command == "stats":
53 | await self.cli.show_stats()
54 |
55 | elif command == "history":
56 | limit = 5
57 | if command_args and command_args[0].isdigit():
58 | limit = int(command_args[0])
59 | self.cli.show_conversation_history(limit)
60 |
61 | elif command == "theme":
62 | if command_args:
63 | self.cli.set_theme(command_args[0])
64 | else:
65 | theme.print_error("Usage: /theme ")
66 | theme.print_info("Available themes: matrix, cyberpunk, minimal")
67 |
68 | elif command == "clear":
69 | theme.clear_screen()
70 | theme.print_banner()
71 |
72 | elif command == "calendar":
73 | await self.cli.show_calendar()
74 |
75 | elif command == "month":
76 | # /month or /month 11 2025
77 | month = None
78 | year = None
79 | if len(command_args) >= 1:
80 | month = int(command_args[0])
81 | if len(command_args) >= 2:
82 | year = int(command_args[1])
83 | await self.cli.show_month_calendar(month, year)
84 |
85 | elif command == "event":
86 | if len(command_args) >= 2:
87 | await self.cli.add_event(command_args)
88 | else:
89 | theme.print_error("Usage: /event