Skip to main content
Glama
jasperan

OraViz MCP

by jasperan

OraViz MCP is pab1it0/adx-mcp-server reimagined for Oracle AI Database -- a deliberately tiny alternative to the broad official Oracle MCP servers. It speaks SQL, profiles tables, and turns result sets into PNG charts any MCP client can show. Seven tools, read-only, no Oracle client libraries (python-oracledb thin mode talks straight to Oracle AI Database 26ai Free or any newer release).

Two ideas shape everything:

  • Visualization first. The headline tool runs your query and returns an actual chart image plus a short data preview -- not a wall of rows.

  • Context engineering. Agents pay for every token a tool returns, so OraViz never dumps a result set. Results are preview-capped, rendered as one compact markdown table with a metadata header, and large values (CLOB, BLOB, VECTOR) are summarised.

Visualization at a Glance

Related MCP server: Oracle ADB AI Agent MCP Server

Why OraViz?

  • Charts, not query dumps -- create_chart renders bar, line, area, scatter, pie, and histogram charts with an Oracle-red palette and returns the PNG as MCP image content.

  • Context-engineered results -- bounded previews with explicit truncated metadata, one header per table instead of repeated JSON keys, CLOB/BLOB/VECTOR summarised, per-cell truncation.

  • Profile before you plot -- profile_table returns per-column nulls, distinct counts, min/max/avg so the model can pick the right chart without fetching rows.

  • Read-only by design -- validation admits a single SELECT/WITH statement (DDL, DML, and PL/SQL are rejected before connecting), every query is stopped by ORACLE_CALL_TIMEOUT, and row and cell caps apply everywhere. The guard is lexical; for a hard boundary, point OraViz at a read-only database account.

  • Minimal surface -- 7 tools, ~600 statements of source, stdio/http/sse/streamable-http transports, structured JSON logs on stderr (stdout stays clean for stdio).

  • Zero client install -- python-oracledb thin mode; no Oracle Instant Client, no ORACLE_HOME, no tnsnames.

The Context Contract

Every row-returning tool follows the same rules, and the test suite asserts them:

Rule

Default

Env knob

Query preview size (execute_query without max_rows)

25 rows

ORACLE_MCP_PREVIEW_ROWS

Hard row cap per query (charts included)

500 rows

ORACLE_MCP_MAX_ROWS

Longest cell before ... truncation

500 chars

ORACLE_MCP_MAX_CELL_CHARS

Statement timeout

60 s

ORACLE_CALL_TIMEOUT

Metadata header per result

<n> row(s) (truncated; more rows exist) | columns: A, B

--

A tool result therefore looks like this instead of a 25-dictionary JSON array:

4 row(s) | columns: REGION, REVENUE

| REGION | REVENUE |
|---|---|
| East | 573932 |
| North | 502897 |
| South | 432190 |
| West | 360759 |

Weird values compress instead of exploding: CLOB renders as text (truncated), BLOB as <binary 1234 bytes>, VECTOR(384) as <VECTOR(384)>, midnight timestamps as dates. When the model really needs raw rows it can pass max_rows explicitly -- and the server still stops at the hard cap.

Tools

Tool

Returns

Context cost

execute_query

Read-only SQL result as a compact markdown table (preview-capped)

Bounded by preview cap

list_tables

Tables and views in the current (or a given) schema

One small table

get_table_schema

Columns, types, length, nullability, primary-key membership

One small table

sample_table_data

First rows of a table

sample_size (default 10)

get_table_details

Owner, tablespace, optimizer stats (NUM_ROWS, LAST_ANALYZED), optional exact row count

Single row

profile_table

Per-column stats: non-null, nulls, distinct, min, max, avg

~1 line per column

create_chart

PNG chart image + short data preview

Image + ≤5 preview rows

How create_chart maps columns

The first column is the x-axis (or the labels for pie charts); numeric columns after it become series. That makes the chart contract simple and SQL-driven:

SELECT region, ROUND(SUM(revenue), 2) AS revenue
FROM sales_demo
GROUP BY region
ORDER BY revenue DESC
create_chart(sql=..., chart_type="bar", title="Revenue by region")
  • bar / line / area -- label column plus one or more numeric series (up to 8 series; bar values are annotated when the chart is small)

  • scatter -- first two numeric columns

  • pie -- label column plus one numeric column; more than 12 slices are grouped into "Other"

  • histogram -- the first numeric column, auto-binned

