Skip to main content
Glama
ys1173

duckdb-iceberg-mcp

by ys1173

duckdb-iceberg-mcp

A free, local SQL query engine for FFWD's Iceberg sink, with optional MCP tools for AI agents. Configure your FFWD connection once, then query tables using a CLI, interactive shell, or MCP client. Other OAuth2 Iceberg REST catalogs are supported using the same connection settings; AWS Glue remains available as an optional backend.

DuckDB runs on your machine and reads the required metadata and data from S3. You do not need a separate hosted query service or a second copy of the lake. S3 request/transfer costs and your own compute costs still apply.

Built on the official Python MCP SDK.

What's new in v0.2.0

  • FFWD/Lakekeeper Iceberg REST support with OAuth2 client credentials and catalog-vended S3 access.

  • One-time setup from the DuckDB connection snippet copied from FFWD's UI; credentials stay in environment configuration, not queries or MCP client definitions.

  • Standalone SQL CLI and interactive shell using the same engine as the MCP tools.

  • Read-only defaults, single-statement SQL validation, bounded results, query interruption, and configurable memory/thread limits.

  • Native Iceberg scanning for Glue using its committed metadata pointer, replacing manual manifest flattening.

  • Customer setup examples, an MIT license, and automated tests on Python 3.12 and 3.13.

Start with FFWD quick start. See live verification for what has actually been tested, and configuration reference for all settings.

Related MCP server: DuckDB MCP Server

FFWD quick start

Requires Python 3.12+ and access to the FFWD catalog, OAuth endpoint, and S3 storage. On first use, DuckDB downloads its official httpfs and iceberg extensions.

1. Install locally

git clone https://github.com/ys1173/duckdb-iceberg-mcp.git
cd duckdb-iceberg-mcp
python3 -m venv .venv
source .venv/bin/activate
pip install -e .

2. Import the FFWD connection once

In FFWD, open your Data Lake Destination → Query Engine → DuckDB instructions. Use the Copy button to get the complete snippet (long endpoints may be clipped visually). Save it locally as ffwd-connection.sql, then run:

duckdb-iceberg setup --from-sql ffwd-connection.sql --env-file .env

3. Check connectivity and discover tables

duckdb-iceberg check --env-file .env
duckdb-iceberg tables --env-file .env
duckdb-iceberg describe ffwd.network.network_logs --env-file .env

4. Query using SQL, without an agent

duckdb-iceberg query --env-file .env "SELECT _ts, _event FROM ffwd.network.network_logs WHERE _event ILIKE '%dns%' ORDER BY _ts DESC LIMIT 10;"
duckdb-iceberg query --env-file .env "SELECT _ts, name, type, value, labels FROM ffwd.network.network_metric ORDER BY _ts DESC LIMIT 10;"
duckdb-iceberg shell --env-file .env

In the shell, terminate SQL with ; and use .quit to exit. Use query --file query.sql to run a file containing one statement. Replace the sample table names with names returned by tables.

5. Add optional MCP access

Point your agent's MCP client at duckdb-iceberg-mcp and the same environment file; see Connect an MCP client. The CLI works independently of MCP, and both reuse the same connection settings. Customers do not need an AI subscription or agent to use the SQL CLI.

Credential configuration

setup parses but never executes the connection snippet. It extracts the catalog endpoint, OAuth endpoint, warehouse, and catalog alias. If the key fields contain placeholders, it asks for your agent key ID and a hidden key secret once. The resulting .env is created with owner-only permissions; existing files are never overwritten. Protect or remove the original snippet if it contains credentials. Table names above are examples: discover the actual names with tables.

For unattended setup, export FFWD_CLIENT_ID and FFWD_CLIENT_SECRET first. They take precedence over values in the snippet. --from-sql - accepts the snippet on stdin; when stdin is piped, missing credentials must come from the environment.

Alternatively, copy config/ffwd.env.example to .env and fill it manually:

UI snippet field

Environment variable

ENDPOINT

FFWD_CATALOG_ENDPOINT

OAUTH2_SERVER_URI

FFWD_OAUTH_TOKEN_ENDPOINT

Value after ATTACH

