Sign inSign up

javdet/nib-kb

By javdet

•Updated 15 days ago

NIB knowledge base — pgvector-backed MCP server for semantic search over infrastructure docs

Image
Machine learning & AI
Developer tools
Databases & storage
0

2.9K

javdet/nib-kb repository overview

⁠NIB — knowledge base (MCP server)

Knowledge-base server for NIB (Neuro Infrastructure Builder), speaking the Model Context Protocol. It stores your infrastructure documentation in PostgreSQL with pgvector, embeds it through an OpenAI-compatible /embeddings endpoint, and answers semantic search queries from any MCP client — the NIB agent, or your own.

The point is specificity. A planning agent that knows the general shape of Kubernetes still cannot tell you which cluster your staging ingress lives on, which registry your images come from, or why that one service is pinned to an old node pool. This is where that knowledge goes, and how the agent retrieves it while planning.

It is one of four images: nib-kb (this one), nib-backend⁠ (API and agent orchestrator), nib-frontend⁠ (web UI) and nib-agent⁠ (the coding-agent runner).


⁠The MCP interface

The server exposes one tool:

knowledge_search — embeds a natural-language query and returns the closest kb_chunks rows from the named collection, by cosine similarity in pgvector.

ParameterTypeRequiredNotes
querystringyesNatural-language search text
collectionstringyeskb_collections.name
limitnumbernoMaximum hits, with a server-side cap

Two transports:

  • streamable HTTP — -transport http -http-addr :8081 -http-path /mcp (the image default), for clients that connect over the network. Add -http-stateless to run without session tracking.
  • stdio — -transport stdio, for a client that spawns the binary as a child process.

Inside NIB the agent reaches this over the internal network at http://kb-mcp:8081/mcp, registered as an MCP server in data/mcp.json. Alongside search, NIB agents read the current source document with get_kb_document and write a collection back with update_kb (those tools live in the backend); the build-knowledge-base skill drives the whole round trip — hand it a project name and a list of repositories and it fills the shipped skeleton in from what the repositories actually say, rather than from what someone remembered to write down last year.


⁠Quick start

docker run -d --name nib-kb \
  -p 8081:8081 \
  -e DATABASE_URL='postgres://nib:nib@postgres:5432/nib?sslmode=disable' \
  -e OPENROUTER_API_KEY="$LLM_API_KEY" \
  -e EMBEDDINGS_BASE_URL=https://api.openai.com/v1 \
  javdet/nib-kb:latest

MCP endpoint: http://<host>:8081/mcp. The database must have the pgvector extension available; the NIB backend creates and migrates the schema.

The whole stack comes up together with the repository's Compose file or Helm chart — see nib-backend⁠.


⁠Configuration

⁠Environment
VariablePurpose
DATABASE_URLPostgres DSN. Required unless you pass -dsn or a -config file with knowledge_base.uri
OPENROUTER_API_KEYAPI key for the embeddings endpoint when -provider openrouter
EMBEDDINGS_BASE_URLOpenAI-compatible API base, e.g. https://api.openai.com/v1 or https://openrouter.ai/api/v1
GOOGLE_API_KEY / GEMINI_API_KEYAPI key when -provider google
GOOGLE_API_BASE_URLGoogle Generative Language API base override
HTTP_REFERER / OPENROUTER_APP_TITLEOptional OpenRouter attribution headers

Despite the name, -provider openrouter is the CLI's label for any OpenAI-compatible /embeddings client — OpenAI itself, OpenRouter, or a self-hosted gateway. Point EMBEDDINGS_BASE_URL wherever you like. -provider google selects the Generative Language API instead.

⁠kb serve-mcp flags
FlagDefaultPurpose
-transportstdio (image overrides to http)stdio or http (streamable HTTP)
-http-addr:8081Listen address for -transport http
-http-path/mcpEndpoint path
-http-statelessoffServe streamable HTTP without session tracking
-dsn—Postgres DSN, overriding DATABASE_URL and config
-config—YAML config to read knowledge_base.uri from
-provideropenrouteropenrouter (OpenAI-compatible) or google — must match how the collection was ingested
-model—If set, every searched collection must use this embedding_model; otherwise the collection row supplies it
-timeout120sHTTP timeout for embedding requests
-embeddings-base-url—OpenAI-compatible base URL
-google-base-url—Google API base URL

The image's default command is:

kb serve-mcp -transport http -http-addr :8081 -http-path /mcp

Override it with command: in Compose or args: in Kubernetes.

Embedding models must match exactly. A collection records the model it was embedded with, and search compares that string against the model in use. Change the embedding model and the old collection stops matching — re-ingest it rather than expecting a silent migration.


⁠Ingesting documents

The same binary ingests. It chunks the input, embeds each chunk in batches, and writes kb_collections / kb_chunks:

docker run --rm -i \
  -e DATABASE_URL='postgres://nib:nib@postgres:5432/nib?sslmode=disable' \
  -e OPENROUTER_API_KEY="$LLM_API_KEY" \
  -e EMBEDDINGS_BASE_URL=https://api.openai.com/v1 \
  --entrypoint kb javdet/nib-kb:latest \
  ingest -collection myproject -model text-embedding-3-small -replace < runbook.md
FlagDefaultPurpose
-collection—Collection name (required)
-model—Embedding model id (required)
-chunk-size512Maximum runes per chunk
-chunk-overlap64Rune overlap between consecutive chunks, so a fact split across a boundary is still findable
-embed-batch32Texts per embedding API request
-insert-batch256Rows per database insert batch
-metriccosineDistance metric label stored on the collection
-replaceoffDelete existing chunks with the same source_uri before inserting — this is what makes re-ingest idempotent instead of duplicating

Files are passed as arguments, or the text is piped on stdin. In normal NIB use you do not run this by hand: the UI and the build-knowledge-base skill drive ingestion for you.


⁠Image contents

  • A single static Go binary (CGO_ENABLED=0) on gcr.io/distroless/static-debian12:nonroot.
  • Runs as nonroot:nonroot. No shell, no package manager, no busybox — the attack surface is the binary and nothing else. Worth knowing before you plan to docker exec into it: you cannot.
  • Ships CA certificates (HTTPS to the embedding provider), tzdata and a nonroot passwd entry.
  • Cross-compiled natively per target architecture, so the arm64 image is built without QEMU.
  • Exposes port 8081. No healthcheck is baked in — the MCP endpoint expects a protocol handshake rather than a plain GET, so probe it at the TCP level (a Kubernetes tcpSocket probe on 8081).

⁠Tags and platforms

latest · vX.Y.Z (release, matching the repository's VERSION file) · <git-sha> (exact commit). Built for linux/amd64 and linux/arm64.

Pin vX.Y.Z in production and keep backend, frontend and kb on the same tag — they are released together from one repository and share the database schema.


  • Source, documentation and issues: https://github.com/javdet/nib⁠
  • Knowledge-base documentation: docs/knowledgebase/ in the repository
  • Licence: Nib Non-Commercial License 1.0 (MIT-based, with attribution and a non-commercial-use restriction). Read LICENSE before deploying this in a commercial setting.

Tag summary

Content type

Image

Digest

sha256:fbab6d4d2…

Size

5.4 MB

Last updated

15 days ago

docker pull javdet/nib-kb