MCPInstall
documents-vector-search logo

documents-vector-search

by shnax0210 43 stars shnax0210/documents-vector-search

Project allows document indexing in vector database and then search. Supports Jira (a ticket is a document) and Confluence (a page is a document). Provides abstraction to add more sources. Supports MCP protocol to use the vector search as a tool in AI agents.

READMEmain

Local Vector Search for Jira, Confluence & Files (with MCP support)

Overview

Index documents from Jira, Confluence, or local files into a local vector database and search them. All data stays on your machine.

Key features:

  • Jira & Confluence (Server/Data Center and Cloud). Jira ticket = document, Confluence page = document
  • Local files (.pdf, .pptx, .docx, etc.) via Unstructured
  • No data sent to third parties (except when used as MCP with a remote AI agent)
  • Hybrid search: vector search + BM25 keyword search, merged by Reciprocal Rank Fusion
  • Incremental updates: no need to rebuild the full index each time
  • Filter results by metafields (space, project, date, etc.)
  • Ability to extend: add more data sources, search engines, embeddings, etc.

Technologies: SQLite (sqlite-vec and BM25), ChromaDB, sentence-transformers, Unstructured, LangChain

More context: Medium article

Contacts:

  • Like it? Please star the repo
  • Found a bug? Open an issue
  • Want to contribute? - feel free to do it via fork and sending a pull request
  • Want to chat? LinkedIn

Updates

  • Check UPDATES.md for major updates.
  • Some minor updates can be not added the file, so they can be found only in git history.

How it works

flowchart TD
    A[1. Create collection] -->|loads & indexes documents| B["Collection stored in ./data/collections/${name}"]
    B --> C{What next?}
    C --> D[2. Update collection]
    C --> E[3. Search via CLI]
    C --> F[4. Search via MCP]
    D -->|indexes only new/changed docs| B
    E -->|search| B
    F -->|search| B
  1. Create a collection — load and index documents from Jira, Confluence, or local files. Stored in ./data/collections/{name}
  2. Update — re-index only new or changed documents (much faster than full creation)
  3. Search — find documents by text query via CLI
  4. MCP — expose search as a tool for AI agents

Collection structure

graph TD
    A["./data/collections/${name}/"] --> B["documents/"]
    A --> C["indexes/"]
    A --> D["manifest.json"]
    B --- B1["Loaded and converted documents"]
    C --- C1["Vector and keyword index files"]
    D --- D1["Collection metadata: name, last update time, reader config, index list"]

See ./main/core/documents_collection_creator.py for creation/update details and ./main/core/documents_collection_searcher.py for search details.

Indexers configuration