FFWD_WAREHOUSE_ID

CLIENT_ID / agent key ID

FFWD_CLIENT_ID

CLIENT_SECRET / agent key secret

FFWD_CLIENT_SECRET

Set CATALOG_TYPE=rest. The default alias is ffwd; CATALOG_NAME overrides it. No separate tenant ID is needed: the UI's endpoint already includes it. Never guess or reconstruct endpoints from a cluster name.

The engine creates a non-persistent DuckDB secret and attaches the catalog on connection creation. It does not ask for credentials during queries. Environment variables override the configuration file. By default .env is resolved from the current working directory; use --env-file /absolute/path/.env or DUCKDB_MCP_ENV_FILE when an agent launches from another directory. Values are read literally, without ${VARIABLE} expansion, to preserve secrets exactly.

For example, if you already have a Glue .env, save FFWD settings separately with duckdb-iceberg setup --from-sql ffwd-connection.sql --env-file .env.ffwd and pass that path to subsequent CLI/MCP commands. Keep the file private and out of Git. When you change or rotate credentials, restart running MCP servers so they reload the configuration. Credentials are configured once, but can still expire or be revoked by your deployment.

OAuth and S3 access

Your FFWD key ID/secret authenticate to the OAuth token endpoint using client credentials. DuckDB's Iceberg extension manages catalog authentication; this is separate from any incoming MCP authentication. The default ACCESS_DELEGATION_MODE=vended_credentials uses scoped storage credentials returned by the catalog. No separate AWS keys are required when your deployment supports credential vending. DuckDB still needs network reachability to S3.

For deployments without vending, install the glue extra (which includes AWS credential support), set ACCESS_DELEGATION_MODE=none, and configure the AWS profile or keys described below. Use AWS_SESSION_TOKEN with temporary credentials. Test expiration/re-authentication with your deployment before relying on long-lived agent sessions.

check discovers tables and reads at most one row from the first table (or --table ffwd.namespace.table) without printing row contents. An empty catalog cannot prove S3 data access.

Connect an MCP client

Run duckdb-iceberg-mcp --env-file /absolute/path/.env for stdio. A Claude-style MCP configuration is:

{
  "mcpServers": {
    "ffwd-lake": {
      "command": "/absolute/path/.venv/bin/duckdb-iceberg-mcp",
      "args": ["--env-file", "/absolute/path/.env"]
    }
  }
}

Use your client's equivalent command/arguments settings; do not copy secrets into the MCP configuration. With REST catalogs the tools are list_tables, describe_table, and query_lakehouse. Tables are queried directly as ffwd.namespace.table; no glue_table registration is needed. Useful agent instruction: “Discover tables and schemas first; use explicit columns and narrow _ts time filters; never request credentials in SQL.”

An agent can call list_tables(), then describe_table("ffwd.network.network_logs"), then query_lakehouse with ordinary SQL. Reload the client after changing its MCP command/arguments. Configuration-file paths should be absolute because desktop clients may not inherit your terminal's working directory or exported environment.

How FFWD querying works

The CLI or MCP tool executes SQL in local DuckDB. DuckDB authenticates to FFWD's OAuth endpoint, attaches the Iceberg REST catalog, and obtains table metadata and delegated storage credentials. It then reads the required S3 metadata/Parquet data directly and performs the query locally. Lakekeeper is the catalog, not a remote SQL execution engine; the catalog does not proxy the S3 data reads. The default FFWD path needs neither Glue nor separate AWS keys when credential vending is enabled.

Limits and deployment safety

  • Read-only by default; single SQL statement per request. SELECT, CTEs, unions, SHOW, DESCRIBE, and read-only EXPLAIN are supported. Session-changing SET, USE, and credential DDL are blocked in read-only mode.

  • MAX_ROWS=250, MAX_CHARS=40000, QUERY_TIMEOUT_SECONDS=30, DUCKDB_MEMORY_LIMIT=1GB, and DUCKDB_THREADS=4 are configurable. Memory limits are per connection, not a whole-process guarantee; external libraries and result materialization may use additional memory. Limits on returned rows do not limit bytes scanned. Query timeout uses DuckDB interruption and is not a hard deadline for connection setup or every network operation.

  • MCP engine operations are serialized off the event loop, preventing concurrent use/eviction of active connections. Up to MAX_SESSIONS=50 connections are retained; session IDs separate state, not data permissions.

  • This is a single configured warehouse/credential per server process, not a multi-tenant authorization gateway. Even authenticated users of the same process access the same configured lake. Run separate instances/credentials for separate customer security boundaries.

  • SQL read-only checks are not a sandbox: SQL can read files and remote resources accessible to the host. Use trusted agents, least-privilege FFWD credentials, and OS/container isolation for untrusted users. HTTP defaults to localhost; require authentication and TLS before exposing it to a network. Full-mode JWT validation does not supply an OAuth login service.

  • This queries committed Iceberg snapshots, not FFWD's live ingestion buffer. Freshness depends on sink commits; performance depends on partitioning, file sizes, selected columns, and the client's network distance from S3. Prefer time filters; ORDER BY ... LIMIT 10 may still scan substantial data.

Troubleshooting: authentication errors → check your key pair and OAuth URL; catalog 403 → check FFWD authorization; S3 403 → check vending/storage permissions and network restrictions. Run check --table ... to separate catalog discovery from data reads. For FFWD onboarding, use this quick start. AWS Glue remains supported as an optional backend; its installation and configuration are documented below.

Live FFWD verification

The v0.2.0 implementation was smoke-tested against a live FFWD deployment with a Lakekeeper catalog and S3-backed Iceberg tables on October 1, 2026, using DuckDB 1.5.3. These were read-only checks, not just mocks:

  • OAuth authentication and native REST catalog attachment succeeded using the supplied FFWD agent key pair.

  • Catalog discovery found ffwd.network.network_logs and ffwd.network.network_metric.

  • A live network_logs read succeeded using catalog-vended S3 credentials, without separately configuring AWS keys.

  • A bounded _event ILIKE '%dns%' query confirmed a sample of 10 matching logs.

  • A real stdio MCP client initialized, discovered the three REST tools, listed tables, described network_logs, and executed an S3-backed query.

The local suite passed 64 tests, and GitHub Actions passed on Python 3.12 and 3.13. A fresh core-wheel installation also passed its tests without the optional Glue dependency; Glue-specific tests were skipped in that environment.

This confirms basic interoperability, not a production performance guarantee. Credential expiry/re-authentication, sustained load, large-dataset performance, and metric-table data scans were not covered by this repository's live smoke test. Customer endpoints, tenant/warehouse IDs, credentials, local MCP configuration, and returned log contents are not published in the repository.

To reproduce the live log-table check with your own configuration:

duckdb-iceberg check --env-file .env --table ffwd.network.network_logs

Use a table discovered in your own warehouse; the sample namespace is not required. GitHub CI uses synthetic credentials and local fixtures, never a customer lake.

AWS Glue architecture

                                              +----------------------+
                                              | MCP Clients          |
                                              | - OpenAI Codex       |
                                              | - Claude Desktop     |
                                              | - OpenCode           |
                                              | - LibreChat          |
                                              +----------------------+
                                                        |
                                                        | MCP Protocol (tools/list · tools/call)
                                                        v
            +--------------------------------------------------------------------------------------------+
            | duckdb-iceberg-mcp                                                                         |
            |                                                                                            |
            | +----------------------------------------------------------------------------------------+ |
            | | MCP Protocol Layer                                                                     | |
            | | stdio · Streamable HTTP · SSE                                                          | |
            | | JWT auth · write guard · row/char limits                                               | |
            | | Session pool: X-MCP-Session-ID (HTTP) · MCP_SESSION_ID (stdio) · LRU max connections   | |
            | +----------------------------------------------------------------------------------------+ |
            |                                          <-->                                              |
            | +----------------------------------------------------------------------------------------+ |
            | | ⚡ DuckDB                                                                               | |
            | | DuckDB columnar execution engine                                                       | |
            | | Vectorized execution · Direct S3 reads                                                 | |
            | | httpfs · iceberg · aws extensions                                                      | |
            | +----------------------------------------------------------------------------------------+ |
            +--------------------------------------------------------------------------------------------+
                          |                                                  |
                          | httpfs extension                                 | boto3
                          | columnar Parquet reads                           | metadata · schema
                          |                                                  | Committed metadata pointer
                          v                                                  v
            +--------------------------------------------------------------------------------------------+
            | AWS                                                                                        |
            | +-------------- Amazon S3 --------------+  +------------ AWS Glue Data Catalog ----------+ |
            | | Apache Iceberg tables                 |  | Databases · Tables · Schema                 | |
            | | Parquet data files                    |  | Iceberg metadata                            | |
            | +---------------------------------------+  +---------------------------------------------+ |
            +--------------------------------------------------------------------------------------------+

Features

  • Query FFWD/OAuth2 Iceberg REST catalogs or AWS Glue tables on S3

  • Three transports: stdio, Streamable HTTP, SSE

  • Easy mode — single-tenant, optional static API key, no IdP required

  • Full mode — JWT/JWKS token validation (Auth0, Cognito, Keycloak, Okta, …)

  • Writes disabled by default; only available in full mode with explicit opt-in

  • Configurable row and character limits to prevent runaway responses

  • Concurrent MCP client sessions — up to MAX_SESSIONS DuckDB connections (default 50), keyed by a client-supplied session id so glue_table views and connection state stay isolated when many clients share the same JWT or API key (HTTP: X-MCP-Session-ID; stdio: MCP_SESSION_ID per process)

Requirements

  • Python 3.12+

  • FFWD catalog details and an agent key pair; or AWS credentials for the optional Glue backend

Optional AWS Glue installation

FFWD users only need the installation above. Install the extra below when using Glue or separately configured AWS storage credentials.

git clone https://github.com/ys1173/duckdb-iceberg-mcp.git
cd duckdb-iceberg-mcp
python -m venv .venv
source .venv/bin/activate
pip install -e '.[glue]'

AWS Glue quick start

stdio (local AI client)

Copy the example config and fill in your AWS details:

cp config/easy.env.example .env
# .env
MCP_MODE=easy
MCP_TRANSPORT=stdio
CATALOG_TYPE=glue
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=...

Run directly:

duckdb-iceberg-mcp

Or configure in Claude Desktop or a client using the same JSON format:

{
  "mcpServers": {
    "duckdb-iceberg-mcp": {
      "command": "/path/to/.venv/bin/duckdb-iceberg-mcp",
      "env": {
        "MCP_MODE": "easy",
        "CATALOG_TYPE": "glue",
        "AWS_REGION": "us-east-1",
        "AWS_ACCESS_KEY_ID": "AKIA...",
        "AWS_SECRET_ACCESS_KEY": "...",
        "MCP_SESSION_ID": "codex-laptop-1"
      }
    }
  }
}

MCP_SESSION_ID is optional. Set a unique value per client install if the same host runs several stdio MCP servers or you want a stable pool key; if unset, the process uses the shared default session. Session behaviour for HTTP clients is documented in MCP client sessions (after Streamable HTTP below).

Streamable HTTP (network clients, e.g. LibreChat in Docker)

MCP_MODE=easy
MCP_TRANSPORT=http
MCP_HOST=0.0.0.0
MCP_PORT=8766
MCP_ALLOWED_HOSTS=host.docker.internal:*,localhost:*
CATALOG_TYPE=glue
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=...
.venv/bin/duckdb-iceberg-mcp --env-file /absolute/path/.env

MCP client URL: http://localhost:8766/mcp

See MCP client sessions (next section) for X-MCP-Session-ID, pool limits, and limitations of different MCP clients.

LibreChat (librechat.yaml):

mcpServers:
  duckdb-iceberg-mcp:
    type: streamable-http
    url: 'http://host.docker.internal:8766/mcp'
    timeout: 60000
    initTimeout: 20000

For other MCP clients, use their Streamable HTTP connection settings with URL http://localhost:8766/mcp.

MCP client sessions

The server keeps one DuckDB connection per session id, not per JWT subject. That way LibreChat, Codex, and other clients can share the same credential but not clobber each other’s registered views from glue_table.

Transport

How the session id is chosen

If missing

Streamable HTTP / SSE

Client sends HTTP header X-MCP-Session-ID (rename via MCP_SESSION_HEADER). Use a stable string per logical client (e.g. UUID). Allowed characters: letters, digits, ., _, -; length 1–128. Invalid values return HTTP 400.

All requests share the default connection.

stdio

Set env MCP_SESSION_ID on that client’s MCP config (one process per client is typical).

Same as empty: default.

Pool limit: When the number of distinct session ids exceeds MAX_SESSIONS, the least recently used connection is closed and removed.

Client support: Not every MCP UI can add custom headers. If yours cannot, those clients share default unless you run separate server instances (different URL or host) per client.

The glue_table tool is per session — each client typically needs to register a table in its own session before query_lakehouse can use the view.


AWS Authentication

Configure credentials using one of these methods (key/secret takes priority if both are set):

Method

Env vars

Explicit credentials

AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY

Named profile

AWS_PROFILE=my-profile

Default chain

Set neither — falls back to env vars, ~/.aws/credentials, instance role


MCP Tools

list_tables(database?)

Lists available catalog tables. For REST/FFWD, database filters by catalog alias (normally ffwd). For Glue, it filters by Glue database name.

describe_table(table_name)

For REST/FFWD, returns column names, DuckDB types, and nullability; use ffwd.namespace.table. For Glue, returns catalog columns/types and partition-key information; use database.table.

glue_table(table_name)

Available only with CATALOG_TYPE=glue; FFWD REST tables need no registration.

Registers a Glue Iceberg table as a native iceberg_scan DuckDB view using Glue's committed metadata_location. The engine does not guess the latest metadata filename or flatten manifests into raw Parquet scans. Re-register the view to pick up a new committed metadata pointer. Tables without a committed pointer are rejected.

Registrations are scoped to the current MCP session (see MCP client sessions). A new session must call glue_table again before querying that view.

glue_table('mydb.mytable')
→ Registered view 'mydb__mytable'. Query with: SELECT * FROM mydb__mytable

query_lakehouse(sql)

Executes one SQL statement. FFWD tables can be queried directly by fully qualified name, such as SELECT _ts, _event FROM ffwd.network.network_logs LIMIT 10. Glue can use registered views or explicit Iceberg metadata paths. Results are CSV text with truncation notices when applicable.


Configuration Reference

Variable

Default

Description

MCP_MODE

easy

easy or full

MCP_TRANSPORT

stdio

stdio, http (Streamable HTTP), sse

MCP_HOST

127.0.0.1

Bind address for HTTP/SSE

MCP_PORT

8000

Port for HTTP/SSE

MCP_ALLOWED_HOSTS

(empty)

Comma-separated allowed Host headers (e.g. host.docker.internal:*,localhost:*). Empty = SDK default

MCP_API_KEY

(empty)

Static bearer token for easy mode HTTP. Empty = no auth

JWKS_URL

(required in full mode)

JWKS endpoint for JWT validation

JWT_AUDIENCE

duckdb-mcp

Expected aud claim in JWTs

CATALOG_TYPE

glue

rest for FFWD; glue for AWS Glue

DUCKDB_MCP_ENV_FILE

(empty)

Explicit environment-file path; CLI --env-file takes precedence

CATALOG_NAME

ffwd

REST catalog SQL alias

FFWD_CATALOG_ENDPOINT

(required for REST)

Complete endpoint copied from FFWD UI

FFWD_OAUTH_TOKEN_ENDPOINT

(required for REST)

Complete OAuth token URL

FFWD_WAREHOUSE_ID

(required for REST)

Warehouse identifier from ATTACH

FFWD_CLIENT_ID

(required for REST)

Agent key ID

FFWD_CLIENT_SECRET

(required for REST)

Agent key secret; keep private

ACCESS_DELEGATION_MODE

vended_credentials

Set none only when configuring separate AWS storage credentials

QUERY_TIMEOUT_SECONDS

30

DuckDB query interruption timeout

DUCKDB_MEMORY_LIMIT

1GB

DuckDB memory limit per connection

DUCKDB_THREADS

4

Threads per connection

