Skip to main content
Glama
RanneG

linkup-mcp

by RanneG

Cursor Linkup MCP Server

Custom MCP (Model Context Protocol) server for Cursor IDE with:

  • 🌐 Web Search - Deep web searches using Linkup API

  • πŸ“š RAG (Retrieval Augmented Generation) - Query documents using LlamaIndex with Ollama

✨ Key Features

  • βœ… Local AI - Uses Ollama (llama3.2) for complete privacy

  • βœ… Zero API Costs - RAG tool is completely free (uses local models)

  • βœ… Source Citations - Know where answers come from

  • βœ… Multiple Document Types - Supports PDF, DOCX, MD, TXT, and more

  • βœ… Cursor Integration - Works seamlessly in Cursor IDE

Related MCP server: Web Search MCP

πŸ“‹ Prerequisites

  • Python 3.12+

  • uv package manager

  • Ollama installed locally with llama3.2 model

  • Linkup API key (optional, only for web search)

πŸš€ Quick Start

1. Clone & Install Dependencies

git clone https://github.com/RanneG/linkup_mcp.git
cd linkup_mcp
uv sync

Default install (uv sync / pip install -e .) is Cursor MCP + RAG only (lighter venv). For stitch_rag_bridge.py, face/OAuth/Gmail, and server-side voice STT, add --extra stitch-bridge. For ElevenLabs voice/music asset generation (elevenlabs-gen CLI), add --extra elevenlabs β€” see docs/elevenlabs/README.md.

2. Install Ollama & Model

# Download from https://ollama.ai/download
# Then pull the model:
ollama pull llama3.2

3. Configure Environment (Optional)

Create a .env file for web search (RAG works without API keys):

LINKUP_API_KEY=your_linkup_api_key  # Optional, for web_search tool

4. Configure Cursor

Add to ~/.cursor/mcp.json (or C:\Users\<username>\.cursor\mcp.json on Windows):

{
  "mcpServers": {
    "linkup-server": {
      "command": "C:\\Users\\YOUR_USERNAME\\AppData\\Local\\Microsoft\\WindowsApps\\python.exe",
      "args": [
        "-m", "uv", "run",
        "--directory", "C:\\path\\to\\linkup_mcp",
        "python", "server.py"
      ]
    }
  }
}

Replace YOUR_USERNAME and path with your actual values.

5. Free local dev ports (optional)

If 8765 (Stitch bridge / bundled UI), 1420 (Tauri), or 5173 (Vite) are stuck after a crash, run Close-DevPorts.bat at the repo root (or .\scripts\Close-StitchDevPorts.ps1). Use -DryRun to list listeners without killing. This stops processes listening on those ports, not β€œlocalhost” itself.

6. Restart Cursor & Use!

In Cursor's chat:

  • "Use the rag tool to tell me about [topic]"

  • "Use the rag_stitch tool to get a UI-ready answer payload"

  • "Search the web for [query]" (requires Linkup API key)

  • Local Whisper (no Linkup): whisper_stt_status then transcribe_wav_file with a path to a .wav file. Requires pip install -e ".[stitch-whisper]" and a Cursor MCP restart.

7. Voice-to-prompt hotkey tool (offline)

Use voice_prompt_tool.py for one-shot dictation directly into your coding flow:

uv sync --extra stitch-whisper --extra voice-prompt
python voice_prompt_tool.py --hotkey ctrl+shift+v

What it does:

  • global start/stop hotkey for microphone capture

  • local faster-whisper transcription (offline)

  • file reference extraction (auth.ts -> @auth.ts)

  • prompt envelope copied to clipboard:

    • [FILE REFERENCE: ...]

    • [TASK: ...]

Optional direct paste after copy:

python voice_prompt_tool.py --autopaste

πŸ“š Using the RAG Tool

Add documents to the data/ folder:

data/
β”œβ”€β”€ document1.pdf
β”œβ”€β”€ notes.md
└── research/
    └── paper.pdf

Supported: PDF, DOCX, TXT, MD, HTML, and more.

Stitch-style response shape

The rag tool now returns a JSON string with:

  • answer: final synthesized answer text

  • confidence: low, medium, or high

  • fallback: true when evidence is weak/insufficient

  • sources: ranked source snippets (source_id, score, snippet)

The rag_stitch tool returns a UI-oriented JSON string:

  • state: answered or fallback

  • answer

  • confidence (low, medium, or high)

  • source_cards (empty when state is fallback so the UI stays clean)

  • show_sources (false on fallback)

  • debug_retrieval_cards (only when STITCH_RAG_DEBUG=1 and fallback β€” raw top chunks for debugging)

Repository split (Stitch production)

The Stitch desktop app (React + Tauri) is migrating to RanneG/stitch-app; linkup_mcp remains the MCP server and HTTP bridge for local RAG, OAuth, subscriptions, face, and in-app help. Cutover checklist and file inventory: docs/stitch/MIGRATION.md (see docs/stitch/README.md).

stitch-api-types (TypeScript)

NPM workspace packages/stitch-api-types publishes .d.ts for POST /api/rag/stitch, POST /api/rag/stitch-help, GET /api/health, and related payloads. Build from repo root: npm run build:stitch-api-types. stitch-app can depend on it with a file: path (see stitch-app docs/BACKEND.md).

Stitch HTTP bridge (for the Stitch desktop app)

Run a small Flask server that exposes the same payload as rag_stitch, plus optional local face verification (/api/face/*, DeepFace + OpenCV liveness β€” see face_verification/). Requires stitch-bridge extras:

uv sync --extra stitch-bridge
.\.venv\Scripts\python.exe stitch_rag_bridge.py

Then point the Stitch app’s Vite dev proxy at http://127.0.0.1:8765 (see stitch-app docs/BACKEND.md or integrations/stitch/README.md; proxy /api for RAG, face, auth, subscriptions, and help routes).

Who needs what: Anyone can run the Stitch UI from stitch-app with Node (see docs/RUNNING.md). linkup_mcp is required for /api/* backend capabilities (auth, data, RAG, face, server-backed Help).

Develop Stitch UI from this repo (optional)

Root scripts npm run dev:browser, npm run dev:desktop, npm run build:stitch-web, npm run build:stitch-app use scripts/run-stitch-ui.mjs, which resolves STITCH_APP_ROOT or sibling ../stitch-app only. See docs/stitch/MIGRATION.md.

Stitch single-window GUI

The canonical bundled flow now starts from stitch-app (Stitch.bat there). It uses this repo for backend bridge capabilities when needed.

  1. Build the Stitch desktop bundle inside stitch-app (npm run build).

  2. Run Stitch.bat from stitch-app root.

  3. Keep this repo available for the bridge runtime (stitch_rag_bridge.py) on 127.0.0.1:8765.

Stitch as a native desktop app (no long manual command chain)

Stitch’s apps/desktop package uses Tauri for a real windowed app (npm run dev there = tauri dev). Run these from stitch-app:

Goal

What to do

One double-click (bridge + sync + Tauri)

Run Stitch-Desktop.bat in the stitch-app repo root.

Same from a terminal

npm run dev (stitch-app)

Bridge already running

Start Stitch from stitch-app and keep this repo bridge on 127.0.0.1:8765

Tauri only (you start the bridge yourself)

npm run dev:desktop

Browser tab only (no Tauri)

npm run dev:browser (uses stitch-app via run-stitch-ui.mjs)

Packaged .exe / installer

npm run build:stitch-app (after Tauri prerequisites and a stitch-app clone)

You need Node on PATH and a local stitch-app clone (sibling ../stitch-app or STITCH_APP_ROOT). The first Tauri dev run may compile Rust dependencies (one-time wait).

Quick regression run

To run the v1 prompt suite against your local PDF corpus:

python rag_regression.py

This prints each response payload and a small summary (sourced count, fallback count, low-confidence count).

Stitch JSON contract tests

python -m unittest tests.test_rag_stitch_contract -v

Validates rag_stitch_contract._to_stitch_view shapes (answered vs fallback, show_sources, optional debug_retrieval_cards).

If MCP-security prompts fall back, add the MCP landscape paper to data/:

πŸ› οΈ Project Structure

linkup_mcp/
β”œβ”€β”€ server.py             # MCP entrypoint (stdio) β€” all MCP tools live here
β”œβ”€β”€ agents.py             # spawn_agent sub-agent system (Ollama)
β”œβ”€β”€ rag.py                # RAGWorkflow (LlamaIndex + Ollama)
β”œβ”€β”€ rag_heuristics.py     # Pure scoring heuristics (unit-tested, no LLM imports)
β”œβ”€β”€ rag_runtime.py        # Lazy shared RAG index (MCP + bridge)
β”œβ”€β”€ rag_stitch_contract.py  # Stitch view JSON contract + guide-grounded help
β”œβ”€β”€ local_whisper_stt.py  # faster-whisper loader/transcribe (MCP + bridge share it)
β”œβ”€β”€ stitch_rag_bridge.py  # HTTP bridge ENTRYPOINT β€” owns Flask app, registers bridge/
β”œβ”€β”€ bridge/               # Bridge route modules (one per concern)
β”‚   β”œβ”€β”€ rag_routes.py     #   /api/rag/stitch, /api/rag/stitch-help, /api/stitch-user-guide
β”‚   β”œβ”€β”€ voice_routes.py   #   /api/voice/transcribe + STT engine selection
β”‚   β”œβ”€β”€ face_routes.py    #   /api/face/* (DeepFace imports deferred)
β”‚   β”œβ”€β”€ health.py         #   /health + /api/health (shared payload)
β”‚   β”œβ”€β”€ spa.py            #   /, /favicon.ico, optional built-SPA serving
β”‚   β”œβ”€β”€ cors.py           #   STITCH_ALLOWED_ORIGINS handling
β”‚   └── errors.py         #   JSON error handler for /api/face|auth|subscriptions
β”œβ”€β”€ stitch_auth/          # Google OAuth (PKCE), sessions, subscriptions SQLite
β”œβ”€β”€ face_verification/    # Local 1:1 face match + liveness (used by bridge)
β”œβ”€β”€ integrations/stitch/  # Pointer README β€” UI lives in stitch-app repo
β”œβ”€β”€ docs/                 # e.g. stitch_user_guide.md (bridge Help / Ask Stitch)
β”œβ”€β”€ data/                 # Your documents
β”œβ”€β”€ tests/                # Contract + unit tests (see CI commands below)
β”œβ”€β”€ pyproject.toml        # Dependencies + extras
β”œβ”€β”€ .cursorrules          # AI context for Cursor
└── .env                  # Environment variables (create this)

Where to add things

Change

Where

New MCP tool

server.py (@mcp.tool()); shared logic in a root module

New bridge HTTP route

New/existing module in bridge/ (Flask blueprint), register in stitch_rag_bridge.py

Auth / subscriptions route

stitch_auth/flask_routes.py

RAG scoring/threshold tweak

rag_heuristics.py (pure, unit-tested) or per-instance attrs on RAGWorkflow

Bridge JSON shape change

rag_stitch_contract.py and packages/stitch-api-types (keep in sync, bump that package)

stitch_rag_bridge.py must keep exporting app and register_stitch_spa_routes β€” stitch-app's stitch_gui.py imports them by name.

Test matrix

# Default profile (uv sync):
python -m unittest tests.test_rag_stitch_contract tests.test_rag_heuristics -v

# With stitch-bridge extra:
python -m unittest tests.test_face_storage tests.test_bridge_routes tests.test_stitch_auth_helpers -v

πŸ”§ How It Works

Cursor IDE β†’ MCP Server (server.py)
                 ↓
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚  RAG Tool   β”‚  Web Searchβ”‚
    β”‚  (rag.py)   β”‚  (Linkup)  β”‚
    β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           ↓
    Ollama (llama3.2) - runs locally

πŸ’° Cost

Tool

Cost

RAG

$0 (local Ollama)

Web Search

~$10-50/month (Linkup API)

Ollama

$0 (runs locally)

πŸ› Troubleshooting

MCP server not loading?

  1. Check Ollama is running: ollama list

  2. Verify path in mcp.json

  3. Check Cursor logs: %APPDATA%\Cursor\logs\

Ollama connection refused?

ollama serve

πŸ” Privacy

  • βœ… RAG Tool: 100% local, documents never leave your machine

  • βœ… Ollama: Runs locally, no cloud API calls

  • ⚠️ Web Search: Queries sent to Linkup servers

Repository

Purpose

chatbot-rag-core

Reusable Python RAG library

chatbot-api-server

Production Docker API server

πŸŽ“ Resources

πŸ“ License

MIT License - See LICENSE

πŸ™ Credits


Made with ❀️ for Cursor IDE users

F
license - not found
-
quality - not tested
B
maintenance

Maintenance

–Maintainers
–Response time
–Release cycle
–Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/RanneG/linkup_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server