UIUC Airfoils
by pipeworx-io
README.md
# @pipeworx/uiuc-airfoils
Airfoil shape coordinates for roughly 1,600 airfoils (NACA, Eppler, Selig,
Wortmann, Goettingen, Drela AG, Clark Y, Wright Brothers and many
designer-named one-offs), searchable by name or family, with max
thickness/camber computed live from the raw coordinates.
Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents to 1851+ live data sources. This is an independent, unofficial integration — not affiliated with, endorsed by, or published by the upstream provider.
## Tools
- `uiuc_airfoil_search(query?, family?, limit?)` — search by name, keyword,
or exact family (e.g. `"naca"`, `"eppler"`, `"goe"`, `"2412"`, `family:
"Wortmann"`). With no filters, returns the total catalog size and the
known family list. Always returns the total match count first; a no-match
response names the filters tried.
- `uiuc_airfoil_geometry(name, include_coordinates?)` — fetches one
airfoil's coordinate file live and returns its point count, coordinate
format, max thickness and max camber (each as a fraction of chord, with
the chordwise station they occur at), and the method used to compute them.
Pass `include_coordinates: true` to also get the raw upper/lower surface
point arrays.
## Auth
Keyless.
## Data sources
- University of Illinois Urbana-Champaign, Applied Aerodynamics Group,
UIUC Airfoil Coordinates Database — airfoil shape coordinates and their
one-line descriptions. Never a route or filename here — see `src/index.ts`
and `scripts/bake-index.mjs` for the routes, which stay out of published
copy per CLAUDE.md step 9b.
## Licence — checked before building, flagged rather than assumed
Before writing a line of code, I checked the database's listing page, its
parent page, and the site's `robots.txt` (a 404 — no restriction stated
there either) for a stated licence or redistribution policy. There is none.
The only copyright-adjacent text anywhere on the site is a generic,
site-wide footer ("© 1994 - 2026 UIUC Applied Aerodynamics Group") with no
accompanying grant or prohibition for the coordinate data itself.
Per the standing rule (proxying a public, keyless upstream per request needs
no explicit grant; baking a dataset is redistribution and needs one; when
terms are silent, build and flag rather than hold):
- The actual coordinate **values** are never baked. `uiuc_airfoil_geometry`
fetches each airfoil's `.dat` file live, per call, every time — a
straight per-request proxy of one file.
- `uiuc_airfoil_search` does read a small baked table of names, one-line
descriptions and a coarse family classification (`src/uiuc-index-data.ts`,
~1,587 rows, regenerated by `scripts/bake-index.mjs`) — never the
coordinates. This is the part resting on the "silent terms, build and
flag" branch of the rule rather than an explicit grant.
- **Flag for whoever reviews this next:** if UIUC ever publishes an explicit
redistribution term for the coordinate data, re-check whether even this
name/description/family index still fits it.
## Coordinate formats and the thickness/camber method
UIUC's `.dat` files come in two layouts, both handled by the parser in
`src/index.ts`:
- **Selig format** — one continuous point loop: starts at the trailing edge
on the upper surface, runs forward to the leading edge, then back along
the lower surface to the trailing edge. No header counts; the parser
splits the loop at its minimum-x point (the leading edge).
- **Lednicer format** — a header line giving `(upperCount, lowerCount)`,
then the upper surface from leading edge to trailing edge, a blank line,
then the lower surface from leading edge to trailing edge.
Format is detected per file (a Lednicer header is two small integer-looking
values on the first data line; anything else is treated as Selig). Once
split into upper(x) and lower(x) surfaces, both are linearly interpolated
onto a shared 101-station cosine-spaced grid over chord (`x` in `0..1` —
UIUC's coordinates are already chord-normalized). From that grid:
- `thickness(x) = upper(x) - lower(x)`
- `camber(x) = (upper(x) + lower(x)) / 2`
Max thickness and max (signed) camber are the largest values over that
grid, reported as a fraction of chord along with the `x` station they occur
at — the same convention NACA's own 4-digit naming encodes. Verified against
NACA 2412 itself: the tool returns 12.0% max thickness at 30% chord and 2.0%
max camber at ~40% chord, which is exactly what "2-4-12" means (2% camber at
40% chord, 12% thickness) and exactly where the NACA 4-digit series places
max thickness (30% chord) by construction — a strong correctness check,
not a coincidence.
## Known gaps
- Family classification is a coarse heuristic over filenames/descriptions
(keyword rules in `scripts/bake-index.mjs`), not an authoritative taxonomy
UIUC itself publishes — airfoils that don't match a known designer/series
keyword land in `"Other"` (currently ~1/3 of the catalog), which is
expected, not a bug.
- A handful of `.dat` files on the site use nonstandard spacing or trailing
annotations the parser can't make sense of; `uiuc_airfoil_geometry` then
returns `geometry_error` with the raw parse failure rather than a
fabricated number.
- The baked name index refreshes only when `scripts/bake-index.mjs` is
re-run by hand (UIUC adds a handful of airfoils every year or two via its
own "Update Directory" section) — there is no automatic refresh path yet.
## Quick Start
Add to your MCP client (Claude Desktop, Cursor, Windsurf, etc.):
```json
{
"mcpServers": {
"uiuc-airfoils": {
"url": "https://gateway.pipeworx.io/uiuc-airfoils/mcp"
}
}
}
```
### What this endpoint actually serves
`tools/list` at `https://gateway.pipeworx.io/uiuc-airfoils/mcp` returns the tools in the table
above **plus the shared Pipeworx meta-tools** — `ask_pipeworx`,
`discover_tools`, `search_within`, `remember`/`recall` and the rest of the
gateway-wide set. So the tool count you see is larger than this table: a
single-pack endpoint currently lists roughly 30 shared tools alongside the
pack's own. The connection's `initialize` response states its exact scope, and
is the authoritative answer for a given day.
This is deliberate, not multiplexing by accident. The meta-tools are what let a
scoped connection answer a question this pack does not cover — via
`ask_pipeworx`, which routes across the whole catalog — without you adding a
second MCP server. There is currently no way to mount a pack endpoint without
them; if the extra schemas cost you more context than the routing is worth,
connect to the full gateway once rather than to several pack endpoints.
Or connect to the full Pipeworx gateway to get every pack's tools listed
directly, instead of just this one's:
```json
{
"mcpServers": {
"pipeworx": {
"url": "https://gateway.pipeworx.io/mcp"
}
}
}
```
Both URLs reach the same gateway and the same 1851+ data sources. The
only difference is which pack's tools are listed **directly**; `ask_pipeworx`
reaches all of them from either one.
## No MCP client? Call it over HTTP
```bash
curl -X POST https://gateway.pipeworx.io/v1/tools/uiuc_airfoil_search \
-H 'Content-Type: application/json' \
-d '{"query":"naca24"}'
```
No account needed for the first calls. Inspect any tool: `GET https://gateway.pipeworx.io/v1/tools/uiuc_airfoil_search`. Find one: `POST https://gateway.pipeworx.io/v1/tools/search_packs` with `{"query":"..."}`.
## Standalone (no gateway account)
This package also runs as a local stdio MCP server — no Pipeworx account, no
gateway round-trip:
```json
{
"mcpServers": {
"uiuc-airfoils": {
"command": "npx",
"args": ["-y", "@pipeworx/mcp-uiuc-airfoils"]
}
}
}
```
Or run it directly to confirm it starts:
```bash
npx -y @pipeworx/mcp-uiuc-airfoils
```
It speaks MCP over stdin/stdout and answers `initialize`/`tools/list`/`tools/call`
for **only** this pack's tools — none of the shared meta-tools the gateway
connection above adds. Same source, same tools, no ask_pipeworx routing.
## Using with ask_pipeworx
Instead of calling tools directly, you can ask questions in plain English —
this works on the pack endpoint above as well as on the full gateway:
```
ask_pipeworx({ question: "your question about Uiuc Airfoils data" })
```
The gateway picks the right tool and fills the arguments automatically.
## More
- [Docs and guides](https://pipeworx.io/docs)
- [pipeworx.io](https://pipeworx.io)
## License
MIT
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues