Pod

Available as Markdown and JSON. Pod is also available over MCP.

Reported issues for IBM Db2 for i

Pod holds 23 of 61 GitHub reports that passed its relevance review. This can include external user reports, maintainer-confirmed bugs, and concrete feature gaps. Treat them as evidence to inspect, not a count of distinct defects.

Back to IBM Db2 for i.

Most discussed

Project Bob Security Review of mcp-server-db2i

Security Review Report: mcp-server-db2i

Executive Summary

This MCP server for IBM DB2i has good security practices overall, with comprehensive SQL injection protection and rate limiting. However, there are several critical security concerns that need immediate attention.


🔴 Critical Issues

1. Credential Exposure in Docker Compose

File: docker-compose.yml

Read the thread · 2026-01-17 · closed · external user · 9 comments

Add list_source_members and read_source_member for RPG and CL source

Problem Statement

The catalog tools tell an agent what the tables and columns are, but not what the data means. On an IBM i ERP most business rules live in RPG and CL programs. That includes what a status code means, how a price is derived, and which program writes a table. The API, ETL, and ad-hoc analysis use cases in docs/use-cases.md all eventually need that answer, and today the agent cannot get it from this server.

Reading a source member with execute_query is possible but…

Read the thread · 2026-09-24 · open · outside contributor · 2 comments

Error when building docker

Bug Description

I building the docker file and getting this error:

mcp-server-db2i git:(main) docker build -t mcp-server-db2i .
[+] Building 125.3s (21/25)                                    docker:default
 => [internal] load build definition from Dockerfile                     0.0s
 => => transferring dockerfile: 2.83kB                                   0.0s
 => resolve image config for docker-image://docker.io/docker/dockerfile  3.1s
 => [auth] docker/dockerfile:pull token for…

