confluence2md-mcp - MCP Server for confluence2md IndexesMCP server that exposes confluence2md-indexer search to any MCP-compatible AI client. Runs as a local stdio server, queries a SQLite index built from confluence2md exports, and returns ranked results with score metadata.
confluence2md Platformconfluence2md-mcp is the third step in a three-tool local Confluence knowledge pipeline. It wraps a SQLite index built by confluence2md-indexer (which indexes output from confluence2md) and serves it to AI clients via MCP. See docs/platform.md for the full architecture.
confluence2md metadata format — other formats are not supported| Variable | Required | Description |
|---|---|---|
CONFLUENCE_INDEX_DB | recommended | Path to the SQLite DB file. Falls back to confluence2md-index.db in the current working directory if unset. |
CONFLUENCE2MD_EMBEDDING_PROVIDER | optional | bow-local (default: local, offline, no API key), openai, or openai-compatible. |
CONFLUENCE2MD_EMBEDDING_MODEL | optional | Model id, for example text-embedding-3-small. |
CONFLUENCE2MD_EMBEDDING_DIM | optional | Vector dimension such as 1024. Part of the embedding identity. |
CONFLUENCE2MD_EMBEDDING_BASE_URL | optional | Endpoint for an openai-compatible provider. |
CONFLUENCE2MD_EMBEDDING_API_KEY_ENV | optional | Name of the variable that holds the API key (preferred over a literal key). |
CONFLUENCE2MD_EMBEDDING_API_KEY | optional | Literal API key. |
CONFLUENCE2MD_EMBEDDING_SKIP | optional | true disables the vector channel and leaves lexical search. |
The remaining CONFLUENCE2MD_EMBEDDING_* variables of the indexer are honoured too — AUTH_HEADER, AUTH_SCHEME, HEADERS, QUERY_PARAMS, DOCUMENT_PREFIX, QUERY_PREFIX, BATCH_SIZE, TIMEOUT, MAX_RETRIES — see the indexer's docs/embedding-providers.md.
The index and the query must agree on the embedding configuration. An index records the identity of the vectors it holds (
provider:variant@dimension, for examplebow-local:fnv1a@256), while a hybrid or vector query resolves its own identity from these variables. When the two differ, the query fails withembedding mismatch: ...instead of returning weak results; the tool error names both identities and how to fix it. Usemode: "lexical"to search without embeddings at all.
This server reads environment variables only. The indexer CLI additionally accepts a
config.yaml; if you indexed through a configuration file, export the equivalentCONFLUENCE2MD_EMBEDDING_*variables here so that both sides resolve the same provider.
This server links confluence2md-indexer v0.5.0, which reads document metadata columns that indexes built by earlier indexer versions do not have. Such indexes are not migrated in place, so rebuild once after upgrading:
confluence2md-indexer index ./output --rebuild
Querying an index built by an older indexer fails with a database error; rebuilding is the supported fix.
Download the binary for your platform from Releases and place it somewhere on your PATH.
Create or edit .vscode/mcp.json in your workspace:
{
"servers": {
"confluence2md": {
"type": "stdio",
"command": "confluence2md-mcp",
"args": [],
"env": {
"CONFLUENCE_INDEX_DB": "/path/to/confluence2md-index.db"
}
}
}
}
MCP: Add Serverin the Command Palette also works.
claude mcp add confluence2md \
confluence2md-mcp \
-e CONFLUENCE_INDEX_DB=/path/to/confluence2md-index.db
WSL note: Use the Linux binary, not the Windows .exe — the .exe does not inherit WSL environment variables. The DB path must be a native Linux path (e.g. /home/user/confluence2md-index.db), not /mnt/c/, to avoid SQLite locking issues on NTFS mounts.
Add to ~/.codex/config.json:
{
"mcpServers": {
"confluence2md": {
"command": "confluence2md-mcp",
"args": [],
"env": {
"CONFLUENCE_INDEX_DB": "/path/to/confluence2md-index.db"
}
}
}
}
confluence.searchSearch indexed Confluence content from a local SQLite DB.
| Argument | Required | Description |
|---|---|---|
query | ✓ | Search query text |
dbPath | Override DB path. Falls back to CONFLUENCE_INDEX_DB env var, then to confluence2md-index.db in the current working directory. | |
mode | hybrid (default) | lexical | vector | |
fusion | weighted (default) | rrf | |
alpha | Weighted fusion alpha [0..1], default 0.70 | |
rrfK | RRF k constant, default 60 | |
topK | Candidates to rank, default 10 | |
limit | Max results to return | |
offset | Result offset | |
candidateK | Candidates per retrieval channel, default 50 | |
expand | Context expansion chunk count | |
spaceKey | Filter by space key | |
pageId | Filter by page ID | |
fromDate | Lower bound YYYY-MM-DD | |
toDate | Upper bound YYYY-MM-DD | |
spaces | Filter by any of several space keys; wins over spaceKey | |
host | Filter by crawled site host | |
author | Creator or last modifier name, case-insensitive | |
createdBy | Creator name only | |
modifiedBy | Last modifier name only | |
depthMin / depthMax | Crawl depth bounds; depthMin: 1 excludes seed pages | |
seedOnly | Only the pages the crawl started from | |
hasAttachments | Only pages that carry at least one attachment | |
updatedSince | Modified within an age (30d, 2w, 12h) or after an absolute date (2026-01-01) | |
embeddingProvider | Override the provider for this call: bow-local | openai | openai-compatible | |
embeddingModel | Override the embedding model | |
embeddingDim | Override the embedding dimension | |
embeddingBaseURL | Override the embedding endpoint | |
embeddingApiKeyEnv | Name of the environment variable that holds the API key | |
embeddingAuthHeader / embeddingAuthScheme | Override the authentication header and scheme | |
embeddingSkip | Disable the vector channel for this call | |
embeddingDocumentPrefix / embeddingQueryPrefix | Text prefixes for asymmetric models |
Metadata filters apply to lexical, vector and hybrid retrieval alike. Arguments win over environment variables: the indexer fills only the embedding fields that the arguments leave unset, so embeddingModel overrides CONFLUENCE2MD_EMBEDDING_MODEL for that call. A literal API key is deliberately not an argument — it would travel through the client conversation and the server log — so set CONFLUENCE2MD_EMBEDDING_API_KEY or name another variable with embeddingApiKeyEnv.
Response fields:
| Field | Description |
|---|---|
schemaVersion | Schema version string for contract stability |
tool | Always "confluence.search" |
dbPath | Resolved DB path used for the query |
request | Echoed request parameters |
count | Number of results returned in this response |
total | Total ranked results before pagination |
results | Array of result objects with chunk text and score breakdown |
Failures are returned as tool errors that keep the indexer's message and add the fix when the cause is actionable: an embedding mismatch names both identities, a missing or vector-less index names the rebuild command, and a disabled vector channel points at CONFLUENCE2MD_EMBEDDING_SKIP. mode: "lexical" works without any embedding configuration.
confluence.list_spacesList the Confluence space keys the index contains, so a client can scope a search without knowing the keys in advance.
| Argument | Required | Description |
|---|---|---|
dbPath | Override DB path. Falls back to CONFLUENCE_INDEX_DB, then to confluence2md-index.db in the current working directory. |
Response fields: schemaVersion, tool, dbPath, count, and spaces — a sorted array of space key strings, empty when the index holds no spaces.
# Linux / macOS / WSL
go build -o bin/confluence2md-mcp .
# Windows
go build -o bin/confluence2md-mcp.exe .
# Cross-compile Linux binary from Windows
GOOS=linux GOARCH=amd64 go build -o bin/confluence2md-mcp-linux-amd64 .
If module downloads fail with
403, setGOPROXY=direct.
go test ./... -run TestMCPStdioSmoke -v
The suite also contains an offline end-to-end test: it installs the pinned indexer (go install ...@v0.5.0), builds an index from a temporary corpus with the default bow-local provider, and drives the server over stdio — checking the tool list, the space list, a search narrowed by space and the provider-mismatch error. It needs no API key or running service, and skips only when the indexer CLI cannot be installed.
Release builds stamp the binary through ldflags; the version is reported in the MCP initialize response and written to the startup log. An unstamped go build reports dev.
CONFLUENCE_INDEX_DB points to a built index containing the chunks_fts and embeddings tables.15 commits
Go
100.0%
confluence2md-mcp - MCP Server for confluence2md IndexesMCP server that exposes confluence2md-indexer search to any MCP-compatible AI client. Runs as a local stdio server, queries a SQLite index built from confluence2md exports, and returns ranked results with score metadata.
confluence2md Platformconfluence2md-mcp is the third step in a three-tool local Confluence knowledge pipeline. It wraps a SQLite index built by confluence2md-indexer (which indexes output from confluence2md) and serves it to AI clients via MCP. See docs/platform.md for the full architecture.
confluence2md metadata format — other formats are not supported| Variable | Required | Description |
|---|---|---|
CONFLUENCE_INDEX_DB | recommended | Path to the SQLite DB file. Falls back to confluence2md-index.db in the current working directory if unset. |
CONFLUENCE2MD_EMBEDDING_PROVIDER | optional | bow-local (default: local, offline, no API key), openai, or openai-compatible. |
CONFLUENCE2MD_EMBEDDING_MODEL | optional | Model id, for example text-embedding-3-small. |
CONFLUENCE2MD_EMBEDDING_DIM | optional | Vector dimension such as 1024. Part of the embedding identity. |
CONFLUENCE2MD_EMBEDDING_BASE_URL | optional | Endpoint for an openai-compatible provider. |
CONFLUENCE2MD_EMBEDDING_API_KEY_ENV | optional | Name of the variable that holds the API key (preferred over a literal key). |
CONFLUENCE2MD_EMBEDDING_API_KEY | optional | Literal API key. |
CONFLUENCE2MD_EMBEDDING_SKIP | optional | true disables the vector channel and leaves lexical search. |
The remaining CONFLUENCE2MD_EMBEDDING_* variables of the indexer are honoured too — AUTH_HEADER, AUTH_SCHEME, HEADERS, QUERY_PARAMS, DOCUMENT_PREFIX, QUERY_PREFIX, BATCH_SIZE, TIMEOUT, MAX_RETRIES — see the indexer's docs/embedding-providers.md.
The index and the query must agree on the embedding configuration. An index records the identity of the vectors it holds (
provider:variant@dimension, for examplebow-local:fnv1a@256), while a hybrid or vector query resolves its own identity from these variables. When the two differ, the query fails withembedding mismatch: ...instead of returning weak results; the tool error names both identities and how to fix it. Usemode: "lexical"to search without embeddings at all.
This server reads environment variables only. The indexer CLI additionally accepts a
config.yaml; if you indexed through a configuration file, export the equivalentCONFLUENCE2MD_EMBEDDING_*variables here so that both sides resolve the same provider.
This server links confluence2md-indexer v0.5.0, which reads document metadata columns that indexes built by earlier indexer versions do not have. Such indexes are not migrated in place, so rebuild once after upgrading:
confluence2md-indexer index ./output --rebuild
Querying an index built by an older indexer fails with a database error; rebuilding is the supported fix.
Download the binary for your platform from Releases and place it somewhere on your PATH.
Create or edit .vscode/mcp.json in your workspace:
{
"servers": {
"confluence2md": {
"type": "stdio",
"command": "confluence2md-mcp",
"args": [],
"env": {
"CONFLUENCE_INDEX_DB": "/path/to/confluence2md-index.db"
}
}
}
}
MCP: Add Serverin the Command Palette also works.
claude mcp add confluence2md \
confluence2md-mcp \
-e CONFLUENCE_INDEX_DB=/path/to/confluence2md-index.db
WSL note: Use the Linux binary, not the Windows .exe — the .exe does not inherit WSL environment variables. The DB path must be a native Linux path (e.g. /home/user/confluence2md-index.db), not /mnt/c/, to avoid SQLite locking issues on NTFS mounts.
Add to ~/.codex/config.json:
{
"mcpServers": {
"confluence2md": {
"command": "confluence2md-mcp",
"args": [],
"env": {
"CONFLUENCE_INDEX_DB": "/path/to/confluence2md-index.db"
}
}
}
}
confluence.searchSearch indexed Confluence content from a local SQLite DB.
| Argument | Required | Description |
|---|---|---|
query | ✓ | Search query text |
dbPath | Override DB path. Falls back to CONFLUENCE_INDEX_DB env var, then to confluence2md-index.db in the current working directory. | |
mode | hybrid (default) | lexical | vector | |
fusion | weighted (default) | rrf | |
alpha | Weighted fusion alpha [0..1], default 0.70 | |
rrfK | RRF k constant, default 60 | |
topK | Candidates to rank, default 10 | |
limit | Max results to return | |
offset | Result offset | |
candidateK | Candidates per retrieval channel, default 50 | |
expand | Context expansion chunk count | |
spaceKey | Filter by space key | |
pageId | Filter by page ID | |
fromDate | Lower bound YYYY-MM-DD | |
toDate | Upper bound YYYY-MM-DD | |
spaces | Filter by any of several space keys; wins over spaceKey | |
host | Filter by crawled site host | |
author | Creator or last modifier name, case-insensitive | |
createdBy | Creator name only | |
modifiedBy | Last modifier name only | |
depthMin / depthMax | Crawl depth bounds; depthMin: 1 excludes seed pages | |
seedOnly | Only the pages the crawl started from | |
hasAttachments | Only pages that carry at least one attachment | |
updatedSince | Modified within an age (30d, 2w, 12h) or after an absolute date (2026-01-01) | |
embeddingProvider | Override the provider for this call: bow-local | openai | openai-compatible | |
embeddingModel | Override the embedding model | |
embeddingDim | Override the embedding dimension | |
embeddingBaseURL | Override the embedding endpoint | |
embeddingApiKeyEnv | Name of the environment variable that holds the API key | |
embeddingAuthHeader / embeddingAuthScheme | Override the authentication header and scheme | |
embeddingSkip | Disable the vector channel for this call | |
embeddingDocumentPrefix / embeddingQueryPrefix | Text prefixes for asymmetric models |
Metadata filters apply to lexical, vector and hybrid retrieval alike. Arguments win over environment variables: the indexer fills only the embedding fields that the arguments leave unset, so embeddingModel overrides CONFLUENCE2MD_EMBEDDING_MODEL for that call. A literal API key is deliberately not an argument — it would travel through the client conversation and the server log — so set CONFLUENCE2MD_EMBEDDING_API_KEY or name another variable with embeddingApiKeyEnv.
Response fields:
| Field | Description |
|---|---|
schemaVersion | Schema version string for contract stability |
tool | Always "confluence.search" |
dbPath | Resolved DB path used for the query |
request | Echoed request parameters |
count | Number of results returned in this response |
total | Total ranked results before pagination |
results | Array of result objects with chunk text and score breakdown |
Failures are returned as tool errors that keep the indexer's message and add the fix when the cause is actionable: an embedding mismatch names both identities, a missing or vector-less index names the rebuild command, and a disabled vector channel points at CONFLUENCE2MD_EMBEDDING_SKIP. mode: "lexical" works without any embedding configuration.
confluence.list_spacesList the Confluence space keys the index contains, so a client can scope a search without knowing the keys in advance.
| Argument | Required | Description |
|---|---|---|
dbPath | Override DB path. Falls back to CONFLUENCE_INDEX_DB, then to confluence2md-index.db in the current working directory. |
Response fields: schemaVersion, tool, dbPath, count, and spaces — a sorted array of space key strings, empty when the index holds no spaces.
# Linux / macOS / WSL
go build -o bin/confluence2md-mcp .
# Windows
go build -o bin/confluence2md-mcp.exe .
# Cross-compile Linux binary from Windows
GOOS=linux GOARCH=amd64 go build -o bin/confluence2md-mcp-linux-amd64 .
If module downloads fail with
403, setGOPROXY=direct.
go test ./... -run TestMCPStdioSmoke -v
The suite also contains an offline end-to-end test: it installs the pinned indexer (go install ...@v0.5.0), builds an index from a temporary corpus with the default bow-local provider, and drives the server over stdio — checking the tool list, the space list, a search narrowed by space and the provider-mismatch error. It needs no API key or running service, and skips only when the indexer CLI cannot be installed.
Release builds stamp the binary through ldflags; the version is reported in the MCP initialize response and written to the startup log. An unstamped go build reports dev.
CONFLUENCE_INDEX_DB points to a built index containing the chunks_fts and embeddings tables.15 commits
Go
100.0%