Become a member!

MCP Firebird: find and fix your Firebird database's problems by talking to your AI

๐ŸŒ
This article is also available in other languages:
๐Ÿ‡ฎ๐Ÿ‡น Italiano  โ€ข  ๐Ÿ‡ช๐Ÿ‡ธ Espaรฑol  โ€ข  ๐Ÿ‡ฉ๐Ÿ‡ช Deutsch  โ€ข  ๐Ÿ‡ง๐Ÿ‡ท Portuguรชs

MCP Firebird is an MCP server that lets your AI assistant really diagnose a Firebird database: execution plans, index advice, schema audits, transaction health. Version 0.2.4 is out, free for internal use, tested from Firebird 2.5 to 5.0.

Logo of MCP Firebird, the MCP server that lets AI assistants diagnose Firebird databases.

A query is slow. The plan says CUSTOMERS NATURAL, and on the filtered column an index does exist. Do you see the trap?

The index is INACTIVE. At this point almost all advice, human or AI, tells you to create a new index. Follow it and you end up with two indexes on the same column, both written on every INSERT, one of them dead. The real fix was one ALTER INDEX ... ACTIVE away, and nobody told you.

MCP Firebird tells you. It’s an MCP server that lets your AI assistant (Claude, Gemini CLI, Cursor, anything that speaks MCP) really diagnose a Firebird database: read the schema, explain an execution plan, propose an index, refuse to propose one that already exists, and measure afterwards whether a goal was met. Today I released version 0.2.4.

In short

  • What it is: an MCP stdio server, a single Windows executable written in Delphi, that turns your AI assistant into a working Firebird DBA.
  • Who it is for: anyone running Firebird 2.5, 3.0, 4.0 or 5.0 in production who wants answers about plans, indexes and schema health instead of guesses.
  • Works with: Claude Desktop, Claude Code, Gemini CLI, OpenCode, Cursor and any MCP client.
  • Install: unzip, copy .env.example to .env, point it at your database, register the exe as a stdio server.
  • License: PolyForm Internal Use, free for your company’s internal operations at any scale. Source on GitHub.

What it does

Nine tools, all read-only: fb_info, fb_list_tables, fb_generate_documentation, fb_analyze_query, fb_suggest_indexes, fb_suggest_index_drops, fb_audit_table, fb_evaluate_goal, fb_monitor_transactions. Every finding carries a runnable remedy and a way to verify that the remedy actually worked, because a report you can’t act on is just a longer way of saying “the database is slow”.

Two design choices matter more than the feature list.

It’s tested on Firebird 2.5, 3.0, 4.0 and 5.0, not just the latest version. The full suite runs on all four engines before every release. The versions behave differently: different defaults, different features. A tool tested only on 5.0 gives wrong answers on a 2.5 server, and many companies still run 2.5 in production.

It doesn’t make answers up. If your SQL contains an error, you get the engine’s error message back, not an empty report that looks like a green light. And when it can’t measure something, it tells you: so you always know whether “no problems found” means the database is fine or the tool couldn’t look.

What a work session looks like

A real session against the suite’s test database, engine Firebird 5.0.4. This is how it looks in Claude Desktop:

A real session in Claude Desktop: asked why a Firebird query is slow, the assistant shows the plan PLAN (CUSTOMERS NATURAL), finds the inactive index IDX_CUST_CITY and proposes ALTER INDEX ACTIVE instead of a second index.

The screenshot above is a single moment of that session. Below we walk through the whole of it, question after question, from the first look at the database to the verified fix.

๐Ÿ‘ค You: I've never seen this database. Document the CUSTOMERS table for me.
๐Ÿค– Assistant: Here is CUSTOMERS: four columns, primary key on CUSTOMER_ID, five indexes. One thing stands out: IDX_CUST_CITY on the CITY column is INACTIVE. It exists, but the engine cannot use it. The report from fb_generate_documentation:
CUSTOMERS
Primary key: CUSTOMER_ID

