Reference

MCP tools

Reference for every tool and resource the Carrick MCP server exposes at api.carrick.tools/mcp.

The Carrick MCP server exposes your indexed services as structured tools and resources. The endpoint is https://api.carrick.tools/mcp — one URL for everything. Your token is scoped to a workspace, and each tool call resolves to exactly one project inside it.

Tools are listed below in the order they typically fire during a coding session.

Project scoping

A workspace can hold several projects (one project = one interconnected system of repos). Every data tool accepts two optional arguments that pick which project a call queries:

NameTypeNotes
projectstringCarrick project slug to query.
repostringYour repo as owner/repo (from the git remote) or just the repo name. Carrick resolves which project it belongs to.

Pass one of them on every call — a repo’s carrick.md usually pins the right project slug. When the workspace has a single project, both can be omitted. If a call can’t be resolved to exactly one project, the tool returns a short teaching message telling the agent what to pass; list_projects shows the options.

These two parameters are not repeated in the tables below.

Intent layer

search_by_intent(query, top_k?, similarity_threshold?)

Semantic search across every exported function in the project, ranked by how closely each matches your query.

Reach for it when the agent is asking a concept question (“verify a webhook signature”, “dedupe users by email”) where keywords do not help. It searches the whole project, not a sampled subset.

Parameters:

NameTypeRequiredDefaultNotes
querystringyesPlain-English description of what the function should do.
top_knumberno8How many matches to return (max 50).
similarity_thresholdnumberno0.3Score floor for inclusion. Raise to filter weak matches; lower to widen results.

Response shape:

{
  "query": "verify a webhook signature",
  "top_k": 8,
  "similarity_threshold": 0.3,
  "total_embedded_scanned": 1247,
  "total_above_threshold": 4,
  "results": [
    {
      "service": "billing",
      "repo": "billing-service",
      "name": "verifyStripeWebhook",
      "file_path": "src/webhooks/stripe.ts",
      "line_number": 24,
      "intent": "Verifies a Stripe webhook signature using the signing secret and rejects requests with mismatched HMACs.",
      "similarity": 0.82
    }
  ]
}

list_function_intents(service?, exclude_service?, limit?, offset?, typed_only?, name_contains?, intent_contains?)

Lists exported functions alongside their LLM-generated intents. Useful for browsing a service’s surface area, or for comparing what sibling services have implemented.

Prefer search_by_intent for concept queries. Use this when you want to scan a whole service end to end, or to diff implementations across two services. Results are paginated: the full haystack runs to thousands of functions, so each call returns one page and a next_offset to fetch the next.

Parameters:

NameTypeRequiredDefaultNotes
servicestringnoRestrict to one service.
exclude_servicestringnoRestrict to everything except one service.
limitnumberno50Max functions per page (max 200).
offsetnumberno0Functions to skip before this page. Pass a previous response’s next_offset to page through.
typed_onlybooleannofalseOnly functions whose signature is fully explicit (every param and the return annotated).
name_containsstringnoCase-insensitive substring filter on the function name.
intent_containsstringnoCase-insensitive substring filter on the intent text.

Response shape:

{
  "total": 1247,
  "returned": 50,
  "offset": 0,
  "limit": 50,
  "has_more": true,
  "next_offset": 50,
  "services": ["billing", "checkout", "inventory"],
  "functions": [
    {
      "service": "billing",
      "repo": "billing-service",
      "name": "verifyStripeWebhook",
      "file_path": "src/webhooks/stripe.ts",
      "line_number": 24,
      "intent": "Verifies a Stripe webhook signature using the signing secret and rejects requests with mismatched HMACs.",
      "typed": true,
      "reason": ""
    }
  ]
}

total counts the filtered set before pagination. typed is true when every parameter and the return are explicitly annotated; otherwise reason names the inferred positions (e.g. param `role` and return are inferred). Fully scanned signatures also carry signature and a per-position types_explicit map.

Structural and type layer

list_projects()

Lists the projects in your workspace and each project’s connected repos. Call it when you don’t know which project slug or repo name to pass to the other tools. Cheap — it reads workspace metadata only, no scan data. Takes no parameters (not even project/repo).

Response shape:

{
  "projects": [
    {
      "slug": "storefront",
      "display_name": "Storefront",
      "repos": ["acme/billing-service", "acme/checkout"]
    }
  ],
  "usage": "Pass `project: \"<slug>\"` (or `repo: \"<owner/repo>\"`) on the other Carrick tools to query that system."
}

list_services()

Catalogue of every service in the project’s index. Cheap. Call this first when orienting.

Response shape:

[
  {
    "repo_name": "billing-service",
    "service_name": "billing",
    "endpoint_count": 14,
    "call_count": 9,
    "last_updated": "2026-05-24T19:02:11Z",
    "commit_hash": "a3f1c9d",
    "has_types": true
  }
]

endpoint_count and call_count count operations across every protocol, the same way get_api_endpoints lists them.

get_api_endpoints(service, method?, path_contains?)

The operations a service exposes, across protocols: HTTP endpoints (GET /api/users/:id), GraphQL fields (query user), and socket events (chat:message (client→server)). Returns one row per operation; HTTP rows are mount-aware, with fully-resolved paths.

Reach for it before writing client code that calls a service, or before changing one of its routes.

Parameters:

NameTypeRequiredNotes
servicestringyesThe service to inspect (fuzzy match by repo name, service name, or trailing segment).
methodstringnoFilter by operation label: HTTP method (GET, POST, …), GraphQL kind (QUERY, MUTATION, SUBSCRIPTION), or socket direction (CLIENT->SERVER, SERVER->CLIENT).
path_containsstringnoSubstring filter on the path, GraphQL field, or event name.

Response shape:

{
  "service": "billing",
  "endpoint_count": 1,
  "endpoints": [
    {
      "protocol": "http",
      "operation": "POST /api/v1/invoices",
      "method": "POST",
      "full_path": "/api/v1/invoices",
      "handler": "createInvoice",
      "owner": "billingRouter",
      "file_location": "src/routes/invoices.ts:42"
    }
  ]
}

For GraphQL and socket rows, method/full_path carry the operation’s label pair instead — (QUERY, user) or (CLIENT->SERVER, chat:message).

get_endpoint_types(service, method, path)

Resolved TypeScript request and response types for a single operation. Each entry tells you whether the type was explicitly annotated or inferred from the handler body, and includes the source location.

Reach for it before building a request body or parsing a response. Guessing JSON shapes from a sample is the most common source of contract drift.

Parameters:

NameTypeRequiredNotes
servicestringyesThe service exposing the endpoint.
methodstringyesHTTP method — or, for a non-HTTP operation, its label from get_api_endpoints (QUERY, MUTATION, CLIENT->SERVER).
pathstringyesAPI path (matched against the service’s mount graph), GraphQL field, or socket event name.

Response shape:

{
  "service": "billing",
  "method": "POST",
  "path": "/api/v1/invoices",
  "types": [
    {
      "type_alias": "CreateInvoiceRequest",
      "type_kind": "request_body",
      "is_explicit": true,
      "source_file": "src/types/invoices.ts",
      "source_line": 12,
      "definition": "{ customer_id: string; amount_cents: number; currency: string }"
    },
    {
      "type_alias": "Invoice",
      "type_kind": "response_body",
      "is_explicit": false,
      "source_file": "src/routes/invoices.ts",
      "source_line": 58,
      "definition": "{ id: string; status: 'open' | 'paid'; amount_cents: number }"
    }
  ]
}

get_type_definition(service, type_alias)

Fully resolved definition for one named type, with transitive dependencies expanded. Use it when get_endpoint_types references a named DTO, discriminated union, or composed type whose shape you need to read.

Parameters:

NameTypeRequired
servicestringyes
type_aliasstringyes

Response shape:

{
  "service": "billing",
  "type_alias": "Invoice",
  "definition": "{ id: string; status: InvoiceStatus; amount_cents: number; line_items: LineItem[] }",
  "expanded": "{ id: string; status: 'open' | 'paid' | 'void'; amount_cents: number; line_items: { sku: string; quantity: number; unit_price_cents: number }[] }"
}

check_compatibility(consumer_service, producer_service, method?, path?)

