Skip to content

Commit 9b91b1f

Browse files
committed
feat(docs): add urban mapper jupyter tutorial
1 parent 9fb5209 commit 9b91b1f

2 files changed

Lines changed: 169 additions & 1 deletion

File tree

docs/tutorials/index.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,17 @@ Here you’ll find guided, hands-on walkthroughs showing how to build, run, and
5050

5151
NEW! A walkthrough of stacking the **MIMIC MCP** with the **Jupyter MCP**
5252

53-
[:octicons-arrow-right-24: Watch & Learn](mimic-jupyter.md)
53+
[:octicons-arrow-right-24: Watch & Reproduce](mimic-jupyter.md)
54+
55+
- :material-table:{ .lg .middle } __UrbanMapper + Jupyter Pipeline__
56+
{: data-tutorials-card data-filter="Geospatial Reproducible Analysis using UrbanMapper & Jupyter"}
57+
58+
---
59+
60+
NEW! A walkthrough of stacking the **UrbanMapper MCP** with the **Jupyter MCP**
61+
62+
[:octicons-arrow-right-24: Watch & Reproduce](urbanmapper-jupyter.md)
63+
5464

5565
</div>
5666

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
# 🧪 Tutorial: Urban Mapper + Jupyter Pipeline
2+
# 🧪 Tutorial: Urban Mapper + Jupyter Pipeline
3+
4+
This tutorial shows how to **stack two MCPs**:
5+
6+
- **Urban Mapper** (urban computing analysis utilising the Urban Mapper official library)
7+
- **Jupyter** (reproducible notebook analysis)
8+
9+
You’ll learn how to:
10+
11+
1. Build a pipeline with both tools
12+
2. Ask in a natural language to build a reproducible urban analysis workflow utilising Urban Mapper
13+
3. Export code and results into a Jupyter Notebook for reproducible Python analysis
14+
15+
---
16+
17+
## 🎥 Video Walkthrough
18+
19+
<iframe width="860" height="515" src="https://www.youtube.com/embed/6gLkmKevj8Y?si=W9LxWnEZSVer2Z_E" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
20+
21+
---
22+
23+
## Prerequisites
24+
25+
```bash
26+
# If you prefer other Python package managers, feel free to adapt `pip install X`.
27+
28+
uv init --python 3.10
29+
uv add mcpstack
30+
uv add mcpstack-jupyter
31+
uv add mcpstack-urbanmapper
32+
33+
# To see if the tools are all connected
34+
uv run mcpstack list-tools
35+
```
36+
37+
## 🔧 Step 1 — Build with Pipeline W/ Urban Mapper Default
38+
39+
Urban Mapper Default is basically using HuggingFace's datasets to load datasets for urban pipeline analysis.
40+
You can control otherwise, but it would be preferable to start with the default.
41+
42+
```bash
43+
uv run mcpstack pipeline urbanmapper --new-pipeline my_pipeline.json
44+
```
45+
46+
## 🔧 Step 2 — Create a Jupyter `ToolConfig`
47+
48+
Basically, Jupyter MCP works with some sort of connections between the LLM and the Jupyter instance. This is via a
49+
URL and a TOKEN. Hence, the need for a `ToolConfig`.
50+
51+
```bash
52+
uv run mcpstack tools jupyter configure \
53+
--token YOUR_JUPYTER_TOKEN
54+
55+
# This create a `jupyter_config.json` file
56+
# Ex of a token: 1117bf468693444a5608e882ab3b55d511f354a175a0df02
57+
```
58+
59+
## 🔧 Step 3 — Add To The Tool To The Pipeline
60+
61+
```bash
62+
uv run mcpstack pipeline jupyter --to-pipeline my_pipeline.json --tool-config jupyter_config.json
63+
```
64+
65+
## 🔧 Step 4 — Compose & Run the Pipeline On Claude Desktop
66+
67+
```bash
68+
uv run mcpstack build --pipeline my_pipeline.json --config-type claude
69+
```
70+
71+
Now you can ask the LLM to operate an Urban Mapper's pipeline analysis and export results into Jupyter.
72+
73+
## 📣 Prompt Used During The Demo Video
74+
75+
### Initial Prompt
76+
```text
77+
Hey there! May we build a `UrbanMapper`'s analysis so that we may have the count of complaints per streets in the Downtown Brooklyn of New York City, please?
78+
79+
I believe that the data of interest on huggingface datasets is called `oscur/NYC_311`
80+
81+
We would like to visualise the output of the `UrbanMapper`'s pipeline analysis interactively with their library. Nothing too fancy simply use the library capability nothing more for the time being.
82+
83+
Note: In case you may need to DL some packages / libraries, run `!uv add <package_name>`
84+
```
85+
86+
### Follow-up Prompt
87+
````text
88+
Okay let's now compute the most common type of complaints per drive street in the same location please. Final pipeline version looks like:
89+
90+
91+
```
92+
# --- Auto-generated by MCP UrbanMapper (YAML-driven defaults) ---
93+
import urban_mapper as um
94+
from urban_mapper.pipeline import UrbanPipeline
95+
from IPython.display import display as _display
96+
97+
# # HF→CSV pre-step
98+
# mapper = um.UrbanMapper()
99+
# data = (
100+
# mapper.loader
101+
# .from_huggingface("oscur/NYC_311")
102+
# .with_columns(longitude_column="Longitude", latitude_column="Latitude")
103+
# .load()
104+
# )
105+
# data['Longitude'] = data['Longitude'].astype(float)
106+
# data['Latitude'] = data['Latitude'].astype(float)
107+
# data.to_csv("./oscur_NYC_311.csv", index=False)
108+
109+
# 1) Define the pipeline
110+
pipeline = UrbanPipeline([
111+
("urban_layer", (
112+
mapper.urban_layer
113+
.with_type("streets_roads")
114+
.from_place("Downtown Brooklyn, New York City", network_type="drive")
115+
.with_mapping(longitude_column="Longitude", latitude_column="Latitude", output_column="Street Name")
116+
.build()
117+
)),
118+
("loader", (
119+
mapper.loader
120+
.from_file("./oscur_NYC_311.csv")
121+
.with_columns(longitude_column="Longitude", latitude_column="Latitude")
122+
.build()
123+
)),
124+
("imputer", (
125+
mapper.imputer
126+
.with_type("SimpleGeoImputer")
127+
.on_columns("Longitude", "Latitude")
128+
.build()
129+
)),
130+
("filter", mapper.filter.with_type("BoundingBoxFilter").build()),
131+
("enricher", (
132+
mapper.enricher
133+
.with_data(group_by="Street Name")
134+
.count_by(output_column="complaint_count")
135+
.build()
136+
)),
137+
("visualiser", (
138+
mapper.visual.with_type("Interactive").with_style({"tiles": "CartoDB positron", "legend": True}).build()
139+
)),
140+
])
141+
142+
# Optional: preview the pipeline structure
143+
pipeline.preview()
144+
145+
# 2) Compose & immediately visualise
146+
_ = pipeline.compose_transform()
147+
_viz = pipeline.visualise(["complaint_count"])
148+
try:
149+
_display(_viz)
150+
except Exception:
151+
pass
152+
```
153+
````
154+
155+
156+
157+
!!! tip
158+
Try chaining additional tools to build research-ready urban analysis (e.g. ML) workflows.

0 commit comments

Comments
 (0)