Skip to content

Custom store ​

1. Implement the store ​

Implement read and replace for your backend: a database, object bucket or internal service.

ts
import { CatalogConflictError, type CatalogStore } from "@havesomecode/kibana-mcp-server/config";

export default function myStore(options: { table: string }): CatalogStore {
  return {
    // serialized catalog of the profile, or undefined when it has none yet
    read: async (profileKey) => db.get(options.table, profileKey),
    // write only if the stored content is still `expected`, else throw CatalogConflictError
    replace: async (profileKey, expected, next, signal) => {
      signal?.throwIfAborted();
      if (!(await db.compareAndSet(options.table, profileKey, expected, next))) {
        throw new CatalogConflictError(profileKey);
      }
    },
    describe: (profileKey) => `db://${options.table}/${profileKey}`,
    close: () => db.close(),
  };
}

Contract ​

MethodRequiredRole
read(profileKey)yesReturns the serialized catalog of the profile, or undefined when it has none yet.
replace(profileKey, expected, next, signal?)yesWrites next only if the stored content is still expected (undefined when there was none). Throws CatalogConflictError otherwise. Checks the optional AbortSignal before issuing a write.
describe(profileKey)noHuman-readable location reported by tools. Must not expose credentials.
close()noReleases connections when the server stops.

The server derives profileKey from the profile name using only lowercase letters, digits and dashes: safe for file names, keys and primary keys.

Check the optional cancellation signal after any wait and before issuing a write. Cancellation never rolls back an already-dispatched write.

Require compare-and-set ​

configure_index reads, validates against Kibana, then writes. Concurrent callers/processes must fail with a conflict if content changed, not erase another writer's source. Retry the operation after a conflict.

2. Configure the store ​

Pass the store and its required options to the configuration file:

ts
import { defineKibanaMcpConfig } from "@havesomecode/kibana-mcp-server/config";
import myStore from "./my-store.js";

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

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