Skip to content

PostgreSQL store ​

1. Install the driver ​

bash
npm install pg

2. Configure the store ​

PostgreSQL keeps one row per profile:

ts
import { defineKibanaMcpConfig } from "@havesomecode/kibana-mcp-server/config";
import store from "@havesomecode/kibana-mcp-server/stores/postgres";

export default defineKibanaMcpConfig({
  url: process.env.KIBANA_URL,
  user: process.env.KIBANA_USER,
  password: process.env.KIBANA_PASSWORD,
  store,
  storeOptions: { url: process.env.DATABASE_URL, table: "ops.kibana_catalogs" },
});

Options ​

OptionDefaultDescription
urlKIBANA_STORE_URL, then DATABASE_URLpostgres:// or postgresql:// URL
tablekibana_mcp_catalogsTable name, optionally schema-qualified. Letters, digits and underscores only.
createTabletrueSet to false when your own migrations create the table
clientnoneA pg Pool or Client you configured yourself. The store never closes it.

Table ​

Created on startup unless createTable is false:

sql
CREATE TABLE IF NOT EXISTS kibana_mcp_catalogs (
  profile_key TEXT PRIMARY KEY,
  content     TEXT NOT NULL,
  updated_at  TIMESTAMPTZ NOT NULL DEFAULT now()
);

Grant the database user SELECT, INSERT and UPDATE on the table, plus schema CREATE if the store creates it.

How writes are protected ​

New catalogs use ON CONFLICT DO NOTHING; existing ones update only WHERE content = <what was read>. No changed row reports a conflict.

Released under the MIT License. Independent project, not affiliated with or endorsed by Elastic. Kibana and Elasticsearch are trademarks of Elasticsearch B.V.