Turned up while writing the path assertions in #337. The four product APIs no longer agree on how a contract version is expressed.
| API |
Prefix |
Version negotiation |
api.ferrlabs.com |
none |
— |
api.ferrfleet.com |
none |
x-ferrfleet-api-version, date-based |
api.ferrtrack.com |
/v1 |
none |
api.ferrgrowth.com |
/v1 |
none |
The MCP client matches whatever each API serves today, so nothing is broken. This is about the convention drifting rather than a live defect, which is why it is P3.
Why it is worth settling
ferrlabs-api-version exists in Kit precisely to replace the prefix, and its own documentation is blunt about it: a /v1 that never moves "is not versioning — it is a prefix", and it stops holding "the moment there is a client that cannot be updated in step: a self-hosted install, an API token in someone else's script, an MCP server".
Two of the four products have adopted it. The other two carry a prefix that has never moved and cannot move without a second router.
That FerrFleet dropped the prefix is also what broke @ferrfleet/mcp until #323: the client was still calling /v1/agents. The same migration on FerrTrack or FerrGrowth would break their MCPs the same way, and the tests added in #337 are what would now catch it.
What this needs
A decision on the API side, not here: either the two remaining products adopt ferrlabs-api-version and drop the prefix, or the convention is that the prefix stays and FerrFleet was the outlier. Either is defensible; the drift is not.
Once it is settled, the client change is small. packages/ferrtrack-mcp/src/api-base.ts and packages/ferrgrowth-mcp/src/api-base.ts would gain the same fleetRequest-style helper that pins the base URL and the version header in one place, and the path assertions in packages/*/src/tools/__tests__/writes.test.ts would move with it.
Turned up while writing the path assertions in #337. The four product APIs no longer agree on how a contract version is expressed.
api.ferrlabs.comapi.ferrfleet.comx-ferrfleet-api-version, date-basedapi.ferrtrack.com/v1api.ferrgrowth.com/v1The MCP client matches whatever each API serves today, so nothing is broken. This is about the convention drifting rather than a live defect, which is why it is P3.
Why it is worth settling
ferrlabs-api-versionexists in Kit precisely to replace the prefix, and its own documentation is blunt about it: a/v1that never moves "is not versioning — it is a prefix", and it stops holding "the moment there is a client that cannot be updated in step: a self-hosted install, an API token in someone else's script, an MCP server".Two of the four products have adopted it. The other two carry a prefix that has never moved and cannot move without a second router.
That FerrFleet dropped the prefix is also what broke
@ferrfleet/mcpuntil #323: the client was still calling/v1/agents. The same migration on FerrTrack or FerrGrowth would break their MCPs the same way, and the tests added in #337 are what would now catch it.What this needs
A decision on the API side, not here: either the two remaining products adopt
ferrlabs-api-versionand drop the prefix, or the convention is that the prefix stays and FerrFleet was the outlier. Either is defensible; the drift is not.Once it is settled, the client change is small.
packages/ferrtrack-mcp/src/api-base.tsandpackages/ferrgrowth-mcp/src/api-base.tswould gain the samefleetRequest-style helper that pins the base URL and the version header in one place, and the path assertions inpackages/*/src/tools/__tests__/writes.test.tswould move with it.