mcp-agent-app
A TypeScript service that converts GeoJSON geometries into 3D triangulated meshes using a local LLM (Ollama). It exposes an MCP tool (generate_mesh) and an HTTP API, making mesh generation accessible both to MCP-compatible clients and standard REST consumers.
POST /generate-mesh
│
▼
Express API (src/api/index.ts)
│
▼
generateMeshAgent (src/agents/generate_mesh_agent.ts)
│
▼
Ollama LLM ──────────────────────────────────────────> MeshData
(llama3.2 @ localhost:11434) { vertices, indices, metadata }
MCP server (src/server.ts) exposes the same agent as an MCP tool over stdio
Stack
| Layer | Technology | |---|---| | Language | TypeScript 5 (strict, ES2022, ESM) | | Runtime | Node.js 18+ with tsx for development | | Web framework | Express 4 | | MCP SDK | @modelcontextprotocol/sdk v1.29, @modelcontextprotocol/server v2.0 alpha | | Schema validation | Zod | | Local LLM | Ollama (llama3.2 at http://localhost:11434) |
Note: The MCP server and HTTP API use Ollama for inference — no Anthropic API key is required for the core mesh generation.
ANTHROPIC_API_KEYis only needed if you extend the agent loop with Claude tool-use.
Project structure
src/
├── server.ts # MCP server — registers and runs the generate_mesh tool
├── agents/
│ └── generate_mesh_agent.ts # Core logic: GeoJSON → Ollama → MeshData
└── api/
└── index.ts # Express HTTP API wrapping the agent
Prerequisites
- Node.js 18+
- Ollama running locally with the
llama3.2model pulled:
ollama pull llama3.2
ollama serve # must be running on http://localhost:11434
Setup
npm install
Run (dev, no build step)
npm run dev # starts the Express API on port 3000 (default)
In another terminal:
curl -X POST http://localhost:3000/generate-mesh \
-H "Content-Type: application/json" \
-d '{"geometry": "{\"type\":\"Polygon\",\"coordinates\":[[[0,0],[1,0],[1,1],[0,1],[0,0]]]}"}'
The geometry field accepts either a JSON string or a parsed GeoJSON object (Geometry or Feature).
Expected response shape:
{
"vertices": [0, 0, 0, 1, 0, 0, ...],
"indices": [0, 1, 2, ...],
"metadata": {
"featureType": "Polygon",
"vertexCount": 8,
"triangleCount": 4
}
}
Mesh conventions
| Geometry type | Mesh output | |---|---| | Polygon / MultiPolygon | Flat base (z=0) + extruded top (z=10) + side walls | | LineString | Ribbon mesh, width 0.0001° | | Point | Small pyramid |
Coordinates map as: longitude → x, latitude → y, elevation → z.
Build & run (production)
npm run build
npm start
Run the MCP server standalone
npm run mcp
# or inspect it interactively:
npx @modelcontextprotocol/inspector npx tsx src/server.ts
The MCP server exposes one tool — generate_mesh — that accepts a GeoJSON geometry or Feature as a JSON string and returns the same MeshData structure as the HTTP API.
NPM scripts
| Script | Description | |---|---| | npm run dev | Start API in watch mode via tsx | | npm start | Run compiled dist/api/index.js | | npm run build | Compile TypeScript to dist/ | | npm run mcp | Run the MCP server standalone |
Environment variables
| Variable | Default | Description | |---|---|---| | PORT | 3000 | Express server port | | CORS_ORIGINS | http://localhost:5173 | Comma-separated list of allowed CORS origins |
Notes
- The MCP server logs to stderr, never stdout — stdout is the stdio protocol channel.
- Ollama responses are validated with a Zod schema; a regex fallback handles markdown-wrapped JSON output.
- The HTTP API allows requests with no
Originheader (server-to-server calls) in addition to the CORS allowlist. - For production: TLS at a reverse proxy, auth + rate limiting in front of
/generate-mesh, and request timeouts viaAbortController. - To swap in a remote MCP server, replace
StdioClientTransportwithStreamableHTTPClientTransportin the MCP manager.