AWS_REGION

us-east-1

AWS region

AWS_PROFILE

(empty)

Named AWS profile

AWS_ACCESS_KEY_ID

(empty)

AWS access key

AWS_SECRET_ACCESS_KEY

(empty)

AWS secret key

AWS_SESSION_TOKEN

(empty)

Session token when using temporary AWS credentials

WRITE_MODE

disabled

disabled or enabled. Always disabled in easy mode

MAX_SESSIONS

50

Max concurrent DuckDB connections per server process, keyed by session id (HTTP header or stdio env). LRU closes evicted connections

MCP_SESSION_HEADER

X-MCP-Session-ID

HTTP header name for the client session id

MCP_SESSION_ID

(empty)

stdio only: fixed session key for this process (defaults to shared default if empty)

MAX_ROWS

250

Maximum rows returned per query

MAX_CHARS

40000

Maximum characters in a query response


Full Mode (JWT Auth)

Full mode validates a JWT bearer token on every request. Session isolation is by X-MCP-Session-ID (not by JWT sub), so many clients can share the same credential while keeping separate DuckDB connections up to MAX_SESSIONS.

MCP_MODE=full
MCP_TRANSPORT=http
MCP_HOST=0.0.0.0
MCP_PORT=8766
JWKS_URL=https://your-idp.example.com/.well-known/jwks.json
JWT_AUDIENCE=duckdb-mcp
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=...

The client passes a JWT as Authorization: Bearer <token>. The server validates it against the JWKS endpoint. Any IdP that issues standard JWTs works (Auth0, AWS Cognito, Keycloak, Okta).

See config/full.env.example for a full template.


Smoke Test

For FFWD, verify catalog discovery and a bounded S3-backed read without displaying row contents:

duckdb-iceberg check --env-file .env --table ffwd.network.network_logs

The compatibility script uses the same CLI engine:

.venv/bin/python scripts/smoke_test.py --env-file .env --table ffwd.network.network_logs

For the optional Glue backend, configure config/easy.env.example and specify a Glue table:

cp config/easy.env.example .env  # fill in AWS credentials
.venv/bin/python scripts/smoke_test.py --env-file .env --table your_database.your_table

Run Tests

pip install -e ".[dev,glue]"
pytest

Unit tests use synthetic credentials and local tables/mocks. GitHub Actions runs them on Python 3.12 and 3.13 without accessing a customer lake. Use duckdb-iceberg check for a live deployment test. Supported DuckDB series: 1.5.x (minimum 1.5.3).

License

MIT; see LICENSE.

Available Tools

4 tools
describe_tableB

Describe a table's schema. Use 'database.table' format for Glue.

ParametersJSON Schema
NameRequiredDescriptionDefault
table_nameYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, and the description only states the purpose. It does not disclose behavioral traits beyond being a read operation, such as error handling or required permissions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no wasted words. The purpose and a key usage hint are front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has only one parameter and an output schema, reducing the need for extensive description. However, without annotations, the description lacks safety and error context, making it minimally complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema coverage is 0%, so the description must compensate. It adds a formatting hint for table_name, which adds meaning beyond the schema's title, but does not provide full semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states it describes a table's schema, which is a specific verb+resource. It does not explicitly differentiate from sibling tools like glue_table, but the purpose is clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a formatting hint for the parameter ('Use 'database.table' format for Glue'), but does not provide guidance on when to use this tool versus siblings or when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

glue_tableA

Register a Glue Iceberg table as a queryable DuckDB view.

Resolves the actual data files from the Iceberg manifest (handles tables where data files live outside the Glue-registered table root).

Usage: glue_table('database.table_name') After calling this, query with: SELECT * FROM database__table_name