| Column      | Type         | Nullable |
| CUSTOMER_ID | INTEGER      | no       |
| NAME        | VARCHAR(400) | no       |
| CITY        | VARCHAR(240) | yes      |
| STATUS      | CHAR(4)      | yes      |

Indexes:
- IDX_CUST_CITY (CITY), INACTIVE
- IDX_CUST_NAME (NAME)
- IDX_CUST_NAME_CITY (NAME, CITY)
- IDX_CUST_STATUS (STATUS)
- RDB$PRIMARY1 (CUSTOMER_ID) [PRIMARY KEY]
๐Ÿ‘ค You: Why is this query slow? SELECT * FROM CUSTOMERS WHERE CITY = 'Rome'
๐Ÿค– Assistant: Because the engine reads the whole table, row by row. The plan from fb_analyze_query is PLAN (CUSTOMERS NATURAL): no index is used for the filter on CITY.
๐Ÿ‘ค You: So which index should I create?
๐Ÿค– Assistant: None. CITY already has an index, IDX_CUST_CITY; it is just disabled. Creating a second one would double the write cost on every INSERT for nothing. Reactivate the one you have with ALTER INDEX IDX_CUST_CITY ACTIVE; and then re-check the plan. The finding from fb_suggest_indexes says exactly this:
ALTER INDEX IDX_CUST_CITY ACTIVE;

๐Ÿ“ This is the answer most advice gets wrong, human or AI: it would have told you to create a second index.

๐Ÿ‘ค You: I ran the ALTER INDEX. Did it actually work?
๐Ÿค– Assistant: Yes, and I can prove it. Before the fix the goal "no full scan" was missed; now it is met and the plan uses IDX_CUST_CITY. The two measurements from fb_evaluate_goal:
before:  goal missed    plan: PLAN (CUSTOMERS NATURAL)
after:   goal met       plan: PLAN (CUSTOMERS INDEX (IDX_CUST_CITY))
๐Ÿ‘ค You: The customer lookup must stay under 50 milliseconds.
๐Ÿค– Assistant: It does, with plenty of margin: fb_evaluate_goal measures 1.85 milliseconds against your 50.
๐Ÿ‘ค You: While we're at it, is there anything else to clean up?
๐Ÿค– Assistant: Three things. On ORDERS there is a duplicate index to drop: it costs a write on every INSERT and gives nothing back. Two indexes on CUSTOMERS have stale statistics, so the optimizer plans on wrong numbers: fix them with SET STATISTICS INDEX. Transactions and sweep are fine. The reports:
DROP INDEX IDX_ORDERS_CUSTOMER_DUP;
SET STATISTICS INDEX IDX_CUST_NAME;
SET STATISTICS INDEX IDX_CUST_STATUS;
Every answer has the same shape: what is wrong, the statement that fixes it, and how to verify the fix landed.

Install in two minutes

Nothing runs as a service and nothing listens on a port: your agent starts the executable and talks to it over stdin/stdout.

  1. Unzip the latest stable release wherever you like.
  2. Copy .env.example to .env beside the exe and fill in host, database, credentials.
  3. Point firebird.client_lib at the fbclient.dll of your Firebird installation. No client library is bundled, on purpose: only you know which server you’re talking to.
  4. Register MCPFirebird.exe in your agent as a stdio MCP server. The README has the exact recipe for each client, in English, Italian, Spanish and German.

The Enterprise edition

The free edition connects to your database with an ordinary SQL connection. It sees what the database knows about itself: schema, execution plans, indexes, transactions. That is already useful, but it stays inside the database.

The Enterprise edition is a paid product: it is only used with a license, always, including inside your company for internal use. There is no free tier of the Enterprise edition. It also connects to the Firebird server as an administrator, through the Services Manager. This way it sees what only the server knows: the configuration files (firebird.conf and databases.conf), the server log (firebird.log), the physical structure of the file, the hardware it runs on and the real workload. Nothing was removed from the free edition: the Enterprise tools stay in its list, and if the assistant calls one it gets a message explaining how to obtain it.

