Skip to content

Commit 5cb9b84

Browse files
authored
Merge pull request #178 from Teradata/docs/restructure-and-fix-fstrings
Docs/restructure and fix fstrings
2 parents 95f81aa + 9eff21a commit 5cb9b84

File tree

5 files changed

+36
-17
lines changed

5 files changed

+36
-17
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Configure the claude_desktop_config.json (Settings>Developer>Edit Config) by add
4242
"mcpServers": {
4343
"teradata": {
4444
"command": "uvx",
45-
"args": ["teradata-mcp-server", "--profile", "all"],
45+
"args": ["teradata-mcp-server"],
4646
"env": {
4747
"DATABASE_URI": "teradata://<USERNAME>:<PASSWORD>@<HOST_URL>:1025/<USERNAME>"
4848
}

docs/developer_guide/DEVELOPER_GUIDE.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ mcp dev teradata-mcp-server
355355
## Build, Test, and Publish
356356

357357
We build with **uv**, test locally (wheel), then push to **TestPyPI** before PyPI.
358+
The examples below use the Twine utility.
358359

359360
### Versions
360361
- The CLI reads its version from package metadata (`importlib.metadata`).
@@ -370,8 +371,7 @@ uv build --no-cache
370371
### 2) Test the wheel locally (no install)
371372
```bash
372373
# Run the installed console entry point from the wheel
373-
uvx ./dist/teradata_mcp_server-<ver>-py3-none-any.whl \
374-
python -m teradata_mcp_server --version
374+
uvx ./dist/teradata_mcp_server-<ver>-py3-none-any.whl teradata_mcp_server --version
375375

376376
# Or install as a persistent tool and run
377377
uv tool install --reinstall ./dist/teradata_mcp_server-<ver>-py3-none-any.whl
@@ -380,13 +380,13 @@ uv tool install --reinstall ./dist/teradata_mcp_server-<ver>-py3-none-any.whl
380380

381381
### 3) Verify metadata/README
382382
```bash
383-
twine check dist/*
383+
uvx twine check dist/*
384384
```
385385

386386
### 4) Publish to **TestPyPI** (dress rehearsal)
387387
```bash
388388
# Upload
389-
python -m twine upload --repository testpypi dist/*
389+
uvx twine upload --repository testpypi dist/*
390390

391391
# Try installing the just-published version with uvx
392392
uvx --no-cache \
@@ -401,9 +401,11 @@ Notes:
401401

402402
### 5) Publish to **PyPI**
403403
```bash
404-
python -m twine upload dist/*
404+
uvx twine upload dist/*
405405
```
406-
If you see `File already exists`, bump the version in `pyproject.toml`, rebuild, and upload again.
406+
If you see `File already exists`, it is either:
407+
- You haven't bumped the the version in `pyproject.toml`. Do so, rebuild, and upload again.
408+
- You have prior builds in the ./dist directory. Remove prior or be specify the exact version (eg. `uvx twine upload dist/*1.4.0*`)
407409

408410
### 6) Post‑publish smoke test
409411
```bash

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "teradata-mcp-server"
3-
version = "0.1.4"
3+
version = "0.1.5"
44
description = "Model Context Protocol (MCP) server for Teradata, Community edition"
55
readme = {file = "README.md", content-type = "text/markdown"}
66
license = {text = "MIT"}

src/teradata_mcp_server/app.py

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -400,19 +400,25 @@ def _cube_query_tool(dimensions: str, measures: str, dim_filters: str, meas_filt
400400
expr = mdef["expression"]
401401
mes_lines.append(f"{expr} AS {measure}")
402402
meas_list = ",\n ".join(mes_lines)
403+
top_clause = f"TOP {top}" if top else ""
404+
dim_comma = ",\n " if dim_list.strip() else ""
405+
where_dim_clause = f"WHERE {dim_filters}" if dim_filters else ""
406+
where_meas_clause = f"WHERE {meas_filters}" if meas_filters else ""
407+
order_clause = f"ORDER BY {order_by}" if order_by else ""
408+
403409
sql = (
404-
f"SELECT {'TOP ' + str(top) if top else ''} * from\n"
410+
f"SELECT {top_clause} * from\n"
405411
"(SELECT\n"
406-
f" {dim_list}{',\n ' if dim_list.strip() else ''}"
412+
f" {dim_list}{dim_comma}"
407413
f" {meas_list}\n"
408414
"FROM (\n"
409415
f"{cube['sql'].strip()}\n"
410-
f"{'WHERE '+dim_filters if dim_filters else ''}"
416+
f"{where_dim_clause}"
411417
") AS c\n"
412418
f"GROUP BY {', '.join(dim_list_raw)}"
413419
") AS a\n"
414-
f"{'WHERE '+meas_filters if meas_filters else ''}"
415-
f"{'ORDER BY '+order_by if order_by else ''}"
420+
f"{where_meas_clause}"
421+
f"{order_clause}"
416422
";"
417423
)
418424
return sql
@@ -439,6 +445,17 @@ async def _dynamic_tool(dimensions, measures, dim_filters="", meas_filters="", o
439445
measure_lines = []
440446
for n, m in cube.get('measures', {}).items():
441447
measure_lines.append(f" - {n}: {m.get('description', '')}")
448+
449+
# Create example strings for documentation
450+
dim_examples = [f"{d} {e}" for d, e in zip(list(cube.get('dimensions', {}))[:2], ["= 'value'", "in ('X', 'Y', 'Z')"])]
451+
dim_example = ' AND '.join(dim_examples)
452+
453+
meas_examples = [f"{m} {e}" for m, e in zip(list(cube.get('measures', {}))[:2], ["> 1000", "= 100"])]
454+
meas_example = ' AND '.join(meas_examples)
455+
456+
order_examples = [f"{d} {e}" for d, e in zip(list(cube.get('dimensions', {}))[:2], [" ASC", " DESC"])]
457+
order_example = ' , '.join(order_examples)
458+
442459
_dynamic_tool.__doc__ = f"""
443460
Tool to query the cube '{name}'.
444461
{cube.get('description', '')}
@@ -451,11 +468,11 @@ async def _dynamic_tool(dimensions, measures, dim_filters="", meas_filters="", o
451468
{chr(10).join(measure_lines)}
452469
453470
* dim_filters (str): Filter expression to apply to dimensions. Valid dimension names are: [{', '.join(cube.get('dimensions', {}).keys())}], use valid SQL expressions, for example:
454-
\"{' AND '.join([f"{d} {e}" for d, e in zip(list(cube.get('dimensions', {}))[:2], ["= 'value'", "in ('X', 'Y', 'Z')"])])}\"
471+
"{dim_example}"
455472
* meas_filters (str): Filter expression to apply to computed measures. Valid measure names are: [{', '.join(cube.get('measures', {}).keys())}], use valid SQL expressions, for example:
456-
\"{' AND '.join([f"{m} {e}" for m, e in zip(list(cube.get('measures', {}))[:2], ["> 1000", "= 100"])])}\"
473+
"{meas_example}"
457474
* order_by (str): Order expression on any selected dimensions and measures. Use SQL syntax, for example:
458-
\"{' , '.join([f"{d} {e}" for d, e in zip(list(cube.get('dimensions', {}))[:2], [" ASC", " DESC"])])}\"
475+
"{order_example}"
459476
top (int): Limit the number of rows returned, use a positive integer.
460477
461478
Returns:

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)