Quick Start

1. Start Oracle AI Database 26ai Free

# Standalone
docker run -d --name oraviz-oracle -p 1530:1521 \
  -e ORACLE_PWD=OraViz2026 \
  container-registry.oracle.com/database/free:latest

# Or with the bundled compose file (.env needs ORACLE_PASSWORD=...)
docker compose up -d

The container takes a couple of minutes to initialize. docker ps shows (healthy) when it is ready.

2. (Optional) Load the demo schema

examples/demo-sales.sql creates a demo user, a 96-row SALES_DEMO table (12 months, 4 regions, 2 channels), and a 6-row PRODUCT_VECTORS table so 26ai vector columns can be inspected too. All values are deterministic.

docker exec -i oraviz-oracle sqlplus -S system/OraViz2026@//localhost:1521/FREEPDB1 <<'SQL'
CREATE USER oraviz IDENTIFIED BY "OraViz2026" DEFAULT TABLESPACE USERS QUOTA UNLIMITED ON USERS;
GRANT CONNECT, RESOURCE TO oraviz;
SQL

docker exec -i oraviz-oracle sqlplus -S oraviz/OraViz2026@//localhost:1521/FREEPDB1 \
  < examples/demo-sales.sql

3. Point your MCP client at the server

{
  "mcpServers": {
    "oraviz": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/jasperan/oraviz-mcp", "oraviz-mcp"],
      "env": {
        "ORACLE_USER": "oraviz",
        "ORACLE_PASSWORD": "OraViz2026",
        "ORACLE_DSN": "localhost:1530/FREEPDB1"
      }
    }
  }
}
{
  "mcpServers": {
    "oraviz": {
      "command": "uv",
      "args": ["--directory", "/path/to/oraviz-mcp", "run", "oraviz-mcp"],
      "env": {
        "ORACLE_USER": "oraviz",
        "ORACLE_PASSWORD": "OraViz2026",
        "ORACLE_DSN": "localhost:1530/FREEPDB1"
      }
    }
  }
}
docker build -t oraviz-mcp .
{
  "mcpServers": {
    "oraviz": {
      "command": "docker",
      "args": ["run", "--rm", "-i", "--network", "host",
               "-e", "ORACLE_USER", "-e", "ORACLE_PASSWORD", "-e", "ORACLE_DSN",
               "oraviz-mcp"],
      "env": {
        "ORACLE_USER": "oraviz",
        "ORACLE_PASSWORD": "OraViz2026",
        "ORACLE_DSN": "localhost:1530/FREEPDB1"
      }
    }
  }
}

--network host lets the container reach the database on the host (on Docker Desktop, host.docker.internal also works). Drop both if the database is reachable on the container network.

4. Ask for a chart

"Profile the SALES_DEMO table, then chart total revenue by region."

The model will call profile_table, pick a chart type, run create_chart, and you get a rendered image back.

Configuration

Variable

Description

Default

ORACLE_USER

Database user (required)

--

ORACLE_PASSWORD

Password for the user (required)

--

ORACLE_HOST

Database hostname

localhost

ORACLE_PORT

Listener port

1521

ORACLE_SERVICE

Service name

FREEPDB1

ORACLE_DSN

Full EZConnect descriptor; overrides host/port/service

--

ORACLE_CONFIG_DIR

Wallet config directory (Autonomous Database / mTLS)

--

ORACLE_WALLET_LOCATION

Wallet location

--

ORACLE_WALLET_PASSWORD

Wallet password

--

ORACLE_MCP_PREVIEW_ROWS

Default preview size for execute_query

25

ORACLE_MCP_MAX_ROWS

Hard row cap per query

500

ORACLE_MCP_MAX_CELL_CHARS

Per-cell truncation limit

500

ORACLE_CONNECT_TIMEOUT

TCP connect timeout, seconds

10

ORACLE_CALL_TIMEOUT

Per-statement timeout, seconds (0 disables)

60

ORACLE_MCP_SERVER_TRANSPORT