With this access the assistant answers questions it could not before. fb_diagnose is the starting point when something is wrong and you do not know where to begin. fb_analyze_config checks every firebird.conf parameter against your engine version and your architecture, because the defaults change between versions. fb_parse_log reads firebird.log and finds corruption, bugchecks, sweeps that never ran. fb_analyze_storage shows the physical structure: index depth, page fill, record-version chains. fb_analyze_host compares the hardware with the configuration: RAM against the configured cache, cores against parallel workers. fb_capture_trace records 60 seconds of real load and ranks the most expensive queries; fb_trace_start, fb_trace_status and fb_trace_stop do the same for up to two hours, in the background.

Why it is worth the money: the Firebird documentation does not tell you which value to use for most parameters, because the right value depends on your workload. The Enterprise edition works by measurement. It records performance under real load, you change a single parameter, it measures again and tells you whether it improved. If it did not, you roll it back.

Free vs Enterprise

Free Enterprise
Engine version, architecture and capabilities (fb_info) โœ… โœ…
List of the tables (fb_list_tables) โœ… โœ…
Schema documentation: columns, keys, indexes (fb_generate_documentation) โœ… โœ…
Execution plan analysis for a query (fb_analyze_query) โœ… โœ…
Advice on indexes to create or reactivate (fb_suggest_indexes) โœ… โœ…
Duplicate or useless indexes to drop (fb_suggest_index_drops) โœ… โœ…
Table check: missing keys, stale statistics, too many indexes (fb_audit_table) โœ… โœ…
Goal verification: plan without full scans, or a time limit (fb_evaluate_goal) โœ… โœ…
Transaction and sweep status (fb_monitor_transactions) โœ… โœ…
Guided diagnosis path (fb_diagnose) โŒ โœ…
firebird.conf and databases.conf checked for your version and architecture (fb_analyze_config) โŒ โœ…
Physical structure: index depth, page fill, record-version chains (fb_analyze_storage) โŒ โœ…
firebird.log reading: corruption, bugchecks, sweeps that never ran (fb_parse_log) โŒ โœ…
Real workload recording: 60 seconds (fb_capture_trace) or up to 2 hours in background (fb_trace_start/status/stop) โŒ โœ…
Hardware against configuration: RAM vs cache, cores vs parallel workers (fb_analyze_host) โŒ โœ…
Before/after measurements of a change, with a verdict โŒ โœ…

Enterprise licenses and support: professionals@bittime.it.

When you need to buy a license, and when you don’t

The free edition ships under the PolyForm Internal Use license: source available, free for the internal operations of you and your company, at any scale, in any industry, consulting included. The whole rule fits in one sentence: ask where the software ends up, never what you did with it. As long as every copy stays in your hands, you owe nobody anything, wherever the software runs and whatever database it examines. You need the commercial license the moment a copy stays with someone else: you leave it installed at a client’s when the engagement ends, you put it inside a product you sell, or you offer it as a service.

Your situation License needed?
Your DBA runs it against the production database every morning No.
Forty developers each run it locally No. No seat count, no registration.
You’re a consultant, you run it from your laptop against the client’s database and bill for your time No. It’s your tool, and it stays yours.
You leave a copy installed on the client’s server when the engagement ends Yes. The software left your hands.
You ship it inside your ERP so your customers get “AI database tuning” Yes. That’s embedding it in a product.
You give your hosting customers a button that runs it for them Yes. That’s offering it as a service.
You write a post, a talk or a course about it No. Read it, quote it, teach it.

One clarification worth making well: the commercial redistribution license and the Enterprise edition are two different products. One lets copies of MCP Firebird leave your hands; the other adds the server-administration tools you read about above, and it is always paid, with its own license, for anyone and any use. Buying one does not include the other.

Commercial licenses: professionals@bittime.it.

Try it

Download the latest stable release, point it at a copy of your database and ask your assistant why your slowest query is slow.

What’s the first question you’d ask your database?

Comments

comments powered by Disqus