MCP Oracle Server
A production-grade Node.js MCP server for Oracle Database with HTTP transport, enabling SQL query execution, table listing, schema retrieval, and natural language to SQL conversion via MCP tools.
README
MCP Oracle Server (HTTP Transport)
A production-grade Node.js Model Context Protocol (MCP) server for Oracle Database with HTTP transport for Telnyx AI Agent compatibility. This server exposes MCP tools over HTTP/JSON-RPC, enabling integration with Telnyx and other HTTP-based MCP clients.
Features
- ✅ HTTP-based MCP Protocol: Full HTTP/JSON-RPC implementation (not STDIO)
- ✅ Telnyx Compatible: Designed for Telnyx AI Agent MCP integration
- ✅ Oracle Database Integration: Connection pooling with
oracledbdriver - ✅ API Key Authentication: Secure
/mcpendpoint with API key validation - ✅ MCP Tools:
runQuery: Execute SQL queries with bind parameterslistTables: List all tables in the databasegetSchema: Get detailed table schema informationnl2sql: Convert natural language to SQL using external service
- ✅ Web Server: Express server with
/health,/ready,/metrics,/webhook/telnyx - ✅ Production Ready: Logging, error handling, connection pooling, graceful shutdown
- ✅ Dockerized: Fully containerized with Docker Compose
Project Structure
mcp-oracle/
├── src/
│ ├── server.js # Main entrypoint: HTTP server + MCP setup
│ ├── oracle.js # Oracle connection pool management
│ ├── auth.js # API key authentication middleware
│ ├── web.js # Express app and routes
│ ├── mcpTransport.js # HTTP transport wrapper for MCP
│ ├── logger.js # Winston logger with file rotation
│ └── tools/
│ ├── runQuery.js # Execute SQL queries
│ ├── listTables.js # List database tables
│ ├── getSchema.js # Get table schema
│ └── nl2sql.js # Natural language to SQL
├── tests/
│ ├── integration.test.sh # Integration test script
│ └── lint-setup.md # Linting setup guide
├── package.json
├── Dockerfile
├── docker-compose.yml
├── .env.example
└── README.md
Prerequisites
- Node.js 20+ (for local development)
- Docker and Docker Compose (for containerized deployment)
- Oracle Database (accessible via network)
- Oracle Instant Client (handled automatically in Docker)
Quick Start
1. Setup Environment
# Copy environment file
cp .env.example .env
# Edit .env with your Oracle credentials
nano .env
Required environment variables:
ORACLE_USER: Oracle database usernameORACLE_PASS: Oracle database passwordORACLE_CONN: Connection string (format:host:port/service)MCP_API_KEY: API key for/mcpendpoint authentication (recommended)
2. Run with Docker Compose
# Build and start all services
docker-compose up --build
# Run in detached mode
docker-compose up -d
# View logs
docker-compose logs -f mcp-oracle
3. Run Locally (Development)
# Install dependencies
npm install
# Set environment variables (or use .env file)
export ORACLE_USER=your_user
export ORACLE_PASS=your_password
export ORACLE_CONN=host:1521/XEPDB1
export MCP_API_KEY=your_api_key
# Start the server
npm start
Configuration
Environment Variables
See .env.example for all available configuration options:
Required:
ORACLE_USER: Oracle database usernameORACLE_PASS: Oracle database passwordORACLE_CONN: Oracle connection string (format:host:port/service)
Recommended:
MCP_API_KEY: API key for/mcpendpoint (if not set, allows unauthenticated requests in dev mode)
Optional:
PORT: HTTP server port (default:3000)NL2SQL_URL: URL of NL2SQL service (default:http://nl2sql-service:8500/query)LOG_LEVEL: Logging level (default:info)CORS_ORIGIN: CORS origin (default:*)MAX_REQUEST_SIZE: Maximum request size (default:10mb)
Oracle Connection Pool
Configure pool settings via environment variables:
ORACLE_POOL_MIN: Minimum pool size (default:2)ORACLE_POOL_MAX: Maximum pool size (default:10)ORACLE_POOL_INCREMENT: Pool increment (default:1)ORACLE_POOL_TIMEOUT: Pool timeout in seconds (default:60)
API Endpoints
MCP Endpoint
POST /mcp
Main MCP protocol endpoint. Accepts JSON-RPC 2.0 requests.
Authentication:
- Header:
x-mcp-api-key: <your-api-key> - Or:
Authorization: Bearer <your-api-key>
Request Format:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}
Response Format:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [...]
}
}
Health & Monitoring
- GET
/health: Basic health check - GET
/ready: Readiness check (verifies DB pool) - GET
/metrics: Prometheus-formatted metrics - POST
/webhook/telnyx: Telnyx webhook handler
MCP Tools
1. runQuery
Execute a SQL query against the Oracle database.
Request:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "runQuery",
"arguments": {
"sql": "SELECT * FROM employees WHERE department_id = :dept_id",
"binds": { "dept_id": 10 },
"maxRows": 100
}
}
}
Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [{
"type": "text",
"text": "{\"success\":true,\"data\":{\"rows\":[...],\"rowCount\":5}}"
}]
}
}
2. listTables
List all tables in the database.
Request:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "listTables",
"arguments": {
"schema": "HR"
}
}
}
3. getSchema
Get detailed schema information for a table.
Request:
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "getSchema",
"arguments": {
"tableName": "employees",
"schema": "HR"
}
}
}
4. nl2sql
Convert natural language query to SQL.
Request:
{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "nl2sql",
"arguments": {
"query": "Show me all customers from New York"
}
}
}
Telnyx Configuration
Setting up Telnyx AI Agent
-
Configure MCP URL:
- In Telnyx AI Agent settings, set the MCP URL to:
https://<your-host>:<port>/mcp - Example:
https://mcp.example.com:3000/mcp
- In Telnyx AI Agent settings, set the MCP URL to:
-
Configure API Key:
- In Telnyx AI Agent MCP configuration, set the API key to match your
MCP_API_KEYenvironment variable - The agent should send requests with header:
x-mcp-api-key: <your-api-key>
- In Telnyx AI Agent MCP configuration, set the API key to match your
-
Example Telnyx Configuration JSON:
{
"mcp": {
"url": "https://your-server.com:3000/mcp",
"apiKey": "your-secure-api-key-here",
"transport": "http"
}
}
Testing Telnyx Integration
# Test MCP endpoint with API key
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "x-mcp-api-key: your-api-key" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}'
Example curl Commands
List Available Tools
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "x-mcp-api-key: changeme" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}'
Execute a Query
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "x-mcp-api-key: changeme" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "runQuery",
"arguments": {
"sql": "SELECT table_name FROM user_tables WHERE ROWNUM <= 5"
}
}
}'
Health Check
curl http://localhost:3000/health
Telnyx Webhook
curl -X POST http://localhost:3000/webhook/telnyx \
-H "Content-Type: application/json" \
-d '{
"event_type": "message.received",
"data": {
"from": "+1234567890",
"to": "+0987654321",
"text": "Hello"
}
}'
Running Tests
Integration Tests
The project includes a bash integration test script:
# Make script executable
chmod +x tests/integration.test.sh
# Run tests (defaults to http://localhost:3000)
./tests/integration.test.sh
# Run with custom URL and API key
BASE_URL=http://your-server:3000 MCP_API_KEY=your-key ./tests/integration.test.sh
The test script validates:
- Health endpoint
- Readiness endpoint
- Metrics endpoint
- MCP authentication
- MCP tools/list
- MCP tools/call (listTables)
Docker Services
mcp-oracle
The main MCP server container:
- Runs HTTP server on port 3000
- Exposes MCP endpoint at
/mcp - Mounts logs directory
- Connects to Oracle database
nl2sql-service
FastAPI service for natural language to SQL conversion:
- Placeholder implementation included
- Exposes API on port 8500
- Replace with your actual NL2SQL service by updating the
imageindocker-compose.yml
oracle-db (Optional)
Local Oracle database for testing:
- Uses
gvenzl/oracle-freeimage - Exposes port 1521
- Data persisted in Docker volume
- Commented out by default - uncomment in
docker-compose.ymlif needed
Logging
Logs are written to:
- Console: Structured JSON logs with timestamps
- Files: Rotating log files in
logs/directory- Format:
mcp-oracle-YYYY-MM-DD.log - Max size: 20MB per file
- Retention: 14 days
- Format:
Security
API Key Authentication
The /mcp endpoint requires API key authentication:
- Set
MCP_API_KEYenvironment variable - Send requests with header:
x-mcp-api-key: <key>orAuthorization: Bearer <key> - If
MCP_API_KEYis not set, requests are allowed but a warning is logged (development mode)
TLS/HTTPS
For production, enable TLS:
-
Option 1: Application-level TLS (not recommended)
- Set
TLS_CERTandTLS_KEYenvironment variables - Update server code to use HTTPS
- Set
-
Option 2: Reverse Proxy (recommended)
- Use nginx, traefik, or similar
- Handle TLS termination at the proxy
- Forward requests to the application on port 3000
Request Limits
- Maximum request size: 10MB (configurable via
MAX_REQUEST_SIZE) - Request timeout: 30 seconds (configurable via
MCP_REQUEST_TIMEOUT) - CORS: Configurable via
CORS_ORIGIN
Troubleshooting
Oracle Connection Issues
- Check connection string format:
host:port/service - Verify network connectivity:
telnet host 1521 - Check Oracle Instant Client: Ensure it's installed in Docker
- Review logs: Check
logs/directory for detailed error messages
MCP Endpoint Issues
- Authentication errors: Verify
MCP_API_KEYmatches in request header - Timeout errors: Increase
MCP_REQUEST_TIMEOUTif queries are slow - Connection refused: Ensure service is running and port is exposed
NL2SQL Service Issues
- Verify service is running:
curl http://nl2sql-service:8500/health - Check network: Ensure services are on the same Docker network
- Review timeout: Default is 30 seconds
Design Notes / Choices
This section documents key design decisions and tradeoffs made during implementation:
1. HTTP Transport Implementation
Decision: Implemented custom HTTP transport wrapper instead of using SDK's STDIO transport.
Rationale:
- The MCP SDK (
@modelcontextprotocol/sdk) primarily supports STDIO transport - Telnyx and other HTTP-based clients require HTTP/JSON-RPC endpoints
- Created a wrapper that routes JSON-RPC requests to MCP Server's internal request handlers
- This allows the server to work with HTTP clients while maintaining compatibility with MCP protocol
Tradeoff:
- Requires manual routing of requests to handlers
- May need updates if SDK adds native HTTP transport in the future
- Benefits: Works with Telnyx and any HTTP client
2. API Key Authentication Pattern
Decision: Simple API key authentication via header, with development mode fallback.
Rationale:
- Telnyx requires API key-based authentication
- Supports both
x-mcp-api-keyheader andAuthorization: Bearerfor flexibility - If
MCP_API_KEYis not set, allows requests but logs warning (useful for local development) - Simple to implement and understand
Tradeoff:
- Not as secure as JWT with expiration, but sufficient for API-to-API communication
- Can be enhanced with JWT support in the future (stub provided in
auth.js)
3. Request Timeout Handling
Decision: 30-second default timeout with configurable value.
Rationale:
- Prevents hanging requests from consuming resources
- SQL queries can be slow, but 30 seconds is reasonable for most cases
- Configurable via
MCP_REQUEST_TIMEOUTfor different use cases - Returns proper JSON-RPC error response on timeout
Tradeoff:
- May timeout on very large/complex queries
- Users can increase timeout or optimize queries
4. Streaming Support
Decision: Implemented request-response pattern without streaming.
Rationale:
- MCP SDK's streaming is designed for STDIO
- HTTP request-response is simpler and more compatible
- Large result sets can be paginated using
maxRowsparameter - Can be enhanced with Server-Sent Events (SSE) or WebSockets if needed
Tradeoff:
- Large result sets must be paginated
- No real-time streaming of results
- Benefits: Simpler implementation, better compatibility
5. Error Handling and Response Format
Decision: All errors return JSON-RPC 2.0 compliant responses with proper error codes.
Rationale:
- Maintains JSON-RPC 2.0 protocol compliance
- Provides structured error information
- Tool errors are wrapped in MCP content format
- Database errors are caught and returned as JSON
Tradeoff:
- Error information is nested (JSON-RPC error → MCP content → tool error)
- Benefits: Protocol compliance, structured errors, easier debugging
License
MIT
Contributing
Contributions welcome! Please ensure:
- Code follows existing style
- All tools return consistent JSON responses
- Error handling is comprehensive
- Logging is appropriate
- Tests are updated
Support
For issues and questions:
- Check logs in
logs/directory - Review Docker Compose logs:
docker-compose logs - Verify environment variables
- Test Oracle connectivity independently
- Run integration tests:
./tests/integration.test.sh
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。