Diff a consumer’s outbound calls against a producer’s exposed operations. HTTP calls get method-and-path matching; GraphQL and socket operations get exact-key existence checks. Surfaces missing operations (the consumer uses something the producer doesn’t expose) and unused ones (the producer exposes operations nobody calls).

Reach for it before removing a route, renaming a path, field, or event, or changing a producer’s response shape.

Parameters:

NameTypeRequiredNotes
consumer_servicestringyesThe service making the calls.
producer_servicestringyesThe service exposing the operations.
methodstringnoFilter by operation label: HTTP method, GraphQL kind, or socket direction.
pathstringnoFilter by HTTP path, GraphQL field, or socket event name.

Response shape:

{
  "consumer": "checkout",
  "producer": "billing",
  "compatible": false,
  "consumer_calls": 6,
  "producer_endpoints": 14,
  "issues": [
    {
      "severity": "error",
      "category": "missing_endpoint",
      "message": "Consumer calls POST /api/v1/invoices/draft but producer has no matching endpoint"
    },
    {
      "severity": "info",
      "category": "unused_endpoint",
      "message": "Producer exposes DELETE /api/v1/invoices/:id but consumer doesn't call it"
    }
  ]
}

get_service_dependencies(service?)

With no argument, returns project-wide npm dependency conflicts: any package pinned to more than one version across services. With a service name, returns that service’s merged dependency map.

Reach for it before adding or upgrading an npm dependency, or when a TypeScript build error looks like a version mismatch.

Parameters:

NameTypeRequiredNotes
servicestringnoOmit for the project-wide conflict view.

Project-wide response shape:

{
  "total_packages": 312,
  "conflict_count": 4,
  "conflicts": [
    {
      "package_name": "zod",
      "severity": "error",
      "versions": [
        { "service": "billing", "version": "3.22.4" },
        { "service": "checkout", "version": "4.0.1" }
      ]
    }
  ]
}

Per-service response shape:

{
  "service": "billing",
  "package_count": 87,
  "dependencies": {
    "zod": { "version": "3.22.4" }
  }
}

Onboarding

scaffold()

Generates the files needed to onboard the current repo onto Carrick, and returns them with instructions for the agent to act on:

  • .github/workflows/carrick.yml — the scan workflow, written verbatim. Keyless via GitHub Actions OIDC; there is no secret to configure.
  • carrick.md — an instruction block telling the agent when to reach for Carrick’s tools, pinned to the resolved project slug. The instructions say to fold it into an existing AGENTS.md/CLAUDE.md when the repo has one.
  • carrick.json — a config skeleton the agent is told to populate by scanning the repo: the service name(s), and the env vars and domains that name internal services versus third-party APIs (using a services array for monorepos).

Your coding agent calls this once per repo during setup. Takes only the shared project/repo scoping arguments, and — unlike the data tools — works on a project whose repos have never been scanned, since that’s exactly when you run it.

Resources

Resources are read-only URIs that the MCP client can fetch directly. Resource URIs carry no project/repo arguments, so they resolve from the token alone: they work when the workspace has a single project, and return a teaching message otherwise.

carrick://services

Full service catalogue as JSON. Equivalent to list_services() but exposed as a resource so the client can subscribe to it.

carrick://services/{name}/types.d.ts

Bundled .d.ts file for one service. Useful when you want the agent to read the whole type surface area in one fetch instead of round-tripping get_type_definition for each name.

Errors and empty results

Every tool returns a single text content block containing JSON. Errors and empty results are represented as plain text inside the same block:

  • Missing service: Service "checkout" not found. Use list_services to see available services.
  • Unresolved project: a short message telling the agent to pass project or repo (and which slugs exist).
  • Project with no scan data yet: a message saying the project resolved but its repos haven’t been scanned since being connected.
  • Empty search: Scanned 1247 embedded intents but none scored above the similarity threshold of 0.3. Try a more concrete phrase, or relax similarity_threshold.
  • Missing types: Endpoint POST /api/v1/invoices exists but has no extracted types.

Treat any response whose first character is not { or [ as a textual diagnostic rather than a structured payload.

  • Connecting your agent covers the setup that gates access to these tools, and the instruction block that tells your agent when to reach for each.
  • Quickstart walks the full setup end to end.