ParametersJSON Schema
NameRequiredDescriptionDefault
table_nameYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so description carries full burden. It discloses that the tool resolves actual data files from Iceberg manifest and handles non-standard data locations. It also indicates the side effect of creating a view. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is six lines, each adding unique value: main action, behavioral details, usage syntax, and post-call query example. No redundant or filler content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of registering a view and the presence of an output schema (though not shown), the description covers the essential behavioral and usage aspects. It could mention what the tool returns, but output schema likely fills that gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description compensates by specifying the parameter format 'database.table_name'. The input schema only has a title 'Table Name', so description adds significant meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool registers a Glue Iceberg table as a queryable DuckDB view, with specific verb 'Register' and resource 'Glue Iceberg table'. It also explains it resolves data files from Iceberg manifest, distinguishing it from siblings like describe_table or list_tables.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit usage syntax 'glue_table('database.table_name')' and post-call query example 'SELECT * FROM database__table_name'. It implicitly guides when to use this tool, but does not explicitly state when not to use or mention alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_tablesA

List available tables. Optionally filter by database name.

ParametersJSON Schema
NameRequiredDescriptionDefault
databaseNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It states the main action and filtering option but does not disclose any behavioral traits such as permissions, performance implications, or edge cases (e.g., empty result). It is minimally adequate for a simple listing tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise with a single sentence that front-loads the main action. Every word earns its place, with no superfluous text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simplicity (1 optional param, output schema exists), the description is fairly complete. It covers the core functionality and filtering. However, it could clarify the scope of 'tables' (e.g., database tables versus other entities) to enhance completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema coverage is 0%, so the description must add meaning. It explains that the 'database' parameter is optional and filters results, which adds value beyond the schema. However, it does not specify the expected format or behavior when the parameter is empty.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('List available tables') and resource, and mentions optional filtering. It is distinct from sibling tools like describe_table and query_lakehouse.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus alternatives like describe_table or query_lakehouse. Implicit usage context is minimal.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

query_lakehouseA

Execute a SQL query. Use read_parquet() or iceberg_scan() for S3 paths, or use the glue_table tool first to register a Glue table by name.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It only states 'Execute a SQL query' without detailing important traits like whether it is read-only, destructive, authentication requirements, rate limits, or error handling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise, with two sentences that front-load the purpose and provide actionable tips. No unnecessary words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has a single parameter and an output schema (so return format need not be described), the description is fairly complete. It covers the main action and usage hints, but could add minor details about potential errors or timeouts.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has one parameter (sql) with no description, but the tool description adds meaning by specifying it should be a SQL query and suggests using certain functions for different data sources. This compensates for the lack of schema documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool executes a SQL query, which is the primary action. It differentiates from siblings by suggesting a workflow involving glue_table for Glue tables, but could be more explicit about what distinguishes this tool from similar ones.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides usage guidance: use read_parquet() or iceberg_scan() for S3 paths, or use glue_table first for Glue tables. This gives context on how to use the tool effectively, though it does not explicitly state when not to use it or list alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv0.1.0
    • First observeddescribe_table
    • First observedglue_table
    • First observedlist_tables
    • First observedquery_lakehouse

TDQS

A3.7/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a distinct purpose: describe_table shows schema, glue_table registers a view, list_tables enumerates tables, and query_lakehouse executes SQL. No overlap in functionality.

Naming Consistency3/5

Most names follow verb_noun (describe_table, list_tables, query_lakehouse), but 'glue_table' is a noun_noun that breaks the pattern, introducing inconsistency.

Tool Count5/5

Four tools cover the essential operations for an Iceberg query server: listing, describing, registering, and querying tables. This is minimal but well-scoped for the stated domain.

Completeness3/5

The server supports read and schema-discovery operations but lacks write or lifecycle management tools (e.g., create, delete, update). This is acceptable for a query-focused tool but leaves gaps for full table management.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    B
    quality
    D
    maintenance
    A Model Context Protocol server that provides a SQL interface for querying and managing Apache Iceberg tables through Claude desktop, allowing natural language interaction with Iceberg data lakes.
    1
    8
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    A Model Context Protocol server implementation that connects AI assistants to DuckDB, enabling them to query and analyze data from various sources including CSV, Parquet, JSON, and cloud storage through SQL.
    18
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to query S3 data lakes using natural language, with support for CSV, JSON, Parquet and tools for data discovery, analysis, and metadata exploration.
    1
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables natural language querying of Snowflake-managed Iceberg tables via Horizon IRC and DuckDB, without using a Snowflake warehouse.
    -