nativegate
nativegate — make legacy Fortran and C++ AI-ready and microservice-ready
Decades-old engineering code — 1990s C++ over FORTRAN 77 — turned into an MCP server, a REST API and a container that AI agents and modern systems can call today, without rewriting it and without hand-writing bindings. Modernization here means the interface, the packaging and the deployment; the numerics stay exactly where they are, and stay provably unchanged.
Website · Blog · Enterprise · Source
This monorepo holds three things:
tools/nativegate/— the generator. Point it at a header or a Fortran deck; it produces the pybind11/f2py bindings, the CMake build, an installable Python package, a FastAPI service, tests, a numerical regression baseline, and a Dockerfile.libraries/petro/— a period-accurate legacy codebase (~4,800 lines, 1988–2004 vintage) that exists to stress the generator against the real thing rather than a toy header. It is the modernization target the whole repo is measured against.services/— what came out the other side. The repo currently carries one committed service,petro_api, generated from the Fortran decks inlibraries/petro/: an independently buildable wheel and container.
Layout
tools/nativegate/ the generator + its docs and test suite
libraries/ native code shared by services (petro, common-cpp,
geometry, demo)
services/<name>/ one generated service per exposed API
gateways/<name>/ created on demand by `ngate gateway`
infrastructure/ docker/ and kubernetes/ (kubernetes/ holds the generated
petro_api manifest)
design.md the 1,073-line specification all of this implementsEvery command runs from this directory — ngate resolves
services/<name>/ relative to your working directory.
Related MCP server: mcp-anything
Start here
cd tools/nativegate && ./scripts/bootstrap.sh && cd - # creates .venv, installs the CLI
tools/nativegate/.venv/bin/ngate quickstart libraries/geometry/geometry.hpp
tools/nativegate/.venv/bin/ngate build geometryThen read Getting started for the same path explained, or the nativegate README for what the tool does and does not handle.
Using the generator on your own project
You do not have to work inside this repo. nativegate installs like any pip
package and resolves services/ against your current directory:
cd /path/to/your-project
python3 -m venv .venv
.venv/bin/pip install "nativegate[clang,build,test] @ git+https://github.com/ravikings/nativegate.git@<sha>#subdirectory=tools/nativegate"
.venv/bin/ngate init && .venv/bin/ngate quickstart src/yourlib.hppPin the commit — this is a code generator, and an unpinned upgrade can change the bindings under a service that was working. Details, including which extras matter and why, are in Using it in another project.
The CLI
One binary covers the whole path from legacy source to running container.
ngate --help is authoritative; this is the map.
Stage | Command | What it does |
Survey |
| Identify the language and dialect of a source tree |
| Rank which files are worth exposing first | |
| List the symbols a file offers, and what would be skipped | |
Scaffold |
| Create |
| Empty service skeleton ( | |
| Print the | |
| detect → scaffold → generate in one step ( | |
Generate |
| Regenerate bindings, CMake, package, service, tests |
| Compile the extension | |
| Pin the service's Python dependencies with hashes | |
Verify |
| Record the numbers the bindings currently return |
| Fail if any of them moved (= | |
| Print the recorded baseline | |
| Generated smoke tests plus the golden check | |
Ship |
| Run the service locally with uvicorn |
| Generate (and optionally | |
| Generate a Kubernetes manifest | |
| Mount several services behind one app | |
| Remove generated build artifacts |
Running the app
tools/nativegate/.venv/bin/ngate build petro_api
tools/nativegate/.venv/bin/pip install services/petro_api/dist/*.whl
tools/nativegate/.venv/bin/ngate serve petro_api # 127.0.0.1:8000
curl localhost:8000/healthzserve is a development convenience: one uvicorn process, bound to loopback,
against the installed wheel. It is not the deployment path. A generated
service is an ordinary FastAPI app (<name>.service:app) in an ordinary
wheel, so anything that already runs your Python services can run it — and
the generated Dockerfile does exactly that, with gunicorn and uvicorn
workers:
tools/nativegate/.venv/bin/ngate docker petro_api --build
docker run -p 8000:8000 petro_api:latestThe service
Service | Language | From | What it exercises |
| Fortran | an F90 facade over 7 fixed-form F77 decks | INCLUDE expansion, COMMON-block state, inferred intent, module nesting, array arguments, 10 exposed routines |
Regenerate it at any time — the bindings, CMake, Python package and tests are all generated:
tools/nativegate/.venv/bin/ngate generate petro_apiThe other directories under libraries/ (geometry, demo, common-cpp)
are inputs used by the docs and the test suite; no service is committed for
them, so the C++ examples in the guides scaffold one as they go.
What is not regenerable is the code you wrote: native/,
nativegate.yaml, and the recorded answers in golden.json. See
what is generated, what is yours.
The legacy library
libraries/petro/ is the point of the whole exercise: black-oil PVT
correlations, Corey/Stone relative permeability, Beggs & Brill wellbore
hydraulics, Peng-Robinson flash, an IMPES simulator core, Peaceman well
indices — with IMPLICIT typing, COMMON blocks, INCLUDE decks, macro-mangled
extern "C" bridges and a pre-standard C++ layer on top. It compiles and
returns physically sensible numbers on its own, before nativegate touches it.
libraries/petro/FINDINGS.md records what
broke when the generator was first pointed at it, and what was fixed —
including a correction to its own first draft, which had blamed fixed-form
parsing for what turned out to be a measurement error in the probe.
Proving the answers did not change
This is the part that makes automated modernization defensible rather than merely fast. For a re-host, "it builds and imports" is not the acceptance criterion. Every service can pin what its bindings return:
tools/nativegate/.venv/bin/ngate golden record petro_api # -> services/petro_api/golden.json
tools/nativegate/.venv/bin/ngate golden verify petro_apiservices/petro_api/golden.json is a worked example: the fluid configured at
35 °API, 0.65 gas gravity and 180 °F, then the 1988 correlations evaluated at
2000 psia, giving Rs = 355.076 scf/stb and Bo = 1.23766 — values a reservoir
engineer can check by hand. It pins 10 entry points, and records the compiler
versions and the SHA-256 of every native source it was recorded from. Commit
the file, and any rebuild that moves a number fails.
See Numerical regression.
Serving several services together
tools/nativegate/.venv/bin/ngate gateway platform-api --service petro_api
uvicorn platform_api.app:appEach service keeps its own wheel, version and build; the gateway just mounts
their routers under /<service>. The alternative — one image per service
behind an ingress — needs no generated code at all. Both are covered in
Deployment topologies.
Tests
cd tools/nativegate
.venv/bin/python -m pytest tests -q # green with or without [fparser]
NATIVEGATE_CPP_PARSER=regex .venv/bin/python -m pytest -q # the fallback C++ backendPer-service suites (generated smoke tests plus the golden check) run with
ngate test <name>.
Beyond unit tests, both language paths are verified by actually building them:
generated CMake fed to real cmake/clang++/gfortran, the extension
imported, the FastAPI service exercised over HTTP. Several real bugs were
found that way and not by inspection — f2py's module nesting, a missing-.cpp
link failure that only surfaces at first import, and a golden harness that
replayed stateful F77 routines out of order.
Status
Where this is usable today: internal, single-tenant-per-service deployments, where a team is calling legacy code it already trusts. Not internet-facing, and not multi-tenant.
What has landed since the first cut: generated services now carry optional API
key auth (api.auth: api_key), rate limiting, request size limits, request
IDs and access logging, an exception handler, /healthz and /readyz with
SIGTERM draining, and generated Kubernetes manifests (ngate k8s, output
in infrastructure/kubernetes/). infrastructure/docker/ is still an empty
skeleton and no CI/CD pipelines are generated.
Three limits are structural rather than unfinished work, and are worth knowing before you size anything:
Fortran services run one native call at a time, per process. Every generated Fortran endpoint takes a single process-wide lock before entering native code, because COMMON blocks are process-global storage — two requests configuring different fluids would otherwise interleave writes into the same COMMON block and each caller would get numbers computed from the other's inputs, with nothing raised and nothing logged. This is deliberate (see
services/petro_api/python/petro_api/router.py). Concurrency for a Fortran service comes from running more processes, not more threads. C++ services are not locked: they get a fresh instance per request instead. A C++ library that keeps file-scope static state is not protected, and the parser cannot see that it does — that one is on you.The API for a stateful library is session-shaped — "configure, then read" — which is safe when one tenant owns the process and unsafe when it does not.
A segfault in native code still takes the worker down. There is no sandbox, no per-call timeout and no per-call isolation.
Before running any of this for a workload that matters, read
Is this production-ready? and
the defect list — honest gap lists against
design.md's own requirements, not a sales pitch.
Contact
Questions, modernization projects, or feedback: sr.rabiu@gmail.com.
Contributing: see CONTRIBUTING.md. All participation in this project's spaces is covered by the Code of Conduct; reports go to the contact above.
This server cannot be deployed
Maintenance
Related MCP Connectors
- typeshipOAuthdev.typeship
Generate a typed SDK, CLI, and MCP server from any OpenAPI or GraphQL spec, and keep them current.
327 dev tools via REST API and MCP. Generate Dockerfiles, schemas, K8s, APIs, and more.
Unified gateway exposing 150+ tools across all NexGenData MCP servers via one endpoint.
AI-native git hosting — repos, PRs, issues, CI gates, and AI code review over MCP (60 tools).
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceA production-ready foundation template for building Model Context Protocol (MCP) servers with FastAPI, featuring modular tools, comprehensive testing, and OpenShift deployment configurations. Includes automated transformation scripts to create custom domain-specific MCP servers.66Apache 2.0
- AlicenseNot gradedqualityAmaintenanceOne command to turn any codebase into an MCP server. Not just REST APIs. Not just OpenAPI specs.45Apache 2.0
- AlicenseNot gradedqualityDmaintenanceMCPGate aggregates multiple MCP servers into a single unified endpoint, enabling centralized tool management with granular filtering, automatic namespacing, and observability. Features a real-time web dashboard and optional PostgreSQL-backed audit trails for monitoring and controlling AI tool access across local and remote deployments.5 npmApache 2.0
- AlicenseNot gradedqualityCmaintenanceGenerates production-ready MCP servers from natural language, OpenAPI specs, database schemas, GraphQL schemas, or ontologies.40 npm1MIT