[Read the thread](https://github.com/Strom-Capital/mcp-server-db2i/issues/24) · 2026-02-13 · closed · external user · 2 comments

### Return BLOB and FOR BIT DATA columns as hex on every driver

## Problem Statement

The same binary value comes back as different text depending on `DB2I_DRIVER`. Found while fixing #163 (PR #165), with `execute_query` against a real IBM i:

```sql
SELECT CAST(X'0AFF' AS BINARY(2)) AS B2,
       CAST(X'C1C2' AS CHAR(2) FOR BIT DATA) AS FBD,
       BLOB(X'0102') AS BL
FROM SYSIBM.SYSDUMMY1
Column odbc (after #165) jt400 mapepire
B2 (BINARY) "0AFF" "0AFF" "0AFF"
FBD…

Read the thread · 2026-09-26 · closed · outside contributor · 1 comment

Return Db2's reason when PARSE_STATEMENT cannot parse a statement

Problem Statement

#116 adds sqlstate, sqlcode, cause and recovery to errors when Db2 rejects a statement. With the parse check on, which is the default (QUERY_PARSE_CHECK), a syntax error never gets that far. QSYS2.PARSE_STATEMENT returns no rows for a statement it cannot parse, and the tools answer with a generic message:

The statement could not be parsed. Fix the SQL, or set QUERY_PARSE_CHECK=false to skip this check.

That affects execute_query, YAML tools (on…

Read the thread · 2026-09-25 · open · outside contributor · 1 comment

Add explain_query with Visual Explain on the Mapepire driver

Problem Statement

An agent cannot tell, before it runs a statement, whether the statement will scan a large table. validate_query checks syntax and names. index_advice (#111) shows what the optimizer asked for in the past, not the plan for the statement at hand. On a production ERP, finding out by running the query is expensive, and see #114 for what happens when it runs too long.

Mapepire has a Visual Explain request (dove). In mapepire-js it is `SQLJob.explain(statement,…

Read the thread · 2026-09-24 · open · outside contributor · 1 comment

Stop long-running queries on IBM i with a query timeout

Problem Statement

Only the Mapepire driver limits how long a statement can run (requestTimeout, default 120 seconds, after which the pool closes the job). The ODBC driver, the default, and the JT400 driver have no limit.

A SELECT that scans a large ERP table, or joins on columns without an index, runs until it finishes. It holds a pool connection and CPU on the IBM i long after the client has given up. For an agent writing ad-hoc SQL, this is the most likely way to hurt a production…

Read the thread · 2026-09-24 · closed · outside contributor · 1 comment

Add index_advice from the IBM i index advisor

Problem Statement

Agents that write extract queries for a BI pipeline, or SQL behind a REST endpoint, cannot tell whether that SQL will scan a large ERP table. The IBM i index advisor already records this. QSYS2.SYSIXADV lists the indexes the query optimizer wanted, how often, and whether it built a temporary index (MTI) to make do.

Reading it through execute_query works, but the raw view is misleading for an agent:

Read the thread · 2026-09-24 · closed · outside contributor · 1 comment

Most recent

Let the server say which system it is: title and instructions for the assistant

Problem Statement

An AI assistant decides which tools to use from what the server tells it: the server's name, its description, and the tool descriptions. This server always introduces itself as mcp-server-db2i, and it sends no instructions. The model knows it can query "Db2 for i", but not that this is the company's ERP.

So a question like "which customers have overdue invoices?" may never reach the server unless the user mentions it by name. The user thinks of "the ERP", "the order…

Read the thread · 2026-09-26 · open · outside contributor · 0 comments

Localize the OAuth sign-in page

Problem Statement

The OAuth sign-in page (src/auth/oauth.ts) is English only: the heading, the labels, the button, the note and every error message. The people who see it are a company's employees, many of whom work in another language every day. A Finnish, Swedish or German finance team asked for their IBM i password on an English page is more likely to hesitate, or to get an error they can't read ("Sign-in failed. Check the user and password.").

Proposed Solution

| Variable |…

Read the thread · 2026-09-26 · open · outside contributor · 0 comments

Customize the OAuth sign-in page: name, logo, heading, colors, fonts and labels

Problem Statement

The OAuth sign-in page (src/auth/oauth.ts) always shows the db2i/mcp logo, the heading "Sign in to IBM i" and the project's colors. The people who see it are a company's own employees, sent there from claude.ai, Claude for Excel or another client, and asked for their IBM i password.

They don't know the project. What makes them trust the page is recognizing their own company: its name, its logo, its colors. A generic page that asks for a system password looks more like…

Read the thread · 2026-09-26 · open · outside contributor · 0 comments

Schema allowlist refuses queries with Db2 special registers such as CURRENT DATE

Problem Statement

With QUERY_ALLOWED_SCHEMAS set, execute_query refuses valid Db2 for i queries that use a special register such as CURRENT DATE, CURRENT TIMESTAMP or CURRENT USER:

The query could not be parsed, so its libraries could not be checked (near line 1: "AS U FROM SYSIBM.SYSDUMMY1")

The schema allowlist check (checkQuerySchemas in src/utils/security/schemaAllowlist.ts) parses a copy of the SQL with node-sql-parser. Neither the db2 nor the mysql dialect reads…

Read the thread · 2026-09-26 · closed · outside contributor · 0 comments

Keep OAuth refresh grants across server restarts

Problem Statement

With MCP_OAUTH_ENABLED, refresh grants live only in memory. Every restart of the server, and every rebuilt Docker image, signs out every OAuth user. Connectors such as claude.ai then need a manual reconnect.

Client registrations already survive, because client IDs are signed with MCP_OAUTH_SECRET. The rest of the in-memory state does not need to:

Read the thread · 2026-09-26 · closed · outside contributor · 0 comments

Numeric columns come back as numbers or strings depending on the driver

Problem Statement

The same numeric value comes back as a JSON number on one driver and a string on another. Found while checking #170 on a real IBM i with execute_query and the default JDBC options:

SELECT CAST('1.50' AS DECIMAL(31,2)) AS DEC_SMALL,
       CAST(7 AS BIGINT) AS BI,
       CAST('0.1' AS DECFLOAT(16)) AS DF_SMALL,
       CAST('1234567890.123456789012345678' AS DECFLOAT(34)) AS DF_WIDE
FROM SYSIBM.SYSDUMMY1

| Column | odbc | jt400 | mapepire |…

Read the thread · 2026-09-26 · open · outside contributor · 0 comments

Schema allowlist rejects CCSID casts and NVARCHAR with a misleading message

Problem Statement

While QUERY_ALLOWED_SCHEMAS is set, every statement is parsed with node-sql-parser to find its libraries (src/utils/security/schemaAllowlist.ts), and a statement the parser cannot read is rejected. The parser does not know some common Db2 for i syntax, so valid read-only queries fail:

SELECT CAST(NOTE AS VARCHAR(60) CCSID 1208) FROM MYLIB.ORDERHDR
SELECT CAST(NOTE AS NVARCHAR(30)) FROM MYLIB.ORDERHDR
SELECT CAST(ITEMNO AS NCHAR(10)) FROM MYLIB.ORDERS

The…

Read the thread · 2026-09-26 · closed · outside contributor · 0 comments

ODBC driver returns non-ASCII characters as U+FFFD

Problem

With DB2I_DRIVER=odbc, every character outside ASCII comes back as � (U+FFFD). Finnish, Swedish and German text in EBCDIC columns (for example CCSID 1143) loses Ä, Ö and Å, and € is lost too. This affects execute_query, YAML tools, profile_table and export_query. The jt400 and mapepire drivers return the same data correctly.

Found during the first real use of export_query (#160): an export of order headers had � where the stored bytes were correct (X'7B' is Ä…

Read the thread · 2026-09-26 · closed · outside contributor · 0 comments

ODBC driver returns binary columns as {} and rounds DECIMAL past 15 digits

Problem Statement

With DB2I_DRIVER=odbc, execute_query and the other tools that return rows lose data in two column types. Found while checking export_query (#160) against a real IBM i:

SELECT CAST(X'0AFF' AS BINARY(2)) AS B2,
       CAST(12345678901234567890.12 AS DECIMAL(31,2)) AS W
FROM SYSIBM.SYSDUMMY1
Column odbc jt400 / mapepire
B2 {} "0AFF"
W 12345678901234567000 "12345678901234567890.12"

-…

Read the thread · 2026-09-26 · closed · outside contributor · 0 comments

Add export_query to write query results to a CSV or XLSX file or download link

Problem Statement

Some questions end in a file, not an answer. "Give me all open orders for this customer as a spreadsheet" or "export this code table for the BI team" is a request for a download. Today every row passes through the model's context, capped by QUERY_MAX_LIMIT. That is expensive, large results are cut off, and the user still has to copy a table out of the chat.

For ETL work the same applies to the agent: in Claude Code or Cursor it can open a local file with DuckDB, pandas…

Read the thread · 2026-09-25 · closed · outside contributor · 0 comments

Add an optional admin tool group for system health, jobs, locks, stale objects and PTFs

Problem Statement

Agents that help with an ERP also get system questions: why is the system slow right now, which job holds a lock on ORDERS, how full is the disk, are we behind on PTFs. IBM's own MCP server (IBM/ibmi-mcp-server) ships YAML toolsets for performance, security and PTFs, and users comparing the two servers will notice the gap.

These tools need more authority than a data user usually has (*JOBCTL, sometimes *ALLOBJ or *AUDIT), and they are not what most users of this…

Read the thread · 2026-09-25 · open · outside contributor · 0 comments

Add table_access for authority, *PUBLIC and RCAC on a table

Problem Statement

When an agent works with a table that holds personal or financial data, the user often asks "who can read this?" or "is this column masked for other users?". Today the agent has to guess, or needs QSYS2 in the allowlist and knowledge of several views. The answer is in the catalog: QSYS2.OBJECT_PRIVILEGES for object authority (including *PUBLIC and authorization lists), QSYS2.AUTHORIZATION_LIST_USER_INFO, and QSYS2.SYSCONTROLS for row permissions and column masks…

Read the thread · 2026-09-25 · open · outside contributor · 0 comments

Add sql_error_log from QSYS2.SQL_ERROR_LOG

Problem Statement

When an application on the IBM i fails with an SQL error, the question is "which SQL failed, where, and how often". Db2 for i keeps this in QSYS2.SQL_ERROR_LOG when SQL error logging is on, and SYSTOOLS.SQLCODE_INFO explains each SQLCODE. The Db2 for i VS Code extension builds its SELF view and *SELF assistant queries on these, which shows developers use them.

It builds on #116, which added cause and recovery text to errors from this server.

Proposed Solution…

Read the thread · 2026-09-25 · open · outside contributor · 0 comments

Add compare_schema across libraries and systems

Problem Statement

IBM i shops run the same application in several libraries or on several systems: development, test and production, or one library per company. Changes are promoted by hand or by a change management tool, and they drift. A column added in test but not in production, or an index that exists on only one side, shows up as a failure at the worst time.

This server already connects to several systems through DB2I_PROFILES, which is what a comparison needs. Neon's MCP server…

Read the thread · 2026-09-25 · open · outside contributor · 0 comments

Add find_usage to show which programs and objects use a table

Problem Statement

The first question in most ERP work is "what uses this table?": which programs read or update MYLIB.ORDERS, which views and indexes depend on it, which SQL statements touch a column. The answer decides whether a change is safe, where a business rule lives and which program to look at. Commercial tools (ARCAD Observer, X-Analysis, and ARCAD's MCP server) sell exactly this. get_related_objects covers database dependents such as views, indexes and triggers, but not…

Read the thread · 2026-09-25 · open · outside contributor · 0 comments

The remaining reports are on the project's issue tracker.