Teradata MCP Server
# Teradata MCP Server
A Model Context Protocol (MCP) server for Teradata database with OAuth 2.1 authentication, multiple authentication mechanisms (TD2, LDAP, Kerberos), and interactive data visualization.
## Features
- **Multiple Auth Mechanisms** — TD2 (default), LDAP, Kerberos, JWT via Teradata `LOGMECH`
- **OAuth 2.1** with Keycloak integration, JWT validation, scope-based authorization
- **Protected Resource Metadata** (RFC 9728 compliant)
- **Interactive Visualization** — ECharts-based MCP App with 19 chart types
- **Connection Resilience** — automatic retry with exponential backoff
- **Non-blocking I/O** — all DB operations run via `asyncio.to_thread()`
- **Per-tool QueryBand** — audit trail for Teradata workload management
## Tools
### Query Tools
- **`query`** — Execute SQL queries, return plain tabular results
- **`visualize_query`** — Execute SQL and render interactive ECharts charts via MCP App
### Schema Tools
- **`list_db`** — List all databases
- **`list_tables`** — List tables/views in a database
- **`show_tables_details`** — Show column names and types for a table
### Analysis Tools
- **`list_missing_values`** — Columns with NULL value counts
- **`list_negative_values`** — Columns with negative value counts
- **`list_distinct_values`** — Distinct category counts per column
- **`standard_deviation`** — Mean and standard deviation for a column
### MCP App — Interactive Visualization
The `visualize_query` tool renders results as interactive charts in the MCP client.
| Category | Charts |
|----------|--------|
| Bar | Basic, Grouped, Stacked, Horizontal, Sorted, Waterfall, Rounded, Polar |
| Line | Basic, Smooth, Area, Stacked Area, Step |
| Pie | Pie, Doughnut, Rose / Nightingale |
| Scatter | Scatter, Bubble |
| Mixed | Bar + Line |
## Quick Start
### Installation
```bash
git clone https://github.com/arturborycki/mcp-teradata.git
cd mcp-teradata
uv sync
```
### Run with TD2 (Standard Authentication)
```bash
uv run teradata-mcp "teradatasql://user:password@host/database"
```
Or via environment variable:
```bash
export DATABASE_URI="teradatasql://user:password@host/database"
uv run teradata-mcp
```
## Configuration
### Claude Desktop
Add to your `claude_desktop_config.json`:
#### TD2 (Username/Password)
```json
{
"mcpServers": {
"teradata": {
"command": "uv",
"args": [
"--directory", "/path/to/mcp-teradata",
"run", "teradata-mcp"
],
"env": {
"DATABASE_URI": "teradatasql://user:password@host/database"
}
}
}
}
```
#### LDAP Authentication
```json
{
"mcpServers": {
"teradata": {
"command": "uv",
"args": [
"--directory", "/path/to/mcp-teradata",
"run", "teradata-mcp"
],
"env": {
"DATABASE_URI": "teradatasql://@host/database",
"DB_LOGMECH": "LDAP",
"DB_LOGDATA": "authcid=ldap_user password=ldap_password"
}
}
}
}
```
The `authcid` format depends on the LDAP directory:
| Directory | Format |
|-----------|--------|
| Active Directory (Simple Bind) | `authcid=user@domain.com` |
| Active Directory (DIGEST-MD5) | `authcid=DOMAIN\username` |
| OpenLDAP / Sun DS | `authcid=username` |
#### Kerberos Authentication
```json
{
"mcpServers": {
"teradata": {
"command": "uv",
"args": [
"--directory", "/path/to/mcp-teradata",
"run", "teradata-mcp"
],
"env": {
"DATABASE_URI": "teradatasql://@host/database",
"DB_LOGMECH": "KRB5"
}
}
}
}
```
#### OAuth-Enabled Configuration
```json
{
"mcpServers": {
"teradata": {
"command": "uv",
"args": [
"--directory", "/path/to/mcp-teradata",
"run", "teradata-mcp"
],
"env": {
"DATABASE_URI": "teradatasql://user:password@host/database",
"OAUTH_ENABLED": "true",
"KEYCLOAK_URL": "https://your-keycloak.example.com",
"KEYCLOAK_REALM": "teradata-realm",
"KEYCLOAK_CLIENT_ID": "teradata-mcp",
"KEYCLOAK_CLIENT_SECRET": "your-secret",
"OAUTH_RESOURCE_SERVER_URL": "https://your-mcp-server.example.com"
}
}
}
}
```
### Environment Variables
#### Database Connection
| Variable | Description | Default |
|----------|-------------|---------|
| `DATABASE_URI` | Teradata connection URL (`teradatasql://user:pass@host/db`) | — |
| `DB_LOGMECH` | Authentication mechanism: `TD2`, `LDAP`, `KRB5`, `TDNEGO`, `JWT` | `TD2` |
| `DB_LOGDATA` | LDAP/JWT credentials (e.g., `authcid=user password=pass`) | — |
| `DB_SSL_MODE` | TLS mode: `ALLOW`, `PREFER`, `REQUIRE`, `VERIFY-CA`, `VERIFY-FULL` | — |
| `DB_ENCRYPT_DATA` | Enable transport encryption | `true` |
#### Connection Resilience
| Variable | Description | Default |
|----------|-------------|---------|
| `DB_MAX_RETRIES` | Max reconnection attempts | `3` |
| `DB_INITIAL_BACKOFF` | Initial backoff delay (seconds) | `1.0` |
| `DB_MAX_BACKOFF` | Max backoff delay (seconds) | `30.0` |
#### MCP Transport
| Variable | Description | Default |
|----------|-------------|---------|
| `MCP_TRANSPORT` | Transport: `stdio`, `sse`, `streamable-http` | `stdio` |
| `MCP_HOST` | Bind address for HTTP transports | `localhost` |
| `MCP_PORT` | Port for HTTP transports | `8000` |
| `MCP_PATH` | Path for streamable-http | `/mcp/` |
#### OAuth 2.1
| Variable | Description | Default |
|----------|-------------|---------|
| `OAUTH_ENABLED` | Enable OAuth authentication | `false` |
| `KEYCLOAK_URL` | Keycloak server URL | — |
| `KEYCLOAK_REALM` | Keycloak realm name | — |
| `KEYCLOAK_CLIENT_ID` | OAuth client ID | — |
| `KEYCLOAK_CLIENT_SECRET` | OAuth client secret | — |
| `OAUTH_RESOURCE_SERVER_URL` | Resource server URL | — |
| `OAUTH_REQUIRED_SCOPES` | Required scopes (comma-separated) | — |
| `OAUTH_VALIDATE_AUDIENCE` | Validate token audience | `true` |
| `OAUTH_VALIDATE_SCOPES` | Validate token scopes | `true` |
| `OAUTH_REQUIRE_HTTPS` | Require HTTPS for OAuth URLs | `true` |
| `CORS_ALLOWED_ORIGINS` | CORS allowed origins | `*` |
### OAuth Scopes
| Scope | Description |
|-------|-------------|
| `teradata:read` | Read access to database resources |
| `teradata:write` | Write access to database resources |
| `teradata:query` | Execute SQL queries |
| `teradata:admin` | Administrative access |
| `teradata:schema` | Schema management operations |
### Transport Compatibility
| Transport | OAuth | Discovery Endpoints | Use Case |
|-----------|-------|-------------------|----------|
| **stdio** | N/A | N/A | Claude Desktop, CLI clients |
| **SSE** | Full | Available | Web applications |
| **Streamable HTTP** | Full | Available | API integrations |
Discovery endpoints (when OAuth enabled):
- `/.well-known/oauth-protected-resource` — RFC 9728 metadata
- `/.well-known/mcp-server-info` — MCP capabilities
- `/health` — Health check
## Docker Deployment
### Development
```bash
docker compose up -d
```
### With OAuth
```bash
docker compose -f docker-compose.oauth.yml up -d
```
### Build
```bash
uv build
```
## Troubleshooting
**Database connection issues:**
- Verify `DATABASE_URI` format: `teradatasql://user:pass@host/database`
- Check network connectivity to Teradata server
- For LDAP: ensure `DB_LOGMECH=LDAP` and `DB_LOGDATA` are set correctly
- Connection issues are automatically retried (configurable via `DB_MAX_RETRIES`)
**LDAP authentication fails:**
- Verify the Teradata server has LDAP configured in TDGSS
- Check `authcid` format matches your directory type
- Escape special characters in passwords (`@` → `\@`, spaces → use quotes)
**Permission denied errors:**
- Verify user has required OAuth scopes
- Check Keycloak role assignments
- `visualize_query` requires `teradata:query` scope (not just `teradata:read`)
**Debug logging:**
```bash
export LOG_LEVEL=DEBUG
uv run teradata-mcp
```
## License
MIT License. See [LICENSE](LICENSE) for details.
## Acknowledgments
- [Model Context Protocol](https://modelcontextprotocol.io/)
- [Keycloak](https://www.keycloak.org/)
- [Teradata](https://www.teradata.com/)
- [FastMCP](https://github.com/modelcontextprotocol/python-sdk)
TDQS
Scored across 8 tools
The tools have some overlap in purpose, particularly between list_tables and show_tables_details, which both deal with table information, and between the various 'list_' statistical tools (distinct_values, missing_values, negative_values, standard_deviation) that all analyze table columns. However, the descriptions help clarify their specific focuses, such as distinct categories vs. missing values vs. negative values, preventing complete confusion.
The naming is mostly consistent with a verb_noun pattern, using 'list_' for most tools (list_db, list_distinct_values, etc.) and other clear verbs like 'query' and 'show_tables_details'. The only minor deviation is 'standard_deviation', which uses a noun phrase instead of a verb, but it still fits the overall readable style without mixing conventions like camelCase.
With 8 tools, the count is well-scoped for a database analysis server. Each tool earns its place by covering distinct aspects like database listing, table listing, SQL querying, and statistical analysis, without being too thin or overloaded for the apparent purpose of interacting with Teradata systems.
The tool surface has notable gaps for a database server. While it covers listing databases and tables, querying, and some statistical analysis, it lacks core CRUD operations like create, update, or delete for databases or tables. This could cause agent failures when trying to modify data, but the existing tools support basic querying and inspection workflows.