What Carrick covers
What Carrick scans, the requirements a repo needs to scan cleanly, the framework story, and the cases that fall outside MVP scope.
Carrick scans TypeScript REST services. It finds your API endpoints and the calls between services, resolves their request and response types, and indexes the result. Your agent queries that index over MCP, and the GitHub Action surfaces contract drift on pull requests.
Before you wire Carrick into a repo, check the requirements below hold and the limitations don’t block your use case. Both lists are short on purpose: the supported scope is deliberately narrow.
Requirements
A repo scans cleanly when all of these are true:
- TypeScript source. Carrick reads request and response types from TypeScript. Pure JavaScript repos can still produce a route map, but endpoint shapes will be
unknownbecause there are no types to read. - A
package.json. Used to detect the framework, resolve dependencies, and ground the dependency conflict checks. - Statically discoverable routes. Carrick finds routes by reading your source, not by running your code. If a path string or HTTP method is a literal in source (or resolvable to one), it gets indexed. If it is computed at runtime from a config file, a database, or an environment variable, it does not. See “Dynamic routing” below.
- GitHub Actions. Carrick runs as a GitHub Action, once per push or pull request, and uploads the result on main-branch runs. Local-only scans aren’t supported.
Framework coverage
Carrick works across REST frameworks. It matches on call shape (app.get, router.use, axios.post, decorators, common HTTP-client patterns) rather than specific framework packages, and adapts to the framework and version it detects in your package.json. Express 4 vs Express 5, Fastify 3 vs Fastify 4: version differences are handled automatically.
End-to-end fixture coverage as of today:
- Express has full producer plus consumer coverage, including response-type extraction and parameter and body-type extraction.
- Koa, Fastify, Hono, NestJS, and Hapi all have code-present extraction paths and should work in practice. They are not yet covered by end-to-end fixtures, so report a bug if a route does not appear in your index after a clean scan.
For unusual or in-house Express-flavoured routers, the scanner generally still picks them up because matching is on imported symbols and call shape rather than framework name. If your framework is detected but routes do not appear in the index, that is a bug worth reporting. If the framework is not detected at all, the dashboard report will say so explicitly.
What Carrick does not cover
These are out of scope at MVP and will stay that way unless we hear consistent demand.
Non-TypeScript services
Python, Go, Rust, Java, Ruby. Carrick relies on TypeScript’s compiler to extract type shapes. Porting the type sidecar to other languages is a large undertaking that does not move the needle for the TypeScript-monorepo problem Carrick exists to solve. If your stack is mixed, the TypeScript services will scan and the rest will be invisible.
Non-REST protocols
- GraphQL. If the scanner detects a GraphQL client (
graphql-request,@apollo/client,urql, and similar), the report includes a banner that says “REST contracts only” and lists the detected libraries. The endpoints those clients call are not indexed. - gRPC, tRPC over WebSocket, custom RPC frameworks. These do not produce HTTP route handlers in the shape the scanner looks for, so the routes will not appear in the index even if the consumer and producer are both TypeScript.
- Message queues, event buses, Kafka, RabbitMQ. Async messaging falls outside the REST contract surface entirely.
Dynamic routing
Carrick reads your source, it does not run your code. The following patterns are invisible to it:
- Routes built at runtime from a config file, a database, or environment-driven feature flags.
- Routes registered from arrays in a loop where the path strings are computed from variables the scanner cannot resolve to literals.
- Routes added by a plugin system where the plugin path is determined after the process starts.
The bar is: static enough to read from source. If the path strings and method names are literal in source (or trivially resolvable to literals), Carrick finds them.
Compiled or generated code
.d.ts-only services without source. There is nothing to scan.- Generated routes that live only in
dist/at runtime. If the generator commits its output to the repo, the routes scan; if the generator runs at build time and the output is gitignored, they do not. - Pre-compiled bundles. The scanner operates on TypeScript source, not on compiled JavaScript bundles or minified output.
Monorepos without per-service package.json
Each service Carrick indexes corresponds to one package.json. Polyrepos work out of the box. Monorepos with workspaces also work as long as each service directory has its own package.json (pnpm workspaces, npm workspaces, Yarn workspaces, Nx with per-app manifests). A monorepo with one root package.json covering many service directories cannot be split into separate services by Carrick; the whole repo will be indexed as a single service.
Related
- Introduction. What Carrick is for and what you can do with it.
- carrick.json. Classify env-var-driven outbound calls so contract checking can run against them.