janglada/mcp_server_jdbc
If you are the rightful owner of mcp_server_jdbc and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
The Informix MCP Server is a Java-based implementation of the Model Context Protocol (MCP) that provides read-only access to IBM Informix databases via JDBC, using an embedded Jetty HTTP server.
Informix MCP Server
A Model Context Protocol (MCP) server implementation in Java 21 using the official MCP Java SDK that provides read-only database access to IBM Informix databases via JDBC with embedded Jetty HTTP transport.
Features
- Official MCP SDK: Built with
io.modelcontextprotocol.sdk:mcp(v0.14.0) - Embedded Jetty: Lightweight HTTP server without Spring framework
- HTTP/Servlet Transport: RESTful HTTP endpoint at
/mcp/message - No Spring: Pure Java with Jetty - minimal dependencies
- Read-Only Access: Secure, read-only database operations
- Three Core Tools:
list_tables: List all tables in the databaseget_table_schema: Get detailed schema information for a tableexecute_query: Execute SELECT queries with strict validation
- Security:
- SQL injection prevention
- Query validation (only SELECT statements allowed)
- Connection pooling with HikariCP
- Java 21 Features:
- Records for immutable data structures
- Pattern matching
- Text blocks
Quick Start
With Docker (Easiest)
# 1. Start Informix Docker container
docker run -d --name informix -p 9088:9088 -e LICENSE=accept \
ibmcom/informix-developer-database:latest
# 2. Wait ~30 seconds for Informix to initialize, then build and run
mvn clean package -DskipTests
java -jar target/mcp-server-jdbc-1.0.0-jar-with-dependencies.jar
# 3. Server starts on http://localhost:8080/mcp/message
# Test it:
curl -X POST http://localhost:8080/mcp/message \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
The MCP server will automatically connect to the Informix Docker container using default settings.
Requirements
- Java Development Kit (JDK) 21 or higher
- Maven 3.6 or higher
- IBM Informix database server (Docker recommended)
- Informix JDBC driver (included in dependencies)
Project Structure
mcp_server_jdbc/
├── src/main/java/com/informix/mcp/
│ ├── InformixMCPServer.java # Main entry point
│ ├── JettyServerConfig.java # Jetty and MCP configuration
│ ├── config/
│ │ └── DatabaseConfig.java # Configuration management
│ ├── database/
│ │ ├── InformixConnection.java # Connection pool manager
│ │ └── QueryValidator.java # SQL query validation
│ ├── model/
│ │ ├── ColumnInfo.java # Column metadata record
│ │ └── QueryResult.java # Query result record
│ └── tools/
│ ├── ListTablesTool.java # Database operations
│ ├── ListTablesToolHandler.java # MCP tool handler
│ ├── GetTableSchemaTool.java # Database operations
│ ├── GetTableSchemaToolHandler.java # MCP tool handler
│ ├── ExecuteQueryTool.java # Database operations
│ └── ExecuteQueryToolHandler.java # MCP tool handler
├── src/main/resources/
│ ├── database.properties.template # Database config template
│ └── logback.xml # Logging configuration
├── pom.xml # Maven build configuration
└── README.md # This file
Architecture
The server uses the official MCP Java SDK with:
- Embedded Jetty: Lightweight HTTP server (no Spring, no Tomcat)
- MCP Servlet Transport: HTTP-based communication via
/mcp/messageendpoint - Tool Handlers: Each tool has a dedicated handler implementing MCP's
CallToolResultinterface - Synchronous API: Uses
McpServer.sync()for blocking operations - Minimal Dependencies: Only Jetty, MCP SDK, and necessary libraries
Installation
1. Start Informix Docker Container (Recommended)
The easiest way to get started is using the official Informix Docker container:
docker run -it --name iif_developer_edition \
--privileged \
-p 9088:9088 \
-p 9089:9089 \
-e LICENSE=accept \
ibmcom/informix-developer-database:latest
Default Docker Container Settings:
- Server Name:
informix - Database:
sysmaster(system database) - Port:
9088(SQLI),9089(DRDA) - Username:
informix - Password:
in4mix - Host:
localhost(when running outside Docker)
Wait for the message "Informix container login Information" before connecting.
2. Clone or Download the Project
cd /home/joan/workspace/mcp_server_jdbc
3. Configure Database Connection
For Docker (Default): No configuration needed! The defaults match the Docker container.
For Custom Setup:
Choose one of the following configuration methods:
Option A: Using Properties File
cp src/main/resources/database.properties.template database.properties
Edit database.properties:
# Defaults for Informix Docker container
informix.host=localhost
informix.port=9088
informix.database=sysmaster
informix.server=informix
informix.username=informix
informix.password=in4mix
informix.pool.size=5
Then set the environment variable:
export INFORMIX_CONFIG_FILE=/path/to/database.properties
Option B: Using Environment Variables
cp .env.template .env
Edit .env and source it:
source .env
Or set variables directly:
# Defaults for Informix Docker container
export INFORMIX_HOST=localhost
export INFORMIX_PORT=9088
export INFORMIX_DATABASE=sysmaster
export INFORMIX_SERVER=informix
export INFORMIX_USERNAME=informix
export INFORMIX_PASSWORD=in4mix
export INFORMIX_POOL_SIZE=5
4. Build the Project
mvn clean package
This will create:
target/mcp-server-jdbc-1.0.0.jar(standard JAR)target/mcp-server-jdbc-1.0.0-jar-with-dependencies.jar(standalone JAR with all dependencies)
Running the Server
Standalone Mode (Default Port 8080)
java -jar target/mcp-server-jdbc-1.0.0-jar-with-dependencies.jar
The server will start on http://localhost:8080 with the MCP endpoint at /mcp/message.
Custom Port (Command Line)
java -jar target/mcp-server-jdbc-1.0.0-jar-with-dependencies.jar 9090
Custom Port (Environment Variable)
MCP_PORT=9090 java -jar target/mcp-server-jdbc-1.0.0-jar-with-dependencies.jar
With Configuration File
INFORMIX_CONFIG_FILE=/path/to/database.properties \
java -jar target/mcp-server-jdbc-1.0.0-jar-with-dependencies.jar
Development Mode
mvn exec:java -Dexec.mainClass="com.informix.mcp.InformixMCPServer"
MCP Endpoint
The server exposes an MCP endpoint at:
POST http://localhost:8080/mcp/message
This endpoint implements the Model Context Protocol over HTTP using the official MCP Servlet transport.
Tool Usage
The server exposes three tools via the MCP protocol. All requests should be sent as JSON to the /mcp/message endpoint.
1. list_tables
Lists all tables in the database.
Parameters:
schema(optional): Filter tables by schema name
Example Request:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_tables",
"arguments": {
"schema": "informix"
}
}
}
Example Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "{\"tables\": [{\"name\": \"customers\", \"schema\": \"informix\", \"type\": \"TABLE\"}], \"count\": 1}"
}
]
}
}
2. get_table_schema
Returns schema information for a specific table.
Parameters:
table_name(required): Name of the table (can include schema:schema.table)
Example Request:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "get_table_schema",
"arguments": {
"table_name": "customers"
}
}
}
Example Response:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [
{
"type": "text",
"text": "{\"tableName\": \"customers\", \"columnCount\": 3, \"columns\": [{\"name\": \"id\", \"type\": \"INTEGER\", \"size\": 10, \"nullable\": false, \"primaryKey\": true}]}"
}
]
}
}
3. execute_query
Executes a SELECT query against the database.
Parameters:
query(required): SQL SELECT statementmax_rows(optional): Maximum number of rows to return (default: 10000)
Example Request:
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "execute_query",
"arguments": {
"query": "SELECT * FROM customers WHERE country = 'USA'",
"max_rows": 100
}
}
}
Example Response:
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{
"type": "text",
"text": "{\"columns\": [\"id\", \"name\", \"country\"], \"rows\": [{\"id\": 1, \"name\": \"John\", \"country\": \"USA\"}], \"rowCount\": 1}"
}
]
}
}
Testing with cURL
Initialize Connection
curl -X POST http://localhost:8080/mcp/message \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {}
}'
List Tools
curl -X POST http://localhost:8080/mcp/message \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
}'
List Tables
curl -X POST http://localhost:8080/mcp/message \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "list_tables",
"arguments": {}
}
}'
Get Table Schema
curl -X POST http://localhost:8080/mcp/message \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "get_table_schema",
"arguments": {
"table_name": "customers"
}
}
}'
Execute Query
curl -X POST http://localhost:8080/mcp/message \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 5,
"method": "tools/call",
"params": {
"name": "execute_query",
"arguments": {
"query": "SELECT * FROM customers LIMIT 10"
}
}
}'
Security Features
Query Validation
The server implements strict query validation:
- ✅ Allowed: SELECT queries, CTEs (WITH...SELECT)
- ❌ Blocked: INSERT, UPDATE, DELETE, DROP, ALTER, CREATE, TRUNCATE, EXEC, and other modification statements
- ❌ Blocked: Multiple statements (semicolon-separated)
- ❌ Blocked: SQL comments that might hide malicious code
- ❌ Blocked: Stored procedure execution
Example of Blocked Queries
-- ❌ Blocked: Data modification
UPDATE customers SET name = 'hacker'
-- ❌ Blocked: Table deletion
DROP TABLE customers
-- ❌ Blocked: Multiple statements
SELECT * FROM customers; DELETE FROM customers
-- ❌ Blocked: Procedure execution
EXECUTE PROCEDURE update_data()
-- ✅ Allowed: Simple SELECT
SELECT * FROM customers WHERE id = 1
-- ✅ Allowed: CTE
WITH active_customers AS (
SELECT * FROM customers WHERE active = true
)
SELECT * FROM active_customers
Connection Pooling
The server uses HikariCP for connection pooling with the following default settings:
- Maximum pool size: 5 connections (configurable)
- Minimum idle: 1 connection
- Connection timeout: 30 seconds
- Idle timeout: 10 minutes
- Max lifetime: 30 minutes
- Connection test query:
SELECT 1 FROM systables WHERE tabid=1
Logging
Logs are written to console (stdout/stderr) and optionally to file.
Log levels can be adjusted in src/main/resources/logback.xml.
Configuration
Server Configuration
- Port: Default 8080
- Override via command line:
java -jar server.jar 9090 - Override via environment:
MCP_PORT=9090 java -jar server.jar
- Override via command line:
Database Configuration
Environment variables (highest priority):
INFORMIX_HOSTINFORMIX_PORTINFORMIX_DATABASEINFORMIX_SERVERINFORMIX_USERNAMEINFORMIX_PASSWORDINFORMIX_POOL_SIZE
Or use INFORMIX_CONFIG_FILE to point to a properties file.
Testing
Unit Tests
mvn test
Integration Tests
To run integration tests, you need a running Informix database:
mvn verify
Troubleshooting
Connection Issues
-
Verify Informix server is running:
onstat - -
Check JDBC URL format:
jdbc:informix-sqli://host:port/database:INFORMIXSERVER=server_name -
Test connectivity:
curl http://localhost:8080/mcp/message
Query Validation Errors
If you get "Forbidden SQL keyword" errors for legitimate SELECT queries:
- Ensure there are no SQL comments in your query
- Check for keywords like "UPDATE_DATE" (use quotes:
"UPDATE_DATE") - Verify the query doesn't contain semicolons
Port Already in Use
Change the port:
java -jar target/mcp-server-jdbc-1.0.0-jar-with-dependencies.jar 9090
Or:
MCP_PORT=9090 java -jar target/mcp-server-jdbc-1.0.0-jar-with-dependencies.jar
Development
Building from Source
mvn clean compile
Running Tests
mvn test
Creating a Release
mvn clean package -DskipTests
Debugging
Enable DEBUG logging in logback.xml:
<logger name="com.informix.mcp" level="DEBUG"/>
<logger name="io.modelcontextprotocol" level="DEBUG"/>
<logger name="org.eclipse.jetty" level="INFO"/>
Dependencies
- MCP SDK (0.14.0): Official Model Context Protocol Java SDK
- MCP Servlet (0.14.0): HTTP Servlet transport for MCP
- Embedded Jetty (11.0.24): Lightweight HTTP server and servlet container
- Informix JDBC Driver (4.50.10): Official IBM Informix JDBC driver
- HikariCP (6.2.1): High-performance JDBC connection pool
- Jackson (2.18.2): JSON processing
- SLF4J/Logback (2.0.16/1.5.12): Logging framework
- JUnit 5 (5.11.4): Testing framework
MCP Protocol Support
This server implements the Model Context Protocol specification:
- Protocol Version: 2024-11-05
- Transport: HTTP/Servlet
- Capabilities: Tools
- Communication: JSON-RPC 2.0
Using in Claude
claude mcp add --transport http database-inspector http://localhost:9090/mcp
Deployment Options
1. Standalone JAR
java -jar target/mcp-server-jdbc-1.0.0-jar-with-dependencies.jar
2. Behind Reverse Proxy (nginx)
server {
listen 80;
server_name mcp.example.com;
location /mcp {
proxy_pass http://localhost:8080/mcp;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
3. Docker
FROM eclipse-temurin:21-jre
COPY target/mcp-server-jdbc-1.0.0-jar-with-dependencies.jar /app.jar
EXPOSE 8080
ENV MCP_PORT=8080
CMD ["java", "-jar", "/app.jar"]
Build and run:
docker build -t informix-mcp-server .
docker run -p 8080:8080 \
-e INFORMIX_HOST=host.docker.internal \
-e INFORMIX_DATABASE=testdb \
-e INFORMIX_SERVER=ol_informix1170 \
-e INFORMIX_USERNAME=informix \
-e INFORMIX_PASSWORD=secret \
informix-mcp-server
4. System Service (systemd)
Create /etc/systemd/system/informix-mcp.service:
[Unit]
Description=Informix MCP Server
After=network.target
[Service]
Type=simple
User=mcp
WorkingDirectory=/opt/informix-mcp
Environment="INFORMIX_HOST=localhost"
Environment="INFORMIX_DATABASE=testdb"
Environment="INFORMIX_SERVER=ol_informix1170"
Environment="INFORMIX_USERNAME=informix"
Environment="INFORMIX_PASSWORD=secret"
Environment="MCP_PORT=8080"
ExecStart=/usr/bin/java -jar /opt/informix-mcp/mcp-server-jdbc-1.0.0-jar-with-dependencies.jar
Restart=on-failure
[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl enable informix-mcp
sudo systemctl start informix-mcp
sudo systemctl status informix-mcp
Advantages of Jetty (No Spring)
- Lightweight: ~2MB vs ~30MB+ for Spring Boot
- Fast Startup: Starts in seconds, not tens of seconds
- Simple Configuration: Pure Java, no XML, no annotations magic
- Low Memory: Minimal footprint for production
- Full Control: Direct access to server configuration
- HTTP Support: Standard web server features without framework overhead
License
This project is provided as-is for use with IBM Informix databases.
Support
For issues and questions:
- Check the logs (console output or
logs/mcp-server.log) - Verify database connectivity
- Review the configuration settings
- Enable DEBUG logging in
logback.xml - Test the endpoint with cURL
Contributing
Contributions are welcome! Please ensure:
- Code follows Java best practices
- All tests pass
- Security features are maintained
- Documentation is updated
- MCP protocol compatibility is preserved
Version History
- 1.0.0 (2025-10-04): Initial release with MCP SDK
- Official MCP Java SDK integration
- Embedded Jetty (no Spring, no frameworks)
- HTTP/Servlet transport
- Three core tools: list_tables, get_table_schema, execute_query
- HikariCP connection pooling
- Comprehensive query validation
- JDK 21 features (records, pattern matching)