When you create a collection, you can specify a list of indexers like: --indexers "indexer_SqlLiteVector__embeddings_sentence-transformers_slash_all-MiniLM-L6-v2", "indexer_SqlLiteBM25" (it's also the default value). The indexers define what vector/keyword databases and embedding models are used. Database and embedding model are separated by __. For example:

  • indexer_SqlLiteVector__embeddings_sentence-transformers_slash_all-MiniLM-L6-v2 means that SqlLite with sqlite-vec extension is used as vector database and sentence-transformers/all-MiniLM-L6-v2 is used as the embedding model. You can use any embedding model from next list, you only need to add prefix embeddings_ and replace slash symbols with _slash_. For example, if you want to use it with BAAI/bge-m3 embedder model, indexer name should be: indexer_SqlLiteVector__embeddings_BAAI_slash_bge-m3;
  • indexer_SqlLiteBM25 means that SqlLite BM25 is used as search engine.
  • indexer_ChromaDb__embeddings_sentence-transformers_slash_all-MiniLM-L6-v2 means that ChromaDb is used as vector database and sentence-transformers/all-MiniLM-L6-v2 is used as the embedding model. Embedding model names follow the same rules as for indexer_SqlLiteVector.

You can define as many indexers as you want, their search results will be combined by Reciprocal Rank Fusion.

Setup

Env setup

Either uv or docker can be used to run the project.

Local setup

  1. Clone the repository
  2. Install uv
  3. Run uv sync in the project root

Docker setup

A Dockerfile is included for running the tool without installing Python or uv locally.

Build the image:

docker build -t documents-vector-search .

Run any command by passing it as arguments and mounting a local data/ folder:

docker run --rm \
  -v $(pwd)/data:/app/data \
  -e CONF_TOKEN="${yourToken}" \
  documents-vector-search \
  uv run dvs.py create-confluence \
    --collection "confluence" \
    --url "${baseConfluenceUrl}" \
    --cql "${confluenceQuery}"
  • Mount -v $(pwd)/data:/app/data so collections and caches are persisted on your host machine
  • Pass credentials as -e ENV_VAR=value (see Authentication)
  • The data/ folder structure (collections/, caches/, local_file_input/) is created automatically inside the container

Run the unified MCP HTTP server with Docker:

docker run --rm \
  -p 8000:8000 \
  -v $(pwd)/data:/app/data \
  documents-vector-search \
  uv run dvs.py mcp --http --httpPort 8000

Then configure your MCP client to connect to http://localhost:8000/mcp.

Commands

All functionality is available through a single script:

uv run dvs.py <operation> [arguments]
OperationDescription
create-confluenceCreate a collection from Confluence pages
create-jiraCreate a collection from Jira tickets
create-filesCreate a collection from local files
updateRe-index new and changed documents of an existing collection
searchSearch in a collection from the command line
fetchFetch a document content from a collection by its id
mcpRun unified MCP server (all collections, stdio or HTTP)
mcp-singleRun MCP stdio server for a single collection

Every operation has its own arguments, each with a short and a long form (e.g. -c / --collection). Run uv run dvs.py <operation> --help to see all of them.

Authentication

Set environment variables before creating or updating Jira/Confluence collections (not needed for local files):

PlatformTypeEnvironment Variables
Confluence Server/DCBearer token (recommended)CONF_TOKEN
Confluence Server/DCLogin/PasswordCONF_LOGIN, CONF_PASSWORD
Confluence CloudEmail/API tokenATLASSIAN_EMAIL, ATLASSIAN_TOKEN (get token)
Jira Server/DCBearer token (recommended)JIRA_TOKEN
Jira Server/DCLogin/PasswordJIRA_LOGIN, JIRA_PASSWORD
Jira CloudEmail/API tokenATLASSIAN_EMAIL, ATLASSIAN_TOKEN (get token)

Cloud vs Server is auto-detected: URLs ending with .atlassian.net are treated as Cloud.

Create collection for Confluence

uv run dvs.py create-confluence \
  --collection "confluence" \
  --url "${baseConfluenceUrl}" \
  --cql "${confluenceQuery}"
  • --collection — name of the collection (used later for update/search). Data stored in ./data/collections/{name}
  • --url — Confluence base URL (e.g., https://confluence.example.com or https://your-domain.atlassian.net)
  • --cql — Confluence query, e.g., "(space = 'MySpace') AND (lastModified >= '2025-01-01')"

Create collection for Jira

uv run dvs.py create-jira \
  --collection "jira" \
  --url "${baseJiraUrl}" \
  --jql "${jiraQuery}"
  • --url — Jira base URL (e.g., https://jira.example.com or https://your-domain.atlassian.net)
  • --jql — Jira query, e.g., "project = MyProject AND created >= -183d"

Create collection for local files

uv run dvs.py create-files --basePath "${pathToFolder}"
  • Collection name defaults to the last folder name. Override with --collection {name}
  • Unreadable files are skipped by default. Use --failFast to stop on first error
  • Filter files with --includePatterns "regex1" "regex2" and --excludePatterns "regex1" "regex2"
  • Uses Unstructured for parsing. Some formats may need extra software

Update collection

uv run dvs.py update --collection "${collectionName}"

Search

uv run dvs.py search \
  --collection "${collectionName}" \
  --query "How to set up react project locally"
  • --includeMatchedChunksText — include matched text chunks in results
  • --filter — filter by metafields (see below)
  • --rrfK — RRF constant for multi-index fusion (default: 60)

Filtering by metafields

Works with ChromaDB, SQLite BM25 and SQLite Vector indexes.

Syntax:

field operator "value" and/or field operator "value"

Operators: =, !=, >, >=, <, <=. Use and / or to join conditions (mixing both is not supported).

Confluence metafields:

FieldDescription
spaceSpace key
createdAtPage creation date
createdByCreator email (lowercase)
lastModifiedAtLast update date

Examples:

--filter 'space = "SPACE_KEY"'
--filter 'space = "SPACE_KEY" and lastModifiedAt > "2026-01-01"'
--filter '(space = "SPACE_KEY1" or space = "SPACE_KEY2") and lastModifiedAt > "2026-01-01"'

Jira metafields:

FieldDescription
projectProject key
typeIssue type (Bug, Task, Story, ...)
statusStatus (Open, In Progress, Done, ...)
priorityPriority (High, Medium, Low, ...)
epicEpic or parent issue key
assigneeAssignee email (lowercase)
createdAtIssue creation date
createdByCreator email (lowercase)
lastModifiedAtLast update date

Examples:

--filter 'project = "PROJ"'
--filter 'project = "PROJ" and lastModifiedAt > "2026-01-01"'
--filter '(project = "PROJ1" or project = "PROJ2") and lastModifiedAt > "2026-01-01"'

Files metafields:

FieldDescription
createdAtFile creation date
lastModifiedAtLast modified date
folder1First subfolder of the file path
folder2Second subfolder of the file path
folderNNth subfolder of the file path (only present if path has N or more subfolders)

Examples:

--filter 'folder1 = "docs"'
--filter 'folder1 = "docs" and folder2 = "api"'
--filter '(folder2 = "api" or folder2 = "presentations") and lastModifiedAt > "2026-01-01"'

Fetch

uv run dvs.py fetch \
  --collection "${collectionName}" \
  --id "${documentId}"
  • --id — document ID to fetch (required)
  • --startLine / --endLine — line range to return (default: 1–200)
  • --format — output format: json, json_with_indent (default), or toon

Set up MCP

There are two MCP server operations:

OperationBest forKey differences
dvs.py mcpModern AI modelsAll collections in one server. AI model chooses collection, filter and number of chunks. Supports stdio and HTTP transport.
dvs.py mcp-singleSimpler AI models or restricted setupsOne collection per server. Collection, filter and other settings are hardcoded via CLI args. Stdio only.

Unified MCP (recommended)

Add to your MCP config (e.g., .vscode/mcp.json for VS Code + GitHub Copilot):

{
    "servers": {
        "dvs": {
            "type": "stdio",
            "command": "uv",
            "args": [
                "--directory", "${fullPathToRootProjectFolder}",
                "run", "dvs.py", "mcp"
            ]
        }
    }
}
  • All collections from ./data/collections/ are available automatically
  • Use --collections "name1" "name2" to limit which collections are exposed
  • Use --rrfK {number} to tune Reciprocal Rank Fusion behavior for multi-index search
  • Use --defaultNumberOfChunks {number} and --maxNumberOfChunks {number} to tune the number of text chunks returned by a single search

Or start as http server:

uv run dvs.py mcp --http --httpPort 8000

And setup mcp like:

{
    "servers": {
        "dvs": {
            "type": "http",
            "url": "http://localhost:8000/mcp",
        }
    }
}

Simple MCP

{
    "servers": {
        "search_${collectionName}": {
            "type": "stdio",
            "command": "uv",
            "args": [
                "--directory", "${fullPathToRootProjectFolder}",
                "run", "dvs.py", "mcp-single",
                "--collection", "${collectionName}"
            ]
        }
    }
}
  • Replace ${collectionName} and ${fullPathToRootProjectFolder} with real values
  • Use --maxNumberOfChunks {number} to control how many text chunks are returned (more = better search, but may exceed model context window)
  • Use --rrfK {number} to tune Reciprocal Rank Fusion behavior for multi-index search
  • Use --filter for metafield filtering (details)

Prompt examples:

  • "Find info about AI use cases, search on Confluence, include all used links"
  • "Find info about PDP carousel, search on Jira, include all used links"

Run unit tests

If you develop the tool, you can run unit tests:

uv run pytest

Good to know

  • Incremental updates — only new/changed documents are re-indexed. Uses lastModifiedDocumentTime from manifest.json (5 mins for Jira and Confluence buffer to avoid missing concurrent updates);
  • Caching — Jira/Confluence collection creation caches downloaded documents in ./data/caches/{hash}. Same parameters = same cache. If you need fresh data, either run an update after creation, or delete the cache folder manually;
  • there are more parameters in each operation, use uv run dvs.py <operation> --help to get more.

More Research & Data MCP servers

Similar servers from the same category.

WeatherXM PRO

weatherxm

Integrates with WeatherXM PRO APIs to provide access to hyperlocal weather data, historical observations, and forecast performance metrics for location-specific analysis and planning.

APICLI+6

Gralio

tymonte

Access 3+ million SaaS reviews, detailed pricing data, alternatives, ratings, funding information, growth metrics, user sentiment analysis, and functional feature data for over 30,000 software products.

Research & Data

Integrates with professional cryptocurrency data APIs from DefiLlama Pro, CoinGecko Pro, and Arkham Intelligence to provide real-time token prices, market data, blockchain analytics, and on-chain intelligence for crypto researchers and traders.

search

Enables semantic and keyword searches across Space Frontiers' library, telegram, and reddit databases through a FastAPI-based server with flexible authentication options.

databaseauthentication+1