Skip to content

Preload

The optional preload field on routes signals that the response is static or slow-changing and that the runtime may cache it locally. This avoids redundant API calls for data that rarely changes.

Some API endpoints return complete, rarely changing datasets (e.g. all hospitals in Germany, all memorial stones in Berlin). Fetching these on every call wastes bandwidth and time. The preload field lets schema authors declare caching intent.

preload is an optional object on route level:

routes: {
getLocations: {
method: 'GET',
path: '/locations.json',
description: 'All hospital locations in Germany',
parameters: [],
preload: {
enabled: true,
ttl: 604800,
description: 'All hospital locations in Germany (~760KB)'
},
output: { /* ... */ },
tests: [ /* ... */ ]
}
}
FieldTypeRequiredDescription
enabledbooleanYesWhether caching is allowed. Must be true to activate.
ttlnumberYesCache time-to-live in seconds. Must be a positive integer.
descriptionstringNoHuman-readable note shown on cache hit.
TTLDurationUse Case
36001 hourFrequently updated data
864001 dayDaily snapshots
6048001 weekWeekly releases, semi-static data
259200030 daysStatic reference data
flowchart TD
A[How often does this data change?] --> B{Daily or more?}
B -->|Yes| C["ttl: 3600-86400"]
B -->|No| D{Weekly?}
D -->|Yes| E["ttl: 604800"]
D -->|No| F{Monthly or less?}
F -->|Yes| G["ttl: 2592000"]
F -->|No| H["Don't use preload"]

When a route has parameters, the cache key must include parameter values:

# With parameters
{namespace}/{routeName}/{paramHash}.json
# Without parameters (or all optional and omitted)
{namespace}/{routeName}.json

Recommended cache directory: ~/.flowmcp/cache/. Each cached response is stored as JSON with metadata:

{
"meta": {
"fetchedAt": "2026-02-17T12:00:00.000Z",
"expiresAt": "2026-02-24T12:00:00.000Z",
"ttl": 604800,
"size": 760123,
"paramHash": null
},
"data": { }
}
flowchart TD
A["flowmcp call tool-name"] --> B{"preload.enabled?"}
B -->|No| C[Normal fetch]
B -->|Yes| D{Cache file exists?}
D -->|No| E[Fetch + store in cache]
D -->|Yes| F{Cache expired?}
F -->|No| G[Return cached response]
F -->|Yes| E
E --> H[Return fresh response]
FlagBehavior
--no-cacheSkip cache entirely, always fetch fresh
--refreshFetch fresh and update cache
CommandDescription
cache statusList all cached responses with size, age, expiry
cache clearRemove all cached responses
cache clear {namespace}Remove cached responses for a specific namespace

Good candidates:

  • The endpoint returns a complete, static or slow-changing dataset
  • The response is larger than ~10KB
  • The data doesn’t change based on time-of-day or real-time events
  • Multiple calls with the same parameters return identical results

Bad candidates:

  • The data changes frequently (live prices, real-time feeds)
  • The response depends on authentication state
  • The endpoint has rate limits that make caching counterproductive

Handlers (preRequest, postRequest) still execute on cached data. The cache stores the raw API response before postRequest transformation.

Route tests always bypass the cache to ensure they test the live API. The --no-cache flag is implied during test execution.

CodeSeverityRule
VAL060errorIf preload is present, it must be a plain object
VAL061errorpreload.enabled must be a boolean
VAL062errorpreload.ttl must be a positive integer (> 0)
VAL063warningpreload.description if present must be a string
VAL064infoRoutes with preload.enabled: true and no parameters are ideal cache candidates
VAL065warningRoutes with preload.enabled: true and required parameters should document caching behavior