Skip to content

feat(mcp): SQLite-backed MCP server config storage + boot merge (#6021)#6106

Merged
houko merged 9 commits into
mainfrom
feat/mcp-db-config
Jun 15, 2026
Merged

feat(mcp): SQLite-backed MCP server config storage + boot merge (#6021)#6106
houko merged 9 commits into
mainfrom
feat/mcp-db-config

Conversation

@houko

@houko houko commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Bounded storage slice of #6021 — SQLite-backed MCP server configuration, so config.toml can be a read-only ConfigMap on Kubernetes and MCP servers can be managed in the database.

The codebase already has a mature SQLite substrate (a migration ladder + per-table stores sharing one r2d2 pool), so this extends that pattern rather than introducing new infra.

Change

  • Migration v43 (migration.rs): SCHEMA_VERSION 42 → 43; migrate_v43 creates mcp_server_configs(name TEXT PK, entry_json TEXT NOT NULL, created_at, updated_at) + an audit row. The full McpServerConfigEntry is stored as one JSON blob so the table tracks the struct without a per-field schema migration.
  • McpConfigStore (new librefang-memory/src/mcp_config_store.rs): upsert / get / load_all / delete / count over the shared pool. upsert uses ON CONFLICT(name) DO UPDATE so created_at survives and updated_at refreshes; load_all is ordered by name for a deterministic boot merge. 6 unit tests.
  • Boot merge (kernel/boot.rs): loads DB MCP configs and overlays them over the file-backed [[mcp_servers]] by name (DB overrides file; DB-only names appended; empty table is a byte-for-byte no-op so file-only setups are unchanged). On store error it logs warn! and continues with the file config — the DB is an augmentation, not a hard boot dependency.

Scope / deferred (follow-ups)

  • Rewire the API write-path (POST /api/mcp/servers) and the CLI (librefang mcp add/rm) onto McpConfigStore — needs a DB-vs-file write toggle (e.g. [mcp] storage = "db") so K8s deployments opt into DB writes.
  • Surface DB entries in config_reload / reload_mcp_servers for hot-reload (boot-time load only for now).
  • A one-time config.toml → DB import path.

Test plan

  • cargo test -p librefang-memory mcp_config_store
  • cargo test -p librefang-memory migration
  • cargo build -p librefang-kernel && cargo clippy -p librefang-memory -p librefang-kernel -- -D warnings

Refs #6021 (storage + boot-merge slice; API/CLI wiring is a follow-up).

Bounded storage slice of #6021. Adds migration v43 (mcp_server_configs table), an McpConfigStore CRUD layer in librefang-memory over the shared r2d2 pool, and a boot-time merge that overlays DB rows over the file-backed [[mcp_servers]] by name (DB overrides file; empty table is a byte-for-byte no-op so file-only setups are unchanged). Lets config.toml be a read-only ConfigMap on K8s. API/CLI write-path, hot-reload, and a file->DB import are scoped follow-ups.
@github-actions github-actions Bot added area/docs Documentation and guides area/kernel Core kernel (scheduling, RBAC, workflows) size/L 250-999 lines changed labels Jun 14, 2026
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 14, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
librefang-deploy 3554183 Jun 14 2026, 10:43 PM

@github-actions github-actions Bot added the ready-for-review PR is ready for maintainer review label Jun 14, 2026
CHANGELOG bullet for #6021 was 6 sentences on a single line; split to
one sentence per line per the prose-wrapping rule.

Multi-line comment blocks in boot.rs (9 lines), migration.rs (6 lines),
and mcp_config_store.rs (module doc 20 lines + four multi-paragraph
method docs) compressed to one short line each per project rule.
No behaviour change.

@houko houko left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pushed one style commit (5939a56): CHANGELOG bullet split to one sentence per line, and multi-paragraph comment blocks in boot.rs, migration.rs, and mcp_config_store.rs compressed to one line each per project rules.
One finding left as a review comment: the boot-merge loop in boot.rs has no direct test (see inline note).


Generated by Claude Code

@github-actions github-actions Bot added has-conflicts PR has merge conflicts that need resolution and removed ready-for-review PR is ready for maintainer review labels Jun 14, 2026
@github-actions github-actions Bot added ready-for-review PR is ready for maintainer review and removed has-conflicts PR has merge conflicts that need resolution labels Jun 15, 2026
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying librefang-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: 110f0ca
Status: ✅  Deploy successful!
Preview URL: https://45e82abd.librefang-docs.pages.dev
Branch Preview URL: https://feat-mcp-db-config.librefang-docs.pages.dev

View logs

@houko
houko merged commit f4c3eec into main Jun 15, 2026
32 checks passed
@houko
houko deleted the feat/mcp-db-config branch June 15, 2026 05:29
houko added a commit that referenced this pull request Jun 15, 2026
…ime_store (#6113) (#6115)

* feat(mcp): persist /api/mcp/servers writes to a DB store via mcp_runtime_store

#6106 added the SQLite mcp_server_configs store and a boot-time merge, but the API write-path (POST/PUT/DELETE /api/mcp/servers, the taint patch) and the read-path still only saw config.toml.
A DB-managed MCP server was therefore invisible to the API and could not be added at all when config.toml was a read-only Kubernetes ConfigMap — the #6021 motivation.

Add a `mcp_runtime_store` knob (default `file`, byte-for-byte the prior behaviour; `db` routes writes to the store).
The boot overlay and reload_mcp_servers now share one McpConfigStore::merge_over helper, so the hot-reload path no longer drops DB-backed servers the boot merge had applied.
The handlers read the effective (file + DB) set, so DB-backed servers are listed, fetched, updated, and deleted like file-backed ones and take effect without a restart.

Tests: McpConfigStore::merge_over unit tests and the mcp_runtime_store_db_test API integration suite.

Closes #6113.

* test(config-overlay): exclude mcp_runtime_store from the ConfigPage overlay audit

The new mcp_runtime_store field is MCP-domain config surfaced on the dedicated /mcp-servers page (like mcp_servers itself), not the general ConfigPage, so every_kernel_config_struct_field_is_exposed_via_overlay must list it in EXCLUDED.

---------

Co-authored-by: Evan <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/docs Documentation and guides area/kernel Core kernel (scheduling, RBAC, workflows) ready-for-review PR is ready for maintainer review size/L 250-999 lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants