|
| 1 | +# FlowTime MCP (Model Context Protocol) Guide |
| 2 | + |
| 3 | +This repo includes a **local MCP server** that exposes a subset of FlowTime Engine + Sim capabilities as MCP tools. |
| 4 | + |
| 5 | +Today, the MCP server is designed to run as a **stdio subprocess** (spawned by a chat client / agent / VS Code extension). It is **not** yet a long-running HTTP service. |
| 6 | + |
| 7 | +Related architecture background: |
| 8 | +- `docs/architecture/ai/mcp-server-architecture.md` |
| 9 | +- `docs/architecture/ai/mcp-modeling.md` |
| 10 | +- `docs/architecture/ai/mcp-modeling-tools.md` |
| 11 | + |
| 12 | +Tracking (Epic 8): |
| 13 | +- `docs/milestones/tracking/M-08.01-tracking.md` through `M-08.05-tracking.md` |
| 14 | + |
| 15 | +--- |
| 16 | + |
| 17 | +## 1) Prerequisites |
| 18 | + |
| 19 | +- **.NET 9 SDK** (for FlowTime Engine + Sim services) |
| 20 | +- **Node.js 20+** and npm (for the MCP server) |
| 21 | +- **VS Code** (recommended for the dev loop; tasks are provided) |
| 22 | + |
| 23 | +Ports (defaults): |
| 24 | +- Engine API: `http://localhost:8080` |
| 25 | +- Sim API: `http://localhost:8090` |
| 26 | + |
| 27 | +--- |
| 28 | + |
| 29 | +## 2) What went wrong with `tsx: not found`? |
| 30 | + |
| 31 | +The MCP server’s development command is: |
| 32 | + |
| 33 | +```bash |
| 34 | +npm run dev |
| 35 | +``` |
| 36 | + |
| 37 | +Which runs: |
| 38 | + |
| 39 | +```bash |
| 40 | +tsx src/index.ts |
| 41 | +``` |
| 42 | + |
| 43 | +`tsx` is installed via **npm devDependencies**, so if you see: |
| 44 | + |
| 45 | +```text |
| 46 | +sh: 1: tsx: not found |
| 47 | +``` |
| 48 | + |
| 49 | +…it almost always means **you haven’t installed npm dependencies yet** in `tools/mcp-server`. |
| 50 | + |
| 51 | +Fix: |
| 52 | + |
| 53 | +```bash |
| 54 | +cd tools/mcp-server |
| 55 | +npm install |
| 56 | +``` |
| 57 | + |
| 58 | +(Equivalent from repo root: `npm install --prefix tools/mcp-server`.) |
| 59 | + |
| 60 | +--- |
| 61 | + |
| 62 | +## 3) One-time setup (local dev) |
| 63 | + |
| 64 | +From the repo root: |
| 65 | + |
| 66 | +```bash |
| 67 | +# Install MCP server dependencies (includes tsx) |
| 68 | +npm install --prefix tools/mcp-server |
| 69 | + |
| 70 | +# Optional: compile TypeScript output (for production-style start) |
| 71 | +npm run build --prefix tools/mcp-server |
| 72 | +``` |
| 73 | + |
| 74 | +--- |
| 75 | + |
| 76 | +## 4) Running the full dev loop (VS Code) |
| 77 | + |
| 78 | +The MCP server depends on both backends: |
| 79 | +- **FlowTime Engine API** (imports run bundles) |
| 80 | +- **FlowTime Sim Service** (orchestrates template runs + draft workflows) |
| 81 | + |
| 82 | +### Recommended: use VS Code tasks |
| 83 | + |
| 84 | +This repo ships tasks in `.vscode/tasks.json`. |
| 85 | + |
| 86 | +1. Start Engine API: task `start-api` (port 8080) |
| 87 | +2. Start Sim API: task `start-sim-api` (port 8090) |
| 88 | +3. Start MCP server: task `start-mcp-server` |
| 89 | + |
| 90 | +The MCP task runs in `tools/mcp-server` and sets the default env vars: |
| 91 | + |
| 92 | +- `FLOWTIME_SIM_API_URL=http://localhost:8090/api/v1` |
| 93 | +- `FLOWTIME_SIM_DRAFT_API_URL=http://localhost:8090/api/v1` |
| 94 | +- `FLOWTIME_API_URL=http://localhost:8080/v1` |
| 95 | +- `FLOWTIME_DATA_DIR=<repo>/data` |
| 96 | +- `FLOWTIME_TEMPLATES_DIR=<repo>/templates` |
| 97 | +- `FLOWTIME_TEMPLATES_DRAFT_DIR=<repo>/templates-draft` |
| 98 | +- `MCP_MAX_BINS=1000` |
| 99 | + |
| 100 | +### Manual equivalent (if you don’t want tasks) |
| 101 | + |
| 102 | +In three terminals: |
| 103 | + |
| 104 | +Terminal 1 (Engine API): |
| 105 | + |
| 106 | +```bash |
| 107 | +dotnet run --project src/FlowTime.API --urls http://0.0.0.0:8080 |
| 108 | +``` |
| 109 | + |
| 110 | +Terminal 2 (Sim API): |
| 111 | + |
| 112 | +```bash |
| 113 | +ASPNETCORE_URLS=http://0.0.0.0:8090 dotnet run --project src/FlowTime.Sim.Service |
| 114 | +``` |
| 115 | + |
| 116 | +Terminal 3 (MCP server): |
| 117 | + |
| 118 | +```bash |
| 119 | +cd tools/mcp-server |
| 120 | +FLOWTIME_SIM_API_URL=http://localhost:8090/api/v1 \ |
| 121 | +FLOWTIME_SIM_DRAFT_API_URL=http://localhost:8090/api/v1 \ |
| 122 | +FLOWTIME_API_URL=http://localhost:8080/v1 \ |
| 123 | +MCP_MAX_BINS=1000 \ |
| 124 | +npm run dev |
| 125 | +``` |
| 126 | + |
| 127 | +You should see something like: |
| 128 | + |
| 129 | +```text |
| 130 | +FlowTime MCP server running on stdio |
| 131 | +``` |
| 132 | + |
| 133 | +--- |
| 134 | + |
| 135 | +## 5) Using it from VS Code (MCP client) |
| 136 | + |
| 137 | +Because this server uses **stdio transport**, your MCP-enabled client must be able to launch it as a subprocess. |
| 138 | + |
| 139 | +A typical launch config looks like: |
| 140 | + |
| 141 | +```json |
| 142 | +{ |
| 143 | + "command": "node", |
| 144 | + "args": ["--import", "tsx", "src/index.ts"], |
| 145 | + "cwd": "<repo>/tools/mcp-server", |
| 146 | + "env": { |
| 147 | + "FLOWTIME_SIM_API_URL": "http://localhost:8090/api/v1", |
| 148 | + "FLOWTIME_SIM_DRAFT_API_URL": "http://localhost:8090/api/v1", |
| 149 | + "FLOWTIME_API_URL": "http://localhost:8080/v1", |
| 150 | + "MCP_MAX_BINS": "1000" |
| 151 | + } |
| 152 | +} |
| 153 | +``` |
| 154 | + |
| 155 | +Notes: |
| 156 | +- The exact JSON shape depends on your MCP client/extension. |
| 157 | +- If you prefer a production-style launch, use `npm run build` then run `node dist/index.js`. |
| 158 | + |
| 159 | +--- |
| 160 | + |
| 161 | +## 6) Environment variables |
| 162 | + |
| 163 | +The MCP server reads: |
| 164 | + |
| 165 | +- `FLOWTIME_SIM_API_URL` |
| 166 | + - Default: `http://localhost:8090/api/v1` |
| 167 | + - Used for: template listing, orchestration runs, series/profile endpoints |
| 168 | + |
| 169 | +- `FLOWTIME_SIM_DRAFT_API_URL` |
| 170 | + - Default: `FLOWTIME_SIM_API_URL` |
| 171 | + - Used for: draft storage + draft run endpoints |
| 172 | + |
| 173 | +- `FLOWTIME_API_URL` |
| 174 | + - Default: `http://localhost:8080/v1` |
| 175 | + - Used for: importing a run bundle into the engine (`POST /v1/runs`) |
| 176 | + |
| 177 | +- `MCP_MAX_BINS` |
| 178 | + - Default: `1000` |
| 179 | + - Guardrail: rejects template run parameters that request more than this bin count |
| 180 | + |
| 181 | +- `MCP_REQUEST_TIMEOUT_MS` (default 30000) |
| 182 | +- `MCP_ORCHESTRATION_TIMEOUT_MS` (default 120000) |
| 183 | + |
| 184 | +--- |
| 185 | + |
| 186 | +## 7) Testing (optional) |
| 187 | + |
| 188 | +The MCP server has smoke/integration tests under `tools/mcp-server/tests`. |
| 189 | + |
| 190 | +Run tests: |
| 191 | + |
| 192 | +```bash |
| 193 | +npm test --prefix tools/mcp-server |
| 194 | +``` |
| 195 | + |
| 196 | +Some tests are skipped unless you provide environment variables: |
| 197 | + |
| 198 | +- `MCP_TEST_SIM_API_URL` |
| 199 | +- `MCP_TEST_ENGINE_API_URL` |
| 200 | + |
| 201 | +Optional (enables additional tests): |
| 202 | +- `MCP_TEST_RUN_ID`, `MCP_TEST_START_BIN`, `MCP_TEST_END_BIN` |
| 203 | + |
| 204 | +Example: |
| 205 | + |
| 206 | +```bash |
| 207 | +MCP_TEST_SIM_API_URL=http://localhost:8090/api/v1 \ |
| 208 | +MCP_TEST_ENGINE_API_URL=http://localhost:8080/v1 \ |
| 209 | +npm test --prefix tools/mcp-server |
| 210 | +``` |
| 211 | + |
| 212 | +--- |
| 213 | + |
| 214 | +## 8) Troubleshooting |
| 215 | + |
| 216 | +### `tsx: not found` |
| 217 | + |
| 218 | +Cause: dependencies not installed. |
| 219 | + |
| 220 | +Fix: |
| 221 | + |
| 222 | +```bash |
| 223 | +npm install --prefix tools/mcp-server |
| 224 | +``` |
| 225 | + |
| 226 | +### 404s / connection errors calling Sim or Engine |
| 227 | + |
| 228 | +Double-check that your URLs include the correct API prefixes: |
| 229 | +- Sim: `http://localhost:8090/api/v1` |
| 230 | +- Engine: `http://localhost:8080/v1` |
| 231 | + |
| 232 | +Also confirm services are running: |
| 233 | +- Engine health: `GET http://localhost:8080/healthz` |
| 234 | +- Sim health: `GET http://localhost:8090/healthz` |
| 235 | + |
| 236 | +### Timeouts |
| 237 | + |
| 238 | +For large templates or slow machines, increase timeouts: |
| 239 | + |
| 240 | +```bash |
| 241 | +MCP_ORCHESTRATION_TIMEOUT_MS=240000 MCP_REQUEST_TIMEOUT_MS=60000 npm run dev |
| 242 | +``` |
| 243 | + |
| 244 | +### “Only simulation mode is supported … PoC” |
| 245 | + |
| 246 | +The current MCP server enforces `mode=simulation` in some tool paths. |
| 247 | + |
| 248 | +--- |
| 249 | + |
| 250 | +## 9) Deployment notes (future / cloud) |
| 251 | + |
| 252 | +Today, `tools/mcp-server` runs over **stdio** and is meant to be spawned by a client. |
| 253 | + |
| 254 | +To run it as a **hosted service** in Azure, you’ll likely need one of these patterns: |
| 255 | + |
| 256 | +1) **Remote transport wrapper** |
| 257 | +- Implement an HTTP/SSE/WebSocket gateway that translates remote requests to a local stdio MCP process. |
| 258 | +- Deploy the gateway + MCP server together (same container/pod) so stdio stays local. |
| 259 | + |
| 260 | +2) **Re-host with a network transport** |
| 261 | +- Add a first-class network transport to the MCP server (when appropriate for the chosen MCP client ecosystem). |
| 262 | + |
| 263 | +In either case: |
| 264 | +- Treat Sim + Engine endpoints as dependencies (network + auth + retries). |
| 265 | +- Add authn/authz (API keys / AAD) before exposing the server publicly. |
| 266 | +- Restrict outbound access: the MCP server should only be able to reach FlowTime APIs. |
| 267 | + |
| 268 | +If you need a concrete Azure deployment plan (Container Apps / AKS / App Service), we can write a follow-up doc once the intended MCP transport is decided. |
0 commit comments