Skip to content

Commit 2871cf4

Browse files
committed
prompts
1 parent c62abc9 commit 2871cf4

4 files changed

Lines changed: 94 additions & 3 deletions

File tree

h3-guide.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# H3 Geospatial Indexing
2+
3+
**Most of these data uses H3 hexagons** (https://h3geo.org) - uniform hexagonal grid covering Earth
4+
5+
## Key Facts
6+
7+
- Each h8 hexagon = **73.7327598 hectares** (≈ 0.737 km²)
8+
- Always report AREAS, not hex counts
9+
- **Use** `APPROX_COUNT_DISTINCT(h8)` when counting hexes to compute areas -- this avoids double-counting and is reasonably fast enough.
10+
11+
## Area Conversion
12+
13+
```sql
14+
SELECT APPROX_COUNT_DISTINCT(h8) * 0.737327598 as area_km2 FROM ...
15+
```
16+
17+
## Joining Different Resolutions
18+
19+
Some datasets use different H3 resolutions (h8 vs h0-h4). Use `h3_cell_to_parent()` to convert:
20+
21+
```sql
22+
-- iNaturalist has h4, wetlands has h8 → convert h8 to h4
23+
JOIN read_parquet('s3://public-inat/range-maps/hex/**') pos
24+
ON h3_cell_to_parent(wetlands.h8, 4) = pos.h4
25+
AND wetlands.h0 = pos.h0 -- Always include h0 for partition pruning!
26+
```
27+
28+
## Generating Output Files
29+
30+
```sql
31+
COPY (SELECT ...) TO 's3://public-output/unique-file-name.csv' (FORMAT CSV, HEADER, OVERWRITE_OR_IGNORE);
32+
```
33+
34+
Then tell the user the *public https* address (note the use of the public, not private endpoint): it should have the format like: `https://s3-west.nrp-nautilus.io/public-output/unique-file-name.csv` (adjust `unique-file-name.csv` part appropriately.)
35+
36+
**Note:** s3://public-output has a 30-day expiration and 1 Gb object size limit. CORS headers will permit files to be placed here and rendered by other tools.

k8s/deployment.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ kind: Deployment
33
metadata:
44
name: duckdb-mcp
55
spec:
6-
replicas: 2
6+
replicas: 1
77
selector:
88
matchLabels:
99
app: duckdb-mcp
@@ -28,7 +28,7 @@ spec:
2828
apt-get update && apt-get install -y git && \
2929
git clone https://github.com/boettiger-lab/mcp-data-server.git /app && \
3030
cd /app && \
31-
uv run --with "mcp" --with "duckdb" --with pandas --with uvicorn server.py
31+
uv run --with "mcp" --with "duckdb" --with pandas --with uvicorn --with tabulate server.py
3232
resources:
3333
requests:
3434
memory: 16Gi

query-optimization.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Query Optimization Essentials
2+
3+
## 1. Filter Small Tables First
4+
5+
```sql
6+
-- Good: Filter country → then join to large dataset
7+
WITH filtered AS (
8+
SELECT h8, h0 FROM read_parquet('s3://public-overturemaps/hex/countries.parquet')
9+
WHERE country = 'US'
10+
)
11+
SELECT ... FROM filtered JOIN read_parquet('s3://public-wetlands/glwd/hex/**') w
12+
ON filtered.h8 = w.h8 AND filtered.h0 = w.h0
13+
```
14+
15+
## 2. ALWAYS Include h0 in Joins
16+
17+
```sql
18+
-- Enables partition pruning → 5-20x faster
19+
JOIN table2 ON table1.h8 = table2.h8 AND table1.h0 = table2.h0
20+
```

server.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,43 @@ def query(sql_query: str) -> str:
9797
except Exception as e:
9898
return f"SQL Error: {str(e)}"
9999

100+
101+
102+
@mcp.prompt("geospatial-analyst")
103+
def analyst_persona() -> str:
104+
"""
105+
Loads the expert persona, H3 math rules, and query optimization guides.
106+
Use this at the start of every chat to ensure correct SQL generation.
107+
"""
108+
optim = load_file("query-optimization.md")
109+
h3_guide = load_file("h3-guide.md")
110+
111+
return f"""
112+
113+
You are an expert **Geospatial Analyst** specializing in H3-indexed data.
114+
115+
YOUR CORE RESPONSIBILITIES:
116+
1. Analyze natural language questions about geospatial data.
117+
2. Write highly optimized DuckDB SQL queries using the rules below.
118+
3. Interpret results with a focus on spatial accuracy.
119+
120+
---
121+
122+
{optim}
123+
124+
---
125+
126+
{h3_guide}
127+
128+
---
129+
130+
REMINDER:
131+
- Always check `catalog://list` first to see available datasets.
132+
- Never assume column names; check the catalog schema.
133+
"""
134+
100135
# -------------------------------------------------------------------------
101-
# 5. SERVER ENTRY POINT (Streamable HTTP)
136+
# 6. SERVER ENTRY POINT (Streamable HTTP)
102137
# -------------------------------------------------------------------------
103138
if __name__ == "__main__":
104139
# Streamable HTTP uses a single endpoint (default: /mcp)

0 commit comments

Comments
 (0)