MCP_TOOLS_DISABLED, or the list narrowed with MCP_TOOLS_ENABLED (see Tool selection). With several systems configured, every tool takes an optional system argument (see Multiple systems). With MCP_TOOL_INTENT=true, every tool also takes an optional context argument: one sentence on why the call is made, written to the audit log and not used by the tool (see Intent). Business SQL tools loaded from YAML appear next to these.
Tools
Note:list_indexesandget_table_constraintsquery theQSYS2SQL catalog views and only return SQL-defined objects. Legacy DDS Logical Files and Physical File constraints are not included.
Procedures and functions
list_routines reads QSYS2.SYSROUTINES for one library and returns one row per specific routine, so each overload of a name is its own row. filter uses the same wildcards as list_tables, and type narrows the list to PROCEDURE or FUNCTION.
describe_routine reads QSYS2.SYSPARMS for a routine. An overloaded name returns every overload unless specific_name picks one. Each result has the fields above plus:
Templates look like
CALL MYLIB.GET_ORDER(ORDERNO => ?), SELECT MYLIB.ORDER_TOTAL(ORDERNO => ?) FROM SYSIBM.SYSDUMMY1, and SELECT * FROM TABLE(MYLIB.OPEN_ORDERS(CUSTNO => ?)) X. execute_query runs only SELECT, so procedures and functions that modify SQL data are never callable through it. While QUERY_ALLOWED_SCHEMAS is set, statements are parsed to check their libraries, and the parser does not read named arguments in a scalar call. A scalar function’s template then uses positional markers and is callable only when SYSIBM is in the list too, because it reads SYSIBM.SYSDUMMY1. A table function’s template, TABLE(MYLIB.OPEN_ORDERS(CUSTNO => ?)), passes the check.
Index advice
index_advice reads the IBM i index advisor (QSYS2.SYSIXADV) for one library, or one table in it. The advisor keeps a row per reason code and variant, so the tool merges rows with the same table, key columns, and index type and sums their counts. rows_merged says how many advisor rows each result stands for.
Results are sorted by
mti_used, then times_advised. Advice the optimizer kept building a temporary index for is the strongest candidate for a permanent one. since keeps only advisor rows last given on or after that date or timestamp, also in the system’s local time. The tool only reads the advice. Review it before creating an index, because the advisor does not check whether an existing index or keyed logical file already covers the keys.
Row limit
execute_query returns at most limit rows (default QUERY_DEFAULT_LIMIT, never above QUERY_MAX_LIMIT), and a business SQL tool at most its maxRows. The result has limitApplied and truncated. The server asks Db2 for one row more than the limit, so truncated: true means more rows match than were returned, and truncated: false means the result is complete. A FETCH FIRST in the statement that is smaller than the limit is kept, and reaching it is not reported as truncation. The server adds its FETCH FIRST before clauses that Db2 for i requires after it, such as FOR READ ONLY, OPTIMIZE FOR n ROWS or an isolation clause like WITH UR, and ignores a limit written inside a comment or a string.
Warnings
A successfulexecute_query or business SQL tool result can carry warnings, which the agent should pass on to the user:
- A result cut at the row limit (
truncated: true) says so and suggests narrowing the filter or aggregating. - A query that reads an annotated table without using its row filter, such as the flag for deleted rows. The table is also listed in
skippedFilters. See Row filters. - With the
odbcdriver,DECIMALandNUMERICcolumns whose values have more than 15 digits and were rounded. See Values that differ by driver.
Query exports
export_query is for results the user wants as a file, such as “all open orders for customer 1001 as a spreadsheet”. It runs a SELECT with the same checks as execute_query and writes every row to a file on the server host, instead of returning the rows to the model. It is registered only when EXPORT_ENABLED=true and EXPORT_DIR are set. See Query exports for the settings.
The result tells the model where the file is and what is in it:
- XLSX has one sheet with a bold, frozen header row and a filter. Numbers, dates, times and timestamps are typed cells. A decimal column with digits after the point gets a number format with its scale, so
72.5in aDECIMAL(9,2)column shows as72.50and still adds up. A decimal orBIGINTwider than 15 digits is written as text so it keeps every digit. Text is always text, so a value that starts with=never becomes a formula. One sheet holds at most 1,048,575 rows. - CSV is UTF-8 with a byte order mark, so Excel opens accented characters correctly, and fields are quoted as in RFC 4180. A text value that starts with
=,+,-or@gets a leading', so a spreadsheet does not run it as a formula. Numbers are never changed. - With the
odbcdriver, node-odbc readsDECIMALandNUMERICvalues as JavaScript numbers, so digits past the 15th are rounded. When a value in the export has 15 or more significant digits, the result has awarningsentry naming the column. Use thejt400ormapepiredriver when such values must be exact. - Text that contains the replacement character
�means characters were lost when the driver decoded it. The result then has awarningsentry naming the columns. With theodbcdriver, setCCSID=1208inDB2I_ODBC_OPTIONS. - CHAR padding is removed. Binary columns are written as upper-case hex, unless
translate binary=trueis set forjt400ormapepire(see Values that differ by driver). - Give every column a unique name. A result with two columns of the same name, such as
a.ORDERNOandb.ORDERNO, is rejected; useAS.
Failed statements
When Db2 rejects a statement inexecute_query, a business SQL tool, validate_query or profile_table, the error result also has these fields:
cause and recovery also follow the message in the text content, and come from the second-level text of the SQL message (SYSTOOLS.SQLCODE_INFO). &1, &2 and so on stand for the values in the first-level message in error. With the JDBC option errors=full, the jt400 and mapepire drivers return the text with the values filled in. If the text cannot be read, the error comes without cause and recovery. Rejections by the SQL validator, the schema allowlist or column masking explain themselves and have none of these fields.
A statement the parse check cannot parse gets these fields too. QSYS2.PARSE_STATEMENT gives no reason of its own, so the server prepares the statement on the read-only connection without running it, and returns Db2’s error, for example The statement could not be parsed: [42000] SQL0104 - Token EXISTS was not valid. This works on the odbc and mapepire drivers. jt400 has no way to prepare a statement without running it, so it keeps the generic message. validate_query puts the same message in violations.
When execute_query or export_query names a column the table does not have (SQLCODE -206, SQLSTATE 42703, or 42S22 through ODBC), recovery starts with a hint such as Check the column names with describe_table for MYLIB.ORDERS before trying again, and put text values in single quotes, not double quotes. The tables come from parsing the statement on the server, with no extra database call. When the statement cannot be parsed, the hint says “the tables in the query” instead, and when describe_table is disabled, it is not named. Business SQL tools do not get the hint, since the caller cannot change their SQL.
Filter syntax
The list tools support pattern matching:Resources
Clients that support MCP resources can read a table’s context without a tool call, and complete library and table names as you type.resources/list offers the annotated tables, for example db2i://MYLIB/ORDERS. Percent-encode # and other reserved characters in names (ORD%23X for ORD#X). A library outside QUERY_ALLOWED_SCHEMAS is rejected with the same message execute_query gives, and completion offers only allowed libraries. Reads and completions that query IBM i count against the rate limit, and reads are written to the audit log. Completion fetches a library’s name list once and reuses it for 60 seconds, so typing a name costs one query rather than one per keystroke.
Prompts
A prompt is listed only when the tools it tells the model to call are enabled:
explore_library needs list_tables and describe_table, and the other two need describe_table. None of them asks for a write.