MCP server for IBM i
π Documentation | 
Here is an overview of the repository structure:
ibmi-mcp-server/
βββ server/ β MCP server implementation (main package)
βββ tools/ β SQL tool YAML configurations
βββ agents/ β Agent implementations and examples
βββ apps/ β Deployment configurations (Docker, Gateway, n8n)
- Server Documentation - MCP server setup, development, and API
- Tools Documentation - SQL tool configuration guide
- Agents Documentation - Agent development and examples
- Deployment Guide - Docker, Gateway, and n8n setup
π Table of Contents
- ibmi-mcp-server (
β οΈ Under Active Development)- π Repository Structure
- π‘ Setup Mapepire
- β‘ Quickstart
- π Installing in MCP Clients
- Prerequisites: Local Installation
- Remote Server Setup
- Client Configurations
- Option 1: Local Stdio Server (Recommended)
- Option 2: Remote HTTP Server
- Environment Variable Expansion
- Managing Servers
- Local (Stdio)
- Remote (HTTP)
- Configuration File Locations
- Option 1: Local Stdio Server
- Option 2: Remote HTTP Server
- Secure Credentials with Input Variables
- Managing Servers
- Local (Stdio)
- Remote (HTTP)
- Local (Stdio)
- Remote (HTTP)
- Local (Stdio)
- Remote (HTTP)
- Local (Stdio)
- Remote (HTTP)
- Local (Stdio)
- Remote (HTTP)
- Local (Stdio)
- Remote (HTTP)
- Option 1: Manual Configuration
- Remote (HTTP) with Agno
- Remote (HTTP) with Official MCP SDK
- Troubleshooting
- π€ IBM i Agents
- βοΈ Configuration
- π IBM i HTTP Authentication (Beta)
- π§© SQL Tool Configuration
- π Running the Server (Development)
- π΅οΈββοΈ MCP Inspector
- Docker & Podman Deployment
- Architecture Overview
- π License
Before you can use the ibmi-mcp-server, you must install and configure Mapepire on your IBM i system.
Mapepire is a modern, high-performance database server for IBM i that provides SQL query execution capabilities over WebSocket connections. It acts as a gateway between modern application architectures (like MCP servers, AI agents, and REST APIs) and IBM i's Db2 for i database.
Traditional IBM i database access methods (ODBC, JDBC) don't align well with modern AI and MCP architectures that require:
- Fast, lightweight connections: AI agents make frequent, short-lived database queries
- WebSocket support: Enables real-time, bidirectional communication for streaming results
- Modern JSON-based protocols: Simplifies integration with TypeScript/JavaScript ecosystems
- Low-latency responses: Essential for interactive AI conversations and tool executions
Mapepire bridges this gap by providing a modern, WebSocket-based SQL query interface that's optimized for the request/response patterns of AI agents and MCP tools.
Quick Install (IBM i SSH Session):
# 1. Install Mapepire using yum
yum install mapepire-server
# 2. Install Service Commander (if not already installed)
yum install service-commander
# 3. Start Mapepire service
sc start mapepireπ Full Documentation: Mapepire System Administrator Guide
Important Notes:
- By default, Mapepire runs on port
8076. You'll need this port number when configuring theDB2i_PORTvariable in your.envfile.- Ensure your IBM i firewall allows inbound connections on port 8076
- For production deployments, configure SSL/TLS certificates (see official guide)
Clone the repository and install dependencies:
git clone https://github.com/IBM/ibmi-mcp-server.git
cd ibmi-mcp-server/
npm installnpm run build
# Or use 'npm run rebuild' for a clean installcp .env.example .envFill out the Db2 for i connection details in the .env file:
# IBM i DB2 for i Connection Settings
# Required for YAML SQL tools to connect to IBM i systems
DB2i_HOST=
DB2i_USER=
DB2i_PASS=
DB2i_PORT=8076
DB2i_IGNORE_UNAUTHORIZED=trueπ Configuration Guide: See the complete Configuration section for all available settings, including IBM i Database Connection, Authentication, HTTP Transport, and more.
Once built, you can start the server in different transport modes: http or stdio.
-
Via Stdio (Default):
npx ibmi-mcp-server --transport stdio --tools ./tools
-
Via Streamable HTTP:
npx ibmi-mcp-server --transport http --tools ./tools
By Default, the server registers SQL tools stored in the
toolsdirectory. This path is set in the.envfile (TOOLS_YAML_PATH). You can override the SQL tools path using the CLI
Make sure that the server is running in http mode:
npx ibmi-mcp-server --transport http --tools ./toolsIn another terminal, navigate to the server/tests/agents directory and follow the setup instructions in the README.
Run an example MCP Client script to list available tools:
cd server/tests/agents
uv run mcp_client.pyList Configured tool annotations and server resources:
cd server/tests/agents
# See a list of configured tools:
uv run test_tool_annotations.py
# see a list of server resources:
uv run test_toolset_resources.pyNote:
test_tool_annotations.pyandrun test_toolset_resources.pyDO NOT require and OpenAI API Key
cd server/tests/agents
export OPENAI_API_KEY=your_open_ai_key
uv run agent.py -p "What is my system status?"This template uses Vitest for testing, with a strong emphasis on integration testing to ensure all components work together correctly.
- Run all tests once:
npm test - Run tests in watch mode:
npm run test:watch
- Run tests and generate a coverage report:
npm run test:coverage
This server can be integrated into any MCP-compatible client using either local (stdio) or remote (HTTP) connections.
For local development, install the server globally using npm link:
# From the ibmi-mcp-server directory
npm install
npm run build
npm linkThis makes the ibmi-mcp-server command available globally on your machine. After linking, you can use npx ibmi-mcp-server in any client configuration.
Note:
TOOLS_YAML_PATHmust be an absolute path to your tools configuration directory (e.g.,/full/path/to/tools).
For HTTP remote connections, you need to:
-
Start the server with IBM i authentication enabled:
# Ensure your .env has these settings: MCP_AUTH_MODE=ibmi IBMI_HTTP_AUTH_ENABLED=true IBMI_AUTH_ALLOW_HTTP=true # For development only! npm run start:http
-
Obtain an access token:
# Use the token script to authenticate node get-access-token.js --verbose # Or set it directly in your environment export IBMI_MCP_ACCESS_TOKEN="your-token-here"
See IBM i HTTP Authentication for detailed authentication setup.
-
Configure your client with the server URL and Bearer token (examples below).
β οΈ Production Note: Replacehttp://localhost:3010with your production endpoint URL and ensure HTTPS is enabled (IBMI_AUTH_ALLOW_HTTP=false).
Claude Code
Claude Code supports both local (stdio) and remote (HTTP) MCP server connections. You can configure servers using the CLI or by editing .mcp.json directly.
Using CLI:
# Add local stdio server
claude mcp add ibmi-mcp \
--env DB2i_HOST=your-ibmi-host.com \
--env DB2i_USER=your-username \
--env DB2i_PASS=your-password \
--env DB2i_PORT=8076 \
--env MCP_TRANSPORT_TYPE=stdio \
-- npx ibmi-mcp-server --tools /absolute/path/to/toolsUsing .mcp.json:
{
"mcpServers": {
"ibmi-mcp": {
"command": "npx",
"args": ["ibmi-mcp-server", "--tools", "/absolute/path/to/tools"],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "your-username",
"DB2i_PASS": "your-password",
"DB2i_PORT": "8076",
"MCP_TRANSPORT_TYPE": "stdio",
"NODE_OPTIONS": "--no-deprecation"
}
}
}
}Using CLI:
# Add remote HTTP server with authentication
claude mcp add --transport http ibmi-mcp http://localhost:3010/mcp \
--header "Authorization: Bearer YOUR_ACCESS_TOKEN_HERE"Using .mcp.json:
{
"mcpServers": {
"ibmi-mcp": {
"url": "http://localhost:3010/mcp",
"type": "http",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN_HERE"
}
}
}
}Claude Code supports environment variable expansion in .mcp.json files, allowing you to keep credentials secure:
{
"mcpServers": {
"ibmi-mcp": {
"command": "npx",
"args": ["ibmi-mcp-server", "--tools", "${IBMI_TOOLS_PATH}"],
"env": {
"DB2i_HOST": "${DB2i_HOST}",
"DB2i_USER": "${DB2i_USER}",
"DB2i_PASS": "${DB2i_PASS}",
"DB2i_PORT": "${DB2i_PORT:-8076}",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}Supported syntax:
${VAR}- Expands to the value of environment variableVAR${VAR:-default}- Expands toVARif set, otherwise usesdefault
# List configured servers
claude mcp list
# Get server details
claude mcp get ibmi-mcp
# Remove a server
claude mcp remove ibmi-mcp
# Check server status in Claude Code
/mcpClaude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"ibmi-mcp": {
"command": "npx",
"args": ["ibmi-mcp-server", "--tools", "/absolute/path/to/tools"],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "your-username",
"DB2i_PASS": "your-password",
"DB2i_PORT": "8076",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}{
"mcpServers": {
"ibmi-mcp": {
"url": "http://localhost:3010/mcp",
"type": "http",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN_HERE"
}
}
}
}VSCode
VSCode supports MCP servers through Copilot Chat. You can configure servers at the user or workspace level using configuration files or the CLI.
Prerequisites: Ensure GitHub Copilot is installed and enabled.
- Workspace:
.vscode/mcp.json(shared with team via version control) - User:
mcp.jsonin your user profile directory- macOS/Linux:
~/.config/Code/User/globalStorage/modelcontextprotocol.mcp/mcp.json - Windows:
%APPDATA%\Code\User\globalStorage\modelcontextprotocol.mcp\mcp.json
- macOS/Linux:
Using CLI:
# Add local stdio server
code --add-mcp '{
"name": "ibmiMcp",
"type": "stdio",
"command": "npx",
"args": ["ibmi-mcp-server", "--tools", "/absolute/path/to/prebuiltconfigs"],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "your-username",
"DB2i_PASS": "your-password",
"DB2i_PORT": "8076",
"MCP_TRANSPORT_TYPE": "stdio"
}
}'Using mcp.json:
{
"servers": {
"ibmiMcp": {
"type": "stdio",
"command": "npx",
"args": ["ibmi-mcp-server", "--tools", "/absolute/path/to/tools"],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "your-username",
"DB2i_PASS": "your-password",
"DB2i_PORT": "8076",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}Using CLI:
# Add remote HTTP server
code --add-mcp '{
"name": "ibmiMcp",
"type": "http",
"url": "http://localhost:3010/mcp",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN_HERE"
}
}'Using mcp.json:
{
"servers": {
"ibmiMcp": {
"type": "http",
"url": "http://localhost:3010/mcp",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN_HERE"
}
}
}
}VSCode supports input variables to avoid hardcoding sensitive credentials:
{
"inputs": [
{
"id": "db2iHost",
"type": "promptString",
"description": "IBM i DB2 host address"
},
{
"id": "db2iUser",
"type": "promptString",
"description": "IBM i username"
},
{
"id": "db2iPass",
"type": "promptString",
"description": "IBM i password",
"password": true
}
],
"servers": {
"ibmiMcp": {
"type": "stdio",
"command": "npx",
"args": ["ibmi-mcp-server", "--tools", "/absolute/path/to/tools"],
"env": {
"DB2i_HOST": "${input:db2iHost}",
"DB2i_USER": "${input:db2iUser}",
"DB2i_PASS": "${input:db2iPass}",
"DB2i_PORT": "8076",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}VSCode will prompt for these values when the server starts, keeping credentials secure.
- View servers: Check the Copilot Chat view in the Activity Bar
- Restart server: Use Command Palette (
Cmd/Ctrl+Shift+P) β "MCP: Restart Server" - Disable server: Remove from
mcp.jsonor disable in settings
Cursor
Add to Cursor settings or .cursor/mcp.json:
{
"mcpServers": {
"ibmi-mcp": {
"command": "npx",
"args": ["ibmi-mcp-server", "--tools", "/absolute/path/to/tools"],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "your-username",
"DB2i_PASS": "your-password",
"DB2i_PORT": "8076",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}{
"mcpServers": {
"ibmi-mcp": {
"url": "http://localhost:3010/mcp",
"type": "http",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN_HERE"
}
}
}
}Windsurf
Add to Windsurf configuration:
{
"mcpServers": {
"ibmi-mcp": {
"command": "npx",
"args": ["ibmi-mcp-server", "--tools", "/absolute/path/to/tools"],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "your-username",
"DB2i_PASS": "your-password",
"DB2i_PORT": "8076",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}{
"mcpServers": {
"ibmi-mcp": {
"url": "http://localhost:3010/mcp",
"type": "http",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN_HERE"
}
}
}
}Roo Code
Configure in Roo Code settings:
{
"mcpServers": {
"ibmi-mcp": {
"command": "npx",
"args": ["ibmi-mcp-server", "--tools", "/absolute/path/to/tools"],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "your-username",
"DB2i_PASS": "your-password",
"DB2i_PORT": "8076",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}{
"mcpServers": {
"ibmi-mcp": {
"url": "http://localhost:3010/mcp",
"type": "http",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN_HERE"
}
}
}
}LM Studio
{
"mcpServers": {
"ibmi-mcp": {
"command": "npx",
"args": ["ibmi-mcp-server", "--tools", "/absolute/path/to/tools"],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "your-username",
"DB2i_PASS": "your-password",
"DB2i_PORT": "8076",
"MCP_TRANSPORT_TYPE": "stdio",
"NODE_OPTIONS": "--no-deprecation"
}
}
}
}{
"mcpServers": {
"ibmi-mcp": {
"url": "http://localhost:3010/mcp",
"type": "http",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN_HERE"
}
}
}
}OpenCode
Add local MCP servers using "type": "local" within the MCP object. Multiple MCP servers can be added. The key string for each server can be any arbitrary name.
opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"ibmi-mcp": {
"type": "local",
"enabled": true,
"command": ["npx", "ibmi-mcp-server", "--tools", "/absolute/path/to/tools"],
"environment": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "your-username",
"DB2i_PASS": "your-password",
"DB2i_PORT": "8076",
"MCP_TRANSPORT_TYPE": "stdio"
},
"enabled": true
}
}
}You can also disable a server by setting enabled to false. This is useful if you want to temporarily disable a server without removing it from your config.
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"ibmi-mcp": {
"type": "remote",
"enabled": true,
"url": "http://localhost:3010/mcp",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN_HERE"
}
}
}
}Gemini CLI
See Gemini CLI Configuration for details.
- Open the Gemini CLI settings file. The location is
~/.gemini/settings.json(where~is your home directory). - Add the following to the
mcpServersobject in yoursettings.jsonfile:
Configure in Gemini CLI settings:
{
"mcpServers": {
"ibmi-mcp": {
"command": "npx",
"args": ["ibmi-mcp-server", "--tools", "/absolute/path/to/tools"],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "your-username",
"DB2i_PASS": "your-password",
"DB2i_PORT": "8076",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}{
"mcpServers": {
"ibmi-mcp": {
"url": "http://localhost:3010/mcp",
"type": "http",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN_HERE"
}
}
}
}Cline
Cline supports MCP servers through both the marketplace and manual configuration.
Prerequisites: Ensure Cline is installed in VSCode.
For Local (Stdio) Server:
- Open Cline
- Click the hamburger menu icon (β°) β MCP Servers
- Choose Local Servers tab
- Click Edit Configuration
- Add the configuration:
{
"mcpServers": {
"ibmi-mcp": {
"command": "npx",
"args": ["ibmi-mcp-server", "--tools", "/absolute/path/to/tools"],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "your-username",
"DB2i_PASS": "your-password",
"DB2i_PORT": "8076",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}For Remote (HTTP) Server:
- Open Cline
- Click the hamburger menu icon (β°) β MCP Servers
- Choose Remote Servers tab
- Click Edit Configuration
- Add the configuration:
{
"mcpServers": {
"ibmi-mcp": {
"url": "http://localhost:3010/mcp",
"type": "streamableHttp",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN_HERE"
}
}
}
}Python Clients (Agno, Official MCP SDK)
import asyncio
import os
from agno.agent import Agent
from agno.tools.mcp import MCPTools, StreamableHTTPClientParams
# Get access token from environment
token = os.environ.get('IBMI_MCP_ACCESS_TOKEN')
if not token:
raise ValueError("IBMI_MCP_ACCESS_TOKEN not set")
url = "http://localhost:3010/mcp"
server_params = StreamableHTTPClientParams(
url=url,
headers={"Authorization": f"Bearer {token}"}
)
async def main():
async with MCPTools(
url=url,
server_params=server_params,
transport="streamable-http"
) as tools:
# List available tools
result = await tools.session.list_tools()
print(f"Available tools: {[t.name for t in result.tools]}")
# Create agent
agent = Agent(
model="openai:gpt-4o", # or your preferred model
tools=[tools],
name="ibmi-agent",
show_tool_calls=True
)
# Run query
await agent.aprint_response("What is the system status?")
if __name__ == "__main__":
asyncio.run(main())import asyncio
import os
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
async def main():
token = os.environ.get('IBMI_MCP_ACCESS_TOKEN')
if not token:
raise ValueError("IBMI_MCP_ACCESS_TOKEN not set")
headers = {"Authorization": f"Bearer {token}"}
async with streamablehttp_client(
"http://localhost:3010/mcp",
headers=headers
) as (read_stream, write_stream, _):
async with ClientSession(read_stream, write_stream) as session:
await session.initialize()
# List tools
tools = await session.list_tools()
print(f"Tools: {[t.name for t in tools.tools]}")
# Execute a tool
result = await session.call_tool("system_status", {})
print(result)
if __name__ == "__main__":
asyncio.run(main())π MCP Python SDK | Agno Framework
Connection Issues:
- Verify
npm linkwas successful:which ibmi-mcp-server - Check that
TOOLS_YAML_PATHis an absolute path - Ensure IBM i credentials are correct
MCP Server Errors:
If using npx ibmi-mcp-server does not work, use node directly:
{
"mcpServers": {
"ibmi-mcp": {
"command": "node",
"args": ["/absolute/path/to/ibmi-mcp-server/server/dist/index.js", "--tools", "/absolute/path/to/tools"],
"env": {
"DB2i_HOST": "your-ibmi-host.com",
"DB2i_USER": "your-username",
"DB2i_PASS": "your-password",
"DB2i_PORT": "8076",
"MCP_TRANSPORT_TYPE": "stdio",
"NODE_OPTIONS": "--no-deprecation"
}
}
}
}Authentication Failures (Remote):
- Confirm server is running with
IBMI_HTTP_AUTH_ENABLED=true - Verify token is valid:
echo $IBMI_MCP_ACCESS_TOKEN - Check server logs for authentication errors
Tool Loading Errors:
- Validate YAML configuration:
npm run validate -- --config tools - Check file permissions on tools directory
- Review server startup logs for parsing errors
IBM i Agents are specialized components designed to interact with the IBM i system, providing capabilities such as monitoring, management, and automation.
- Integration with IBM i: Seamless integration with IBM i system APIs and tools.
- Modular Architecture: Easily extendable and customizable to fit specific use cases.
- Real-time Monitoring: Continuous monitoring of system performance and health.
Navigate to the agents directory and follow the setup instructions in the README. This includes details on configuration, running agents, and examples. Most agent examples require the MCP server to be running in HTTP mode. Read the docs for each agent example for details.
The server is configured using environment variables, typically set in a .env file at the project root. Configuration is organized into logical groups for easier management.
Quick Start:
cp .env.example .env
code .env # Edit with your settingsπ₯οΈ MCP Server Settings
Core server configuration including server identity, transport mode, and logging.
| Variable | Description | Default | Required |
|---|---|---|---|
MCP_SERVER_NAME |
Server name identifier for MCP protocol | Package name from package.json |
No |
MCP_SERVER_VERSION |
Server version for MCP protocol | Version from package.json |
No |
MCP_TRANSPORT_TYPE |
Transport protocol: stdio (local) or http (remote) |
stdio |
No |
MCP_LOG_LEVEL |
Logging verbosity: error, warn, info, debug |
debug |
No |
LOGS_DIR |
Directory for log files (relative to project root) | logs |
No |
NODE_ENV |
Node environment: development, production, test |
development |
No |
Examples:
# Development with verbose logging
MCP_SERVER_NAME=ibmi-mcp-dev
MCP_TRANSPORT_TYPE=http
MCP_LOG_LEVEL=debug
NODE_ENV=development
# Production with minimal logging
MCP_SERVER_NAME=ibmi-mcp-prod
MCP_TRANSPORT_TYPE=stdio
MCP_LOG_LEVEL=warn
NODE_ENV=productionπ HTTP Transport Settings
Configuration for HTTP transport mode, including network settings, session management, and CORS.
| Variable | Description | Default | Required |
|---|---|---|---|
MCP_HTTP_PORT |
HTTP server port | 3010 |
No |
MCP_HTTP_HOST |
HTTP server bind address | 127.0.0.1 |
No |
MCP_HTTP_ENDPOINT_PATH |
MCP endpoint path | /mcp |
No |
MCP_SESSION_MODE |
Session handling: stateless, stateful, or auto |
auto |
No |
MCP_STATEFUL_SESSION_STALE_TIMEOUT_MS |
Timeout for idle stateful sessions (milliseconds) | 1800000 (30 min) |
No |
MCP_HTTP_MAX_PORT_RETRIES |
Max attempts to find available port if default is in use | 15 |
No |
MCP_HTTP_PORT_RETRY_DELAY_MS |
Delay between port retry attempts (milliseconds) | 50 |
No |
MCP_ALLOWED_ORIGINS |
Comma-separated CORS allowed origins | None (all origins blocked) | No |
Session Modes:
auto: Automatically detects client capabilities and uses the best session modestateful: Maintains persistent sessions with connection state (best for long-running interactions)stateless: Each request is independent (best for load balancing and horizontal scaling)
Examples:
# Development server with CORS for local web clients
MCP_HTTP_PORT=3010
MCP_HTTP_HOST=0.0.0.0 # Listen on all interfaces
MCP_SESSION_MODE=auto
MCP_ALLOWED_ORIGINS=http://localhost:3000,http://localhost:5173
# Production server with strict security
MCP_HTTP_PORT=443
MCP_HTTP_HOST=0.0.0.0
MCP_SESSION_MODE=stateful
MCP_ALLOWED_ORIGINS=https://app.example.com,https://dashboard.example.com
MCP_STATEFUL_SESSION_STALE_TIMEOUT_MS=3600000 # 1 hourπ Authentication & Authorization
Security configuration for protecting the MCP server and authenticating clients.
| Variable | Description | Default | Required |
|---|---|---|---|
MCP_AUTH_MODE |
Authentication mode: none, jwt, oauth, ibmi |
none |
No |
Required when MCP_AUTH_MODE=jwt.
| Variable | Description | Default | Required |
|---|---|---|---|
MCP_AUTH_SECRET_KEY |
Secret key for signing/verifying JWT tokens (min 32 characters) | None | β Yes (for JWT mode) |
Required when MCP_AUTH_MODE=oauth.
| Variable | Description | Default | Required |
|---|---|---|---|
OAUTH_ISSUER_URL |
OAuth authorization server issuer URL | None | β Yes (for OAuth mode) |
OAUTH_JWKS_URI |
OAuth JWKS endpoint for public key verification | None | No |
OAUTH_AUDIENCE |
Expected audience identifier for this MCP server | None | β Yes (for OAuth mode) |
Required when MCP_AUTH_MODE=ibmi. See IBM i HTTP Authentication for detailed setup.
| Variable | Description | Default | Required |
|---|---|---|---|
IBMI_HTTP_AUTH_ENABLED |
Enable IBM i authentication endpoints | false |
β Yes (for IBM i mode) |
IBMI_AUTH_ALLOW_HTTP |
Allow HTTP (non-HTTPS) authentication requests | false |
No |
IBMI_AUTH_TOKEN_EXPIRY_SECONDS |
Token lifetime in seconds | 3600 (1 hour) |
No |
IBMI_AUTH_CLEANUP_INTERVAL_SECONDS |
How often to clean up expired tokens (seconds) | 300 (5 minutes) |
No |
IBMI_AUTH_MAX_CONCURRENT_SESSIONS |
Maximum concurrent authenticated sessions | 100 |
No |
IBMI_AUTH_PRIVATE_KEY_PATH |
Path to RSA private key for encryption | None | β Yes (for IBM i mode) |
IBMI_AUTH_PUBLIC_KEY_PATH |
Path to RSA public key for encryption | None | β Yes (for IBM i mode) |
IBMI_AUTH_KEY_ID |
Identifier for the RSA keypair | None | β Yes (for IBM i mode) |
Examples:
# No authentication (development only)
MCP_AUTH_MODE=none
# JWT authentication
MCP_AUTH_MODE=jwt
MCP_AUTH_SECRET_KEY="your-very-secret-key-at-least-32-characters-long"
# OAuth authentication
MCP_AUTH_MODE=oauth
OAUTH_ISSUER_URL=https://auth.example.com
OAUTH_AUDIENCE=https://api.example.com/mcp
OAUTH_JWKS_URI=https://auth.example.com/.well-known/jwks.json
# IBM i authentication (see docs for keypair generation)
MCP_AUTH_MODE=ibmi
IBMI_HTTP_AUTH_ENABLED=true
IBMI_AUTH_KEY_ID=production
IBMI_AUTH_PRIVATE_KEY_PATH=secrets/private.pem
IBMI_AUTH_PUBLIC_KEY_PATH=secrets/public.pem
IBMI_AUTH_ALLOW_HTTP=false # HTTPS only in production
IBMI_AUTH_TOKEN_EXPIRY_SECONDS=7200 # 2 hours- Never use
MCP_AUTH_MODE=nonein production - Always use
IBMI_AUTH_ALLOW_HTTP=falsein production (requires HTTPS) - Generate strong secret keys (32+ characters) for JWT mode
- Rotate keys regularly for enhanced security
ποΈ IBM i Database Connection
Configuration for connecting to IBM i Db2 for i databases via Mapepire.
| Variable | Description | Default | Required |
|---|---|---|---|
DB2i_HOST |
IBM i system hostname or IP address | None | β Yes (for SQL tools) |
DB2i_USER |
IBM i user profile for database connections | None | β Yes (for SQL tools) |
DB2i_PASS |
Password for IBM i user profile | None | β Yes (for SQL tools) |
DB2i_PORT |
Mapepire daemon/gateway port | 8076 |
No |
DB2i_IGNORE_UNAUTHORIZED |
Skip TLS certificate verification (for self-signed certs) | true |
No |
Connection Flow:
- Server connects to Mapepire daemon/gateway at
DB2i_HOST:DB2i_PORT - Authenticates using
DB2i_USERandDB2i_PASS - Executes SQL tools through authenticated connection pool
Examples:
# Development connection with self-signed certs
DB2i_HOST=ibmi-dev.example.com
DB2i_USER=DEVUSER
DB2i_PASS=devpassword
DB2i_PORT=8076
DB2i_IGNORE_UNAUTHORIZED=true
# Production connection with verified SSL
DB2i_HOST=ibmi-prod.example.com
DB2i_USER=PRODUSER
DB2i_PASS=strongProductionPassword123
DB2i_PORT=8076
DB2i_IGNORE_UNAUTHORIZED=false # Require valid SSL cert
# Connecting to Mapepire gateway
DB2i_HOST=mapepire-gateway.example.com
DB2i_USER=APIUSER
DB2i_PASS=apiPassword456
DB2i_PORT=443 # Gateway on HTTPS
DB2i_IGNORE_UNAUTHORIZED=false- Store credentials securely (use secrets management in production)
- Use read-only accounts when possible
- Set
DB2i_IGNORE_UNAUTHORIZED=falsewith valid SSL certificates in production - Consider using IBM i authentication mode for per-user connection pooling
π§© SQL YAML Tool Configuration
Settings for loading and managing SQL tools defined in YAML configuration files. See Tools Documentation for YAML tool development.
| Variable | Description | Default | Required |
|---|---|---|---|
TOOLS_YAML_PATH |
Path to YAML tool configurations (file, directory, or glob) | None | No |
SELECTED_TOOLSETS |
Comma-separated list of toolsets to load (filters available tools) | None (load all) | No |
YAML_AUTO_RELOAD |
Automatically reload tools when YAML files change | true |
No |
When loading multiple YAML files, these settings control merge behavior:
| Variable | Description | Default | Required |
|---|---|---|---|
YAML_MERGE_ARRAYS |
Merge arrays from multiple files (true) or replace them (false) |
false |
No |
YAML_ALLOW_DUPLICATE_TOOLS |
Allow duplicate tool names across files | false |
No |
YAML_ALLOW_DUPLICATE_SOURCES |
Allow duplicate source names across files | false |
No |
YAML_VALIDATE_MERGED |
Validate merged configuration before loading tools | true |
No |
Path Resolution:
- File:
TOOLS_YAML_PATH=tools/performance.yaml - Directory:
TOOLS_YAML_PATH=tools/(loads all .yaml/.yml files) - Glob pattern:
TOOLS_YAML_PATH=tools/**/*.yaml - Multiple sources: Use CLI
--toolsto override at runtime
Examples:
# Load all tools from a directory
TOOLS_YAML_PATH=tools/
YAML_AUTO_RELOAD=true # Hot reload on file changes
# Load specific tools file
TOOLS_YAML_PATH=tools/performance-tools.yaml
SELECTED_TOOLSETS=monitoring,diagnostics
# Advanced merging (multiple config sources)
TOOLS_YAML_PATH=tools/
YAML_MERGE_ARRAYS=true # Combine toolsets from multiple files
YAML_ALLOW_DUPLICATE_TOOLS=false # Enforce unique tool names
YAML_VALIDATE_MERGED=true # Validate after merging
# Production: disable hot reload
TOOLS_YAML_PATH=/opt/mcp-tools/production.yaml
YAML_AUTO_RELOAD=falseCLI Override:
# Override TOOLS_YAML_PATH at runtime
npx ibmi-mcp-server --tools ./my-custom-tools
# Load specific toolsets only
npx ibmi-mcp-server --toolsets performance,securityπ OpenTelemetry (Observability)
Configuration for distributed tracing and metrics using OpenTelemetry.
| Variable | Description | Default | Required |
|---|---|---|---|
OTEL_ENABLED |
Enable OpenTelemetry instrumentation | false |
No |
OTEL_SERVICE_NAME |
Service name for telemetry data | MCP_SERVER_NAME or package name |
No |
OTEL_SERVICE_VERSION |
Service version for telemetry data | MCP_SERVER_VERSION or package version |
No |
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT |
OTLP endpoint for trace export | None (logs to file) | No |
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT |
OTLP endpoint for metrics export | None (not exported) | No |
OTEL_TRACES_SAMPLER_ARG |
Trace sampling ratio (0.0 to 1.0, where 1.0 = sample all) | 1.0 (100%) |
No |
OTEL_LOG_LEVEL |
OTel internal diagnostic log level | INFO |
No |
Supported OTEL_LOG_LEVEL values: NONE, ERROR, WARN, INFO, DEBUG, VERBOSE, ALL
Examples:
# Development: local file logging only
OTEL_ENABLED=true
OTEL_SERVICE_NAME=ibmi-mcp-dev
OTEL_LOG_LEVEL=DEBUG
# Traces written to logs/traces/ directory
# Production: export to Jaeger
OTEL_ENABLED=true
OTEL_SERVICE_NAME=ibmi-mcp-prod
OTEL_SERVICE_VERSION=1.9.1
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://jaeger:4318/v1/traces
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://jaeger:4318/v1/metrics
OTEL_TRACES_SAMPLER_ARG=0.1 # Sample 10% of traces
OTEL_LOG_LEVEL=WARN
# Production: export to cloud provider
OTEL_ENABLED=true
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://otlp.example.com/v1/traces
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=https://otlp.example.com/v1/metrics
OTEL_TRACES_SAMPLER_ARG=1.0 # Sample all tracesInstrumentation Coverage:
- All MCP tool executions
- HTTP requests and responses
- Database queries (SQL tools)
- Authentication flows
- Custom spans for critical operations
π€ LLM Provider Integration
Configuration for Large Language Model providers used by the server.
| Variable | Description | Default | Required |
|---|---|---|---|
OPENROUTER_API_KEY |
API key for OpenRouter.ai service | None | No |
OPENROUTER_APP_URL |
Application URL for OpenRouter dashboard | http://localhost:3000 |
No |
OPENROUTER_APP_NAME |
Application name for OpenRouter identification | Package name | No |
Default parameters for LLM requests (applied when not specified in request):
| Variable | Description | Default | Range | Required |
|---|---|---|---|---|
LLM_DEFAULT_MODEL |
Default model identifier | google/gemini-2.5-flash |
- | No |
LLM_DEFAULT_TEMPERATURE |
Sampling temperature (randomness) | None (provider default) | 0.0 - 2.0 | No |
LLM_DEFAULT_TOP_P |
Nucleus sampling threshold | None (provider default) | 0.0 - 1.0 | No |
LLM_DEFAULT_MAX_TOKENS |
Maximum tokens in response | None (provider default) | 1+ | No |
LLM_DEFAULT_TOP_K |
Top-K sampling (number of candidates) | None (provider default) | 0+ | No |
LLM_DEFAULT_MIN_P |
Minimum probability threshold | None (provider default) | 0.0 - 1.0 | No |
Examples:
# Basic OpenRouter setup
OPENROUTER_API_KEY=sk-or-v1-...
OPENROUTER_APP_NAME=ibmi-mcp-server
OPENROUTER_APP_URL=http://localhost:3000
# Custom LLM defaults for deterministic responses
LLM_DEFAULT_MODEL=anthropic/claude-3.5-sonnet
LLM_DEFAULT_TEMPERATURE=0.0 # Deterministic
LLM_DEFAULT_MAX_TOKENS=4000
LLM_DEFAULT_TOP_P=1.0
# Balanced configuration for creative responses
LLM_DEFAULT_MODEL=google/gemini-2.5-flash
LLM_DEFAULT_TEMPERATURE=0.7
LLM_DEFAULT_TOP_P=0.9
LLM_DEFAULT_MAX_TOKENS=2000π OAuth Proxy (Advanced)
Configuration for OAuth proxy endpoints (advanced use cases).
| Variable | Description | Default | Required |
|---|---|---|---|
OAUTH_PROXY_AUTHORIZATION_URL |
OAuth authorization endpoint URL | None | No |
OAUTH_PROXY_TOKEN_URL |
OAuth token endpoint URL | None | No |
OAUTH_PROXY_REVOCATION_URL |
OAuth token revocation endpoint URL | None | No |
OAUTH_PROXY_ISSUER_URL |
OAuth issuer URL for proxy | None | No |
OAUTH_PROXY_SERVICE_DOCUMENTATION_URL |
Service documentation URL | None | No |
OAUTH_PROXY_DEFAULT_CLIENT_REDIRECT_URIS |
Comma-separated default redirect URIs | None | No |
Example:
OAUTH_PROXY_AUTHORIZATION_URL=https://auth.example.com/oauth/authorize
OAUTH_PROXY_TOKEN_URL=https://auth.example.com/oauth/token
OAUTH_PROXY_REVOCATION_URL=https://auth.example.com/oauth/revoke
OAUTH_PROXY_ISSUER_URL=https://auth.example.com
OAUTH_PROXY_SERVICE_DOCUMENTATION_URL=https://docs.example.com/oauth
OAUTH_PROXY_DEFAULT_CLIENT_REDIRECT_URIS=http://localhost:3000/callback,https://app.example.com/callbackNote: OAuth proxy features are for advanced integration scenarios. Most users should use standard OAuth authentication via
MCP_AUTH_MODE=oauth.
Development:
# Recommended development .env
MCP_TRANSPORT_TYPE=http
MCP_HTTP_PORT=3010
MCP_SESSION_MODE=auto
MCP_LOG_LEVEL=debug
MCP_AUTH_MODE=none # Or ibmi with allow HTTP
NODE_ENV=development
DB2i_HOST=ibmi-dev.local
DB2i_USER=DEVUSER
DB2i_PASS=devpass
DB2i_IGNORE_UNAUTHORIZED=true
TOOLS_YAML_PATH=tools/
YAML_AUTO_RELOAD=true
OTEL_ENABLED=trueProduction:
# Recommended production .env
MCP_TRANSPORT_TYPE=http
MCP_HTTP_PORT=3010
MCP_SESSION_MODE=auto
MCP_LOG_LEVEL=warn
MCP_AUTH_MODE=ibmi # Or jwt/oauth
NODE_ENV=production
DB2i_HOST=ibmi-prod.example.com
DB2i_USER=PRODUSER
DB2i_PASS=${SECURE_PASSWORD_FROM_VAULT}
DB2i_IGNORE_UNAUTHORIZED=false # Require valid SSL
TOOLS_YAML_PATH=/opt/mcp-tools/production.yaml
YAML_AUTO_RELOAD=false
YAML_VALIDATE_MERGED=true
IBMI_HTTP_AUTH_ENABLED=true
IBMI_AUTH_ALLOW_HTTP=false # HTTPS only
IBMI_AUTH_PRIVATE_KEY_PATH=/opt/secrets/private.pem
IBMI_AUTH_PUBLIC_KEY_PATH=/opt/secrets/public.pem
OTEL_ENABLED=true
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://otlp.example.com/v1/tracesSecurity Checklist:
- β
Never commit
.envfiles to version control - β Use secrets management (Vault, AWS Secrets Manager, etc.) in production
- β Rotate credentials and keys regularly
- β
Use HTTPS/TLS in production (
IBMI_AUTH_ALLOW_HTTP=false) - β
Enable authentication (
MCP_AUTH_MODE != none) - β Use strong passwords (12+ characters, mixed case, numbers, symbols)
- β
Restrict
MCP_ALLOWED_ORIGINSto known domains - β
Set appropriate
IBMI_AUTH_MAX_CONCURRENT_SESSIONSlimits
The server supports IBM i HTTP authentication that allows clients to obtain access tokens for authenticated SQL tool execution. This enables per-user connection pooling and secure access to IBM i resources.
- Client Authentication: Clients authenticate with IBM i credentials via HTTP Basic Auth
- Token Generation: Server creates a secure Bearer token and establishes a dedicated connection pool
- Tool Execution: Subsequent tool calls use the Bearer token for authenticated execution
- Pool Management: Each token maintains its own connection pool for isolation and security
To enable IBM i HTTP authentication, we need to set up Encryption keys and configure the server environment. To protect IBM i credentials during transmission, the authentication flow uses RSA and AES encryption. You need to generate an RSA keypair for the server:
mkdir -p secrets
openssl genpkey -algorithm RSA -out secrets/private.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -pubout -in secrets/private.pem -out secrets/public.pemCreate or update your .env file with the following settings:
# Enable IBM i authentication system
IBMI_HTTP_AUTH_ENABLED=true
MCP_AUTH_MODE=ibmi
# IBM i authentication settings
IBMI_AUTH_KEY_ID=development
IBMI_AUTH_PRIVATE_KEY_PATH=secrets/private.pem
IBMI_AUTH_PUBLIC_KEY_PATH=secrets/public.pem
# Security settings
IBMI_AUTH_ALLOW_HTTP=true # Development only - use HTTPS in production
IBMI_AUTH_TOKEN_EXPIRY_SECONDS=3600 # Token lifetime (1 hour)
# Resource management
IBMI_AUTH_MAX_CONCURRENT_SESSIONS=100
IBMI_AUTH_CLEANUP_INTERVAL_SECONDS=300
# IBM i connection details
DB2i_HOST=your-ibmi-host
DB2i_USER=your-username
DB2i_PASS=your-passwordUse the included get-access-token.js script to obtain authentication tokens:
# Using credentials from .env file
node get-access-token.js --verbose
# Using CLI arguments (overrides .env)
node get-access-token.js --user myuser --password mypass --host my-ibmi-host
# Quiet mode for shell evaluation
eval $(node get-access-token.js --quiet)
echo $IBMI_MCP_ACCESS_TOKENThe script automatically:
- Loads IBM i credentials from
.envwith CLI fallback - Fetches the server's public key
- Encrypts credentials client-side
- Requests an access token
- Sets
IBMI_MCP_ACCESS_TOKENenvironment variable - Provides copy-paste export commands
sequenceDiagram
participant CLI as Client CLI
participant Auth as MCP Server (/api/v1/auth)
participant IBM as IBM i
CLI->>Auth: GET /api/v1/auth/public-key
Auth-->>CLI: { keyId, publicKey }
CLI->>CLI: Generate AES-256-GCM session key + IV
CLI->>CLI: Encrypt credentials + request body with session key
CLI->>CLI: Encrypt session key with server public key (RSA-OAEP)
CLI->>Auth: POST /api/v1/auth { keyId, encryptedSessionKey, iv, authTag, ciphertext }
Auth->>Auth: Look up keyId, decrypt session key with private key
Auth->>Auth: Decrypt ciphertext, validate GCM tag, validate payload
Auth->>IBM: Authenticate against IBM i with decrypted credentials
IBM-->>Auth: Success/Failure
Auth->>Auth: Generate access token, provision pool session
Auth-->>CLI: 201 JSON { access_token, expires_in, ... }
Once you have a token, use it in your MCP client to authenticate requests:
import asyncio
import os
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
async def main():
# Get the access token from environment
token = os.environ.get('IBMI_MCP_ACCESS_TOKEN')
if not token:
raise ValueError("IBMI_MCP_ACCESS_TOKEN environment variable not set")
# Set up authentication headers
headers = {"Authorization": f"Bearer {token}"}
# Connect to the IBM i MCP server with authentication
async with streamablehttp_client(
"http://localhost:3010/mcp",
headers=headers
) as (read_stream, write_stream, _):
# Create a session using the authenticated streams
async with ClientSession(read_stream, write_stream) as session:
# Initialize the connection
await session.initialize()
# List available tools (now authenticated with your IBM i credentials)
tools = await session.list_tools()
print(f"Available tools: {[tool.name for tool in tools.tools]}")
# Execute a tool with authenticated IBM i access
result = await session.call_tool("system_status", {})
print(f"System status result: {result}")
if __name__ == "__main__":
asyncio.run(main())Development Environment:
IBMI_AUTH_ALLOW_HTTP=trueallows HTTP for testing- Use localhost/trusted networks only
- Shorter token lifetimes for testing
Production Environment:
IBMI_AUTH_ALLOW_HTTP=falseenforces HTTPS- Use proper TLS certificates
- Longer token lifetimes for stability
- Network security and access controls
- Monitor
IBMI_AUTH_MAX_CONCURRENT_SESSIONSfor resource usage
When enabled (IBMI_HTTP_AUTH_ENABLED=true), the server provides these endpoints:
| Endpoint | Method | Description |
|---|---|---|
/api/v1/auth |
POST | Authenticate with IBM i credentials and receive Bearer token |
The Primary way to confgure tools used by this MCP server is through tools.yaml files (see tools/ for examples). There are 3 main sections to each yaml file: sources, tools, and toolsets. Below is a breakdown of each section
The sources section of your tools.yaml defines the data sources the MCP server has access to
sources:
ibmi-system:
host: ${DB2i_HOST}
user: ${DB2i_USER}
password: ${DB2i_PASS}
port: 8076
ignore-unauthorized: trueNote
The environment variables DB2i_HOST, DB2i_USER, DB2i_PASS, and DB2i_PORT can be set in the server .env file. see Configuration
The tools section of your tools.yaml defines the actions your agent can take: what kind of tool it is, which source(s) it affects, what parameters it uses, etc.
tools:
system_status:
source: ibmi-system
description: "Overall system performance statistics with CPU, memory, and I/O metrics"
parameters: []
statement: |
SELECT * FROM TABLE(QSYS2.SYSTEM_STATUS(RESET_STATISTICS=>'YES',DETAILED_INFO=>'ALL')) XThe toolsets section of your tools.yaml allows you to define groups of tools that you want to be able to load together. This can be useful for defining different sets for different agents or different applications.
toolsets:
performance:
tools:
- system_status
- system_activity
- remote_connections
- memory_pools
- temp_storage_buckets
- unnamed_temp_storage
- http_server
- system_values
- collection_services
- collection_categories
- active_job_infoMore documentation on SQL tools coming soon!
The server supports multiple transport modes and session configurations for different development scenarios. Use the appropriate startup command based on your needs.
# Basic HTTP server
npm run start:http
# HTTP with custom tools path
npm run start:http -- --tools ./my-configs
# HTTP with specific toolsets
npm run start:http -- --toolsets performance,monitoring# Basic stdio transport
npm run start:stdio
# Stdio with custom tools path
npm run start:stdio -- --tools ./my-custom-toolsMake sure that to use the absolute path for tools
The MCP_SESSION_MODE environment variable controls how the HTTP server handles client sessions:
auto(default): Automatically detects client capabilities and uses the best session modestateful: Maintains persistent sessions with connection statestateless: Each request is independent, no session state maintained
# Set session mode via environment variable
MCP_SESSION_MODE=stateful npm run start:http
# Or set in .env file
echo "MCP_SESSION_MODE=stateful" >> .env
npm run start:httpBoth transport modes support these command-line options:
Note: CLI arguments override corresponding settings in
.envfile when provided.
| Option | Short | Description | Example |
|---|---|---|---|
--tools <path> |
Override YAML tools configuration path (overrides TOOLS_YAML_PATH) |
--tools ./custom-configs |
|
--toolsets <list> |
-ts |
Load only specific toolsets (comma-separated) (overrides SELECTED_TOOLSETS) |
--toolsets performance,security |
--transport <type> |
-t |
Force transport type (http or stdio) (overrides MCP_TRANSPORT_TYPE) |
--transport http |
--help |
-h |
Show help information | --help |
--list-toolsets |
List available toolsets from YAML configuration | --list-toolsets |
1. Standard Development Server
npm run start:http
# Server: http://localhost:3010/mcp
# Tools: tools/ (from .env)
# Session: auto-detected2. Custom Tools Path
npm run start:http -- --tools ./my-tools
# Server: http://localhost:3010/mcp (port from .env or default)
# Tools: ./my-tools3. Specific Toolsets Only
npm run start:http -- --toolsets performance,monitoring
# Only loads tools from 'performance' and 'monitoring' toolsets- Hot Reloading: Enable
YAML_AUTO_RELOAD=truein.envfor automatic tool configuration updates - Verbose Logging: Set
MCP_LOG_LEVEL=debugfor detailed operation logs - CORS: Configure
MCP_ALLOWED_ORIGINSfor web-based clients - Authentication: Use
MCP_AUTH_MODE=ibmiwith IBM i HTTP auth for token-based access
Port Already in Use
# Configure port in .env file
echo "MCP_HTTP_PORT=3011" >> .env
npm run start:httpTools Not Loading
# Check tools path
npm run start:http -- --tools ./tools
# List available toolsets first
npm run start:http -- --list-toolsets --tools ./tools
# Get help
npm run start:http -- --helpThe MCP Inspector is a tool for exploring and debugging the MCP server's capabilities. It provides a user-friendly interface for interacting with the server, viewing available tools, and testing queries.
Here are the steps to run the MCP Inspector:
-
Make sure to build the server
cd ibmi-mcp-server/ npm run build -
Create an
mcp.jsonfile:cp template_mcp.json mcp.json
Fill out the connection details in
mcp.jsonwith your IBM i system information. You should use the same credentials as in your.envfile:{ "mcpServers": { "default-server": { "command": "node", "args": ["dist/index.js"], "env": { "TOOLS_YAML_PATH": "tools", "NODE_OPTIONS": "--no-deprecation", "DB2i_HOST": "<DB2i_HOST>", "DB2i_USER": "<DB2i_USER>", "DB2i_PASS": "<DB2i_PASS>", "DB2i_PORT": "<DB2i_PORT>", "MCP_TRANSPORT_TYPE": "stdio" } } } } -
Start the MCP Inspector
npm run mcp-inspector
-
Click on the URL displayed in the terminal to open the MCP Inspector in your web browser.
Starting MCP inspector... βοΈ Proxy server listening on 127.0.0.1:6277 π Session token: EXAMPLE_TOKEN Use this token to authenticate requests or set DANGEROUSLY_OMIT_AUTH=true to disable auth π Open inspector with token pre-filled: http://localhost:6274/?MCP_PROXY_AUTH_TOKEN=EXAMPLE_TOKEN π MCP Inspector is up and running at http://127.0.0.1:6274 π
- Use the MCP Inspector to explore and test your MCP server's capabilities
- View available tools and their parameters
- Test queries against the server
- Debug issues with tool execution
The project includes a comprehensive docker-compose.yml that sets up the complete MCP gateway with the IBM i MCP Server.
ContextForge MCP Gateway is a feature-rich gateway, proxy and MCP Registry that federates MCP and REST services - unifying discovery, auth, rate-limiting, observability, virtual servers, multi-transport protocols, and an optional Admin UI into one clean endpoint for your AI clients.
Read more about it here.
Choose one of the following container platforms:
- Docker Desktop (macOS/Windows): Download here
- Docker Engine (Linux): Installation guide
- Podman Desktop (macOS/Windows): Download here
- Podman CLI (Linux): Installation guide
- podman-compose:
pip install podman-compose
The docker-compose.yml uses a local build of the MCP Gateway image. To build it, clone the MCP Gateway repository and build the image:
git clone https://github.com/IBM/mcp-context-forge.git
cd mcp-context-forge
# Build image using Docker
make docker-prod
# Or build image using Podman
make podman-prodThis will create a local image named localhost/mcpgateway/mcpgateway that the docker-compose.yml can use. More details on building the MCP Gateway image can be found in the MCP Gateway Docs.
Create a .env file in the ibmi-mcp-server directory with your IBM i connection details:
cd ibmi-mcp-server/
cp .env.example .env
# Edit .env with your IBM i connection details
code .envmake sure to set the follow variables in your .env file:
# IBM i connection details
DB2i_HOST="your_host"
DB2i_USER="your_user"
DB2i_PASS="your_pass"
# MCP Auth mode
MCP_AUTH_MODE=ibmi
# IBM i HTTP authentication settings
IBMI_AUTH_KEY_ID=development
IBMI_AUTH_PRIVATE_KEY_PATH=secrets/private.pem
IBMI_AUTH_PUBLIC_KEY_PATH=secrets/public.pem
# Enable IBM i HTTP authentication endpoints (requires MCP_AUTH_MODE=ibmi)
IBMI_HTTP_AUTH_ENABLED=true
# Allow HTTP requests for authentication (development only, use HTTPS in production)
IBMI_AUTH_ALLOW_HTTP=trueNote: You need to generate an RSA keypair for the server if you haven't already done so. See the IBM i HTTP Authentication section for instructions.
Once you have your .env file configured, you can start the complete stack using Docker or Podman.
-
Start the complete stack:
# Start all services in background docker-compose up -d # Or start specific services docker-compose up -d gateway ibmi-mcp-server postgres redis
-
Verify services are running:
docker-compose ps
-
Start the complete stack:
# Start all services in background podman compose up -d # Or start specific services podman compose up -d gateway ibmi-mcp-server postgres redis
-
Verify services are running:
podman compose ps
The docker-compose setup includes these services:
| Service | Port | Description | Access URL |
|---|---|---|---|
| gateway | 4444 | MCP Context Forge main API | http://localhost:4444 |
| ibmi-mcp-server | 3010 | IBM i SQL tools MCP server | http://localhost:3010 |
| postgres | - | PostgreSQL database (internal) | - |
| redis | 6379 | Cache service | redis://localhost:6379 |
| pgadmin | 5050 | Database admin UI | http://localhost:5050 |
| redis_insight | 5540 | Cache admin UI | http://localhost:5540 |
# Docker
docker-compose up -d # Start all services
docker-compose up -d gateway # Start specific service
docker-compose up --no-deps gateway # Start without dependencies
# Podman
podman compose up -d # Start all services
podman compose up -d gateway # Start specific service
podman compose up --no-deps gateway # Start without dependencies# Docker
docker-compose down # Stop all services
docker-compose stop gateway # Stop specific service
# Podman
podman compose down # Stop all services
podman compose stop gateway # Stop specific service# Docker
docker-compose logs -f gateway # Follow gateway logs
docker-compose logs --tail=100 ibmi-mcp-server
# Podman
podman compose logs -f gateway # Follow gateway logs
podman compose logs --tail=100 ibmi-mcp-server# Docker
docker-compose build ibmi-mcp-server # Rebuild specific service
docker-compose up --build -d # Rebuild and restart all
# Podman
podman compose build ibmi-mcp-server # Rebuild specific service
podman compose up --build -d # Rebuild and restart allAfter the Containers are up and running, you can access the MCP Context Forge UI at http://localhost:4444
Enter the demo credentials:
- User:
admin - Password:
changeme
To Configure the IBM i MCP server is the admin ui, navigate to the "Gateways/MCP Servers" tab. and enter the mcp server endpoint:
- IBM i mcp server endpoint:
http://ibmi-mcp-server:3010
Once the MCP server is connect, you can then manage the tools provided by the server:
This template is built on a set of architectural principles to ensure modularity, testability, and operational clarity.
- Core Server (
src/mcp-server/server.ts): The central point where tools and resources are registered. It uses aManagedMcpServerwrapper to provide enhanced introspection capabilities. It acts the same way as the native McpServer, but with additional features like introspection and enhanced error handling. - Transports (
src/mcp-server/transports/): The transport layer connects the core server to the outside world. It supports bothstdiofor direct process communication and a streamable Hono-basedhttpserver. - "Logic Throws, Handler Catches": This is the immutable cornerstone of our error-handling strategy.
- Core Logic (
logic.ts): This layer is responsible for pure, self-contained business logic. It throws a structuredMcpErroron any failure. - Handlers (
registration.ts): This layer interfaces with the server, invokes the core logic, and catches any errors. It is the exclusive location where errors are processed and formatted into a final response.
- Core Logic (
- Structured, Traceable Operations: Every operation is traced from initiation to completion via a
RequestContextthat is passed through the entire call stack, ensuring comprehensive and structured logging.
| Feature Area | Description | Key Components / Location |
|---|---|---|
| π MCP Server | A functional server with example tools and resources. Supports stdio and a Streamable HTTP transport built with Hono. |
src/mcp-server/, src/mcp-server/transports/ |
| π Observability | Built-in OpenTelemetry for distributed tracing and metrics. Auto-instrumentation for core modules and custom tracing for all tool executions. | src/utils/telemetry/ |
| π Production Utilities | Logging, Error Handling, ID Generation, Rate Limiting, Request Context tracking, Input Sanitization. | src/utils/ |
| π Type Safety/Security | Strong type checking via TypeScript & Zod validation. Built-in security utilities (sanitization, auth middleware for HTTP). | Throughout, src/utils/security/, src/mcp-server/transports/auth/ |
| βοΈ Error Handling | Consistent error categorization (BaseErrorCode), detailed logging, centralized handling (ErrorHandler). |
src/utils/internal/errorHandler.ts, src/types-global/ |
| π Documentation | Comprehensive README.md, structured JSDoc comments, API references. |
README.md, Codebase, tsdoc.json, docs/api-references/ |
| π΅οΈ Interaction Logging | Captures raw requests and responses for all external LLM provider interactions to a dedicated interactions.log file for full traceability. |
src/utils/internal/logger.ts |
| π€ Agent Ready | Includes a .clinerules developer cheatsheet tailored for LLM coding agents. | .clinerules/ |
| π οΈ Utility Scripts | Scripts for cleaning builds, setting executable permissions, generating directory trees, and fetching OpenAPI specs. | scripts/ |
| π§© Services | Reusable modules for LLM (OpenRouter) and data storage (DuckDB) integration, with examples. | src/services/, src/storage/duckdbExample.ts |
| π§ͺ Integration Testing | Integrated with Vitest for fast and reliable integration testing. Includes example tests for core logic and a coverage reporter. | vitest.config.ts, tests/ |
| β±οΈ Performance Metrics | Built-in utility to automatically measure and log the execution time and payload size of every tool call. | src/utils/internal/performance.ts |
src/mcp-server/: Contains the core MCP server, tools, resources, and transport handlers.src/config/: Handles loading and validation of environment variables.src/services/: Reusable modules for integrating with external services (DuckDB, OpenRouter).src/types-global/: Defines shared TypeScript interfaces and type definitions.src/utils/: Core utilities (logging, error handling, security, etc.).src/index.ts: The main entry point that initializes and starts the server.
Explore the full structure yourself:
See the current file tree in docs/tree.md or generate it dynamically:
npm run treeThe template enforces a strict, modular pattern for adding new tools and resources, as mandated by the Architectural Standard. The echoTool (src/mcp-server/tools/echoTool/) serves as the canonical example.
This is the cornerstone of the architecture:
-
logic.ts: This file contains the pure business logic.- It defines the Zod schemas for input and output, which serve as the single source of truth for the tool's data contract.
- The core logic function is pure: it takes validated parameters and a request context, and either returns a result or throws a structured
McpError. - It never contains
try...catchblocks for formatting a final response.
-
registration.ts: This file is the "handler" that connects the logic to the MCP server.- It imports the schemas and logic function from
logic.ts. - It calls
server.registerTool(), providing the tool's metadata and the runtime handler. - The runtime handler always wraps the call to the logic function in a
try...catchblock. This is the only place where errors are caught, processed by theErrorHandler, and formatted into a standardized error response.
- It imports the schemas and logic function from
This pattern ensures that core logic remains decoupled, pure, and easily testable, while the registration layer handles all transport-level concerns, side effects, and response formatting.
This project is licensed under the Apache License 2.0. See the LICENSE file for details.