stdio (default), http, sse, streamable-http

stdio

ORACLE_MCP_BIND_HOST

Bind host for network transports

127.0.0.1

ORACLE_MCP_BIND_PORT

Bind port for network transports

8080

LOG_FORMAT

json (default) or console for human-readable logs

json

LOG_LEVEL

structlog level number

20 (INFO)

Copy .env.template to .env -- the server loads it via python-dotenv.

The network transports (http, sse, streamable-http) have no built-in authentication. Keep the default 127.0.0.1 bind, or put an authenticating proxy in front of the port before exposing it.

Architecture

oraviz-mcp
  src/oraviz_mcp/
    server.py          # FastMCP app, config, Oracle client, validation, the 7 tools
    charts.py          # pure matplotlib rendering (bar/line/area/scatter/pie/histogram -> PNG bytes)
    main.py            # entry point: env validation, transport selection
  tests/
    test_config.py     # config dataclasses + env parsing
    test_validation.py # SQL guard, identifiers, formatting, result rendering
    test_charts.py     # every chart type + validation errors
    test_server_tools.py  # all tools against a scripted fake cursor
    test_main.py       # entry point
    integration/       # live Oracle tests (skipped without ORAVIZ_TEST_DSN)
  examples/demo-sales.sql
  docs/testing.md

Data flow: the MCP client calls a tool -> server.py validates (validate_query / validate_table_name) -> python-oracledb thin connection -> rows are narrowed (fetch cap) -> either rendered as a compact table (render_rows) or handed to charts.py -> the model receives text, or an image plus a short preview.

Development

uv sync --extra dev          # install everything (matplotlib, fastmcp, oracledb, pytest)
uv run pytest                # hermetic unit suite (~98% line coverage; the 90% gate is enforced)
uv run pytest -k chart       # focus on one area

# Live integration tests against the 26ai Free container from Quick Start
ORAVIZ_TEST_DSN=localhost:1530/FREEPDB1 \
ORAVIZ_TEST_USER=oraviz \
ORAVIZ_TEST_PASSWORD=OraViz2026 \
uv run pytest tests/integration -v --no-cov

docker build -t oraviz-mcp . # container build (multi-stage, non-root)

See docs/testing.md and tests/README.md for the testing story.

OraViz vs. the official Oracle MCP servers

Oracle ships rich, general-purpose MCP servers -- SQLcl's built-in MCP server (run-sql, connect, schema-information, ...), ORDS MCP, the OCI Database Tools MCP, and the reference servers in oracle/mcp. Use those when you need breadth: DDL, transactions, RAC, RAG pipelines.

OraViz is the opposite bet: seven tools, read-only SQL, and a hard focus on turning data into pictures without flooding the model's context. If you want the database operated, use the official servers. If you want the database seen, use this one.

Benchmarks

We measured the tokens an agent must process to answer the same questions through OraViz and through the official SQLcl MCP server, against the same 26ai Free database (tiktoken cl100k_base: tool schemas plus every tool result):

Stage

OraViz

SQLcl MCP

Savings

Tool schemas (read once per session)

844

2,139

60.5%

Schema discovery

69

354

80.5%

Full 96-row dump

825

2,136

61.4%

Whole workflow (5 questions)

2,319

5,006

53.7%

The 10-row sample step trades ~55% more framing tokens than raw CSV, and that overhead cannot grow with the result size. Rendering the aggregate as a chart costs 123 text tokens plus the PNG image. Full methodology, step-by-step numbers, and reproduction commands: benchmarks/. The full write-up is in paper/paper.pdf, the results deck in slides/, and a live showcase at jasperan.github.io/oraviz-mcp.

Credits

License

MIT -- see LICENSE.


GitHub&nbsp; LinkedIn&nbsp; Oracle

Available Tools

7 tools
create_chartCreate ChartA

Runs a read-only SQL query and renders the result as a chart image (PNG). chart_type is one of: bar, line, area, scatter, pie, histogram. The first column is the x-axis or labels; numeric columns after it become series. Returns the image plus a data preview.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYes
titleNo
x_labelNo
y_labelNo
chart_typeYes

TDQS

A3.9/5.0
Behavior3/5

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

With no annotations provided, the description carries the burden of behavioral disclosure. It does disclose that the query is read-only and that the output is an image plus a data preview, which is helpful. It stops short of describing limitations, error behavior, or how the image is represented.

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?

Three compact sentences deliver high-value information without filler. The read-only and chart-image purpose is front-loaded, followed by chart types and column mapping, then the return payload.

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 description covers the core invocation details and return payload, but no output schema exists and the description does not specify how the PNG image is delivered (URL, base64, file path). It also leaves the label parameters undocumented, so the definition is workable but not fully complete.

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?

Schema coverage is 0%, so the description must compensate. It adds important meaning: the list of valid chart_type values, how columns map to axes and series, and the read-only nature of the sql parameter. The optional title, x_label, and y_label parameters are left to inference, but their names are largely self-explanatory.

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 states a specific action: run a read-only SQL query and render the result as a PNG chart. It clearly distinguishes itself from sibling tools like execute_query by emphasizing chart generation, not just raw query results.

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 intended use is implied: use this tool when you need a visual chart from SQL results. However, it does not explicitly say when to prefer this over execute_query or other sibling tools, nor does it mention any exclusions.

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

execute_queryExecute QueryA

Executes a read-only SELECT/WITH query and returns a compact markdown table plus a metadata line (row count, and whether more rows exist). Results are preview-capped by default to protect the caller's context: aggregate in SQL and only pass max_rows when the raw rows are really needed. Large cell values are summarised.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYes
max_rowsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden. It explicitly states read-only behavior, preview-capping, and summarisation of large cells, which are key behavioral traits. It also explains the rationale (protect caller's context). Missing details like error handling or timeout are minor for a query 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 concise (three sentences) and well-structured: purpose and return format first, then usage tips. Every sentence earns its place, and the key information about preview-capping is front-loaded. No fluff or repetition.

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?

The tool has an output schema, so return format is partly covered, but the description still explains the markdown table and metadata. It covers the essential aspects: read-only, preview cap, and summarisation. It lacks info on error behavior or limits, but for a straightforward query tool this is acceptable.

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?

Schema description coverage is 0%, so the description must compensate. It explains max_rows' purpose (when to pass it) but does not describe the 'query' parameter beyond implying SELECT/WITH syntax. The query is self-explanatory as a string, but the parameter semantics are not fully fleshed out for a schema that offers no descriptions.

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 executes read-only SELECT/WITH queries and returns a markdown table with metadata. This distinguishes it from sibling tools like list_tables or sample_table_data, which serve different purposes. The verb 'executes' and resource 'query' are specific and unambiguous.

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 provides practical usage guidance (e.g., aggregate in SQL, only pass max_rows when needed) but does not explicitly differentiate when to use this tool versus alternatives like sample_table_data. The context of being the primary query tool is implied, but not stated as a rule or recommendation.

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

get_table_detailsGet Table DetailsA

Retrieves table details: owner, tablespace, optimizer statistics (NUM_ROWS, BLOCKS, AVG_ROW_LEN, LAST_ANALYZED) and, optionally, an exact row count.

ParametersJSON Schema
NameRequiredDescriptionDefault
table_nameYes
exact_row_countNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior3/5

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

With no annotations provided, the description must carry the behavioral burden. It does disclose that exact_row_count is optional and that statistics are returned by default, which is useful. However, it does not mention potential performance costs of exact_row_count, permission requirements, or error behavior. It adds some value but not the full transparency expected without annotations.

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 a single, efficient sentence that front-loads the main action and lists specific details. There is no fluff or repetition, and every word adds value.

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?

For a tool with two parameters and an output schema, the description is mostly complete. It specifies what data is returned and the optional flag. The only minor gap is the lack of notes on the cost or implications of exact_row_count, but this is not critical for basic use given the output schema exists.

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?

Schema description coverage is 0%, so the description must compensate. It explicitly explains that exact_row_count yields an exact count instead of statistics, which goes beyond the bare boolean type. table_name is self-evident from its name, so the description covers the key parameter semantics adequately.

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 verb 'Retrieves' and the specific resource 'table details', listing the exact fields (owner, tablespace, optimizer statistics, optional row count). This distinguishes it from siblings like get_table_schema (schema structure) and profile_table (data profiling). The purpose is unambiguous and not a tautology.

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?

The description gives no guidance on when to use this tool versus alternatives. It does not mention, for example, 'use this instead of get_table_schema when you need statistics' or any exclusions. The agent is left to infer usage purely from the tool's name and description, which is minimal.

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

get_table_schemaGet Table SchemaA

Retrieves the schema of a table or view as a compact markdown table: column name, data type, length, nullability, and whether the column is part of the primary key.

ParametersJSON Schema
NameRequiredDescriptionDefault
table_nameYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior3/5

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

With no annotations, the description must disclose behavior. It states it returns a compact markdown table with specified fields, implying a read-only operation. However, it does not mention potential failure modes (e.g., nonexistent table), whether the result is ordered, or any access requirements. For a simple retrieval tool this is adequate but not rich.

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 a single, well-structured sentence that front-loads the action ('Retrieves the schema') and then details the output fields. There is no redundancy or filler; every clause earns its place.

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?

For a simple tool with one parameter and an existing output schema, the description is mostly complete. It tells what is returned and covers both tables and views. The only minor gap is not addressing error behavior or naming conventions, but these are not critical for a straightforward retrieval tool.

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

Parameters2/5

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

The schema has no descriptions for the single parameter 'table_name', and the description does not compensate. It does not specify whether the name should be fully qualified, case-sensitive, or how to reference views versus tables. With 0% schema coverage, the description carries the full burden and fails to add any parameter-level 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 retrieves the schema of a table or view, and specifies the exact components returned (column name, data type, length, nullability, primary key). This is a specific verb-resource pair that distinguishes it from siblings like get_table_details (which likely covers more than schema) and list_tables (which lists tables). The markdown format is an extra clarifying detail.

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 is provided on when to use this tool versus alternatives such as get_table_details or execute_query. There is no mention of prerequisites, limitations, or scenarios where another tool would be more appropriate. The agent must infer usage from the tool name alone.

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

list_tablesList TablesA

Retrieves a list of all tables and views available in the configured Oracle schema as a compact markdown table. Optionally takes a schema name.

ParametersJSON Schema
NameRequiredDescriptionDefault
schemaNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior3/5

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

With no annotations, the description carries the burden of behavior disclosure. It communicates a read-only operation through 'Retrieves' and is open about the markdown output, but it doesn't mention permissions, auth needs, errors, or that no data is materially changed. This is acceptable for a listing tool but not rich.

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?

One sentence front-loads the core action and output format, then adds optional parameter detail. No filler redundancy or repeated title 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?

The tool is simple with one optional parameter and an output schema present. The description covers purpose, scope, output format, and parameter optionality, which is nearly complete. The main missing piece is explicit behavior for providing versus omitting schema name, but this is minor at this complexity.

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?

Schema coverage is 0% and the description was at least notes 'Optionally takes a schema name', which clarifies that schema is optional and what it refers to. However, it does not explain how the optional schema interacts with the configured schema or list filtering, and the property name already indicates 'schema', so the description adds limited semantic value.

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 ('Retrieves a list'), the resource ('all tables and views'), the context ('configured Oracle schema'), and the output format ('compact markdown table'). It distinguishes naturally from siblings like get_table_schema, which targets a single table, and execute_query, which runs ad-hoc SQL.

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 intended use in this case is implied by the purpose: use when you need to enumerate tables/views. The sibling tool names add context, but the description offers no explicit guidance on when to choose it over alternatives, 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.

profile_tableProfile TableB

Profiles a table for visualization: row count plus per-column statistics (non-null count, distinct count, min, max, average) to decide which chart fits the data.

ParametersJSON Schema
NameRequiredDescriptionDefault
columnsNo
table_nameYes
max_columnsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.3/5.0
Behavior2/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure, but it does not state whether the tool is read-only, how expensive it could be, or how it handles empty/missing data. It lists outputs, but important behavioral traits like modification safety, performance, or error conditions are left unstated.

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?

A single, tightly worded sentence packs a clear purpose and the core delivered statistics. There is no fluff—every word adds signal: it says what, what what purpose, and what kind of output.

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

Completeness2/5

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

The description covers the high-level goal but does not explain the parameter semantics or usage boundaries, which matters because the schema descriptions are empty. Even though an output schema exists, the tool cannot be reliably invoked with just this description plus schema.

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

Parameters1/5

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

Schema coverage is 0%, so the description should compensate by explaining the three parameters. It only vaguely implies table_name via 'Profiles a table' and never explains columns or max_columns, including optionality, defaults, or effects. This is a critical gap for correct invocation.

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's specific function: profiling a table for visualization with row count and per-column statistics to guide chart selection. It distinguishes the tool from siblings like sample_table_data or get_table_schema by emphasizing the analytical/statistical output and visualization intent.

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?

It gives clear context: this is used to determine an appropriate chart by inspecting table characteristics. It does not explicitly name alternatives or when not to use it, so it stops short of a 5, but the intended use case is sufficiently communicated.

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

sample_table_dataSample Table DataA

Retrieves a small sample of rows from the specified table as a compact markdown table. sample_size controls how many rows to return (default: 10, capped by the server).

ParametersJSON Schema
NameRequiredDescriptionDefault
table_nameYes
sample_sizeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

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

Annotations are absent, so the description carries the full burden of behavioral disclosure. It discloses that only a small sample is returned, that rows come as a markdown table, and that sample_size defaults to 10 and is server-capped. However, it doesn't state whether the sample is deterministic/random, whether the operation is read-only (though 'retrieves' implies so), or how errors like non-existent tables or permission failures behave. Adequate but not complete.

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 filler. The main purpose and output format are front-loaded; the parameter behavior follows in the second sentence. Everything present contributes necessary information, and no word is wasted.

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?

With an output schema available and a simple two-parameter input, the description covers the core behavior, sample mechanism, output format, and the default/cap behavior of sample_size. It is complete enough for an agent to successfully call the tool for a quick preview. The only missing-piece is a clarification about how this differs from execute_query when both could return rows, but that is more of an usage guideline than a completeness 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?

Schema description coverage is 0%, so the description must compensate. It clearly defines sample_size's effect ('controls how many rows to return'), the default (10), and server cap. It correctly identifies table_name as 'the specified table'. This adds meaningful semantics beyond the bare integer/string types. Slight gap: it does not specify table_name formatting or whether sample_size is inclusive or capped at a hard maximum.

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 states a clear, specific action ('Retrieves a small sample of rows'), names the resource ('from the specified table'), and specifies the output format ('compact markdown table'). This is distinct from siblings like list_tables (lists table names), get_table_details (metadata), and profile_table (statistics); even execute_query is clearly different in scope ('a small sample' vs arbitrary query results). There is no ambiguity about what the tool does.

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 implies usage for quick data previews but does not explicitly say when to choose this over execute_query or get_table_details. It states that sample_size is capped by the server, but it does not provide scenarios or compare to full-query retrieval, leaving the 'instead of' guidance to inference.

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. 7 tool updatesv0.1.0
    • First observedcreate_chart
    • First observedexecute_query
    • First observedget_table_details
    • First observedget_table_schema
    • First observedlist_tables
    • First observedprofile_table
    • First observedsample_table_data

TDQS

A3.9/5.0

Scored across 7 tools

Disambiguation4/5

Most tools target clearly distinct operations, but a few boundaries require careful reading: create_chart and execute_query both run SQL, and get_table_details and get_table_schema both describe table metadata. The descriptions clarify the outputs enough that an agent should usually pick correctly.

Naming Consistency5/5

All tool names follow a consistent snake_case verb_noun pattern: execute_query, list_tables, get_table_schema, sample_table_data, get_table_details, profile_table, create_chart. The naming is predictable and uniform across the set.

Tool Count5/5

Seven tools is well-scoped for an Oracle exploration and visualization server. Each tool serves a distinct discovery or charting purpose without unnecessary bloat or missing core functionality.

Completeness4/5

The server covers the full exploration-to-visualization workflow: listing objects, inspecting schema, sampling data, profiling columns, running queries, and creating charts. Minor gaps exist, such as no table DDL viewer or chart configuration options, but an agent can accomplish the intended tasks without dead ends.

Related MCP Connectors

Related MCP Servers