carrick-tools/carrick
GitHub: carrick-tools/carrick
Carrick 是一个面向 TypeScript 微服务的跨仓库语义索引工具,通过 MCP 协议为 AI 编程智能体提供类型感知和意图感知的代码理解能力,同时在 PR 阶段自动检测跨服务的 API 契约偏差。
Stars: 0 | Forks: 0
# Carrick
Carrick 是一个实时的、具备类型感知和意图感知的跨仓库索引,涵盖了你的 GitHub 组织中的每一个 TypeScript 服务,并通过 Model Context Protocol 向 AI 编程智能体开放。
**开始使用:** 请在 [app.carrick.tools](https://app.carrick.tools) 注册 · 完整文档请访问 [docs.carrick.tools](https://docs.carrick.tools)
## 智能体可以提问的问题
将 Claude Code、Cursor、Windsurf 或 Codex 连接到 Carrick MCP endpoint。Carrick 能够回答关于你的组织的语义级问题,这些问题通常是智能体必须在各个仓库中通过 grep 查找才能(并且难以准确)回答的:
- “我们的各个服务中,哪些函数负责处理 webhook 签名?”
- “我们在哪里通过电子邮件对用户进行去重?”
- “哪些代码调用了 `/api/users`,以及它们期望的响应结构是什么?”
- “向我展示每一个在遇到速率限制错误时进行重试的函数。”
这些问题之所以能够得到解答,是因为该索引结合了结构化事实、解析后的类型,以及对每个函数实际功能的逐项描述。
## 索引包含哪些内容
对于你的组织中每个仓库里的每个被扫描的函数,Carrick 会存储三个层级的数据:
- **结构化。** 声明的 endpoint、发出的出站调用、挂载点以及标准化路径。
- **类型感知。** 通过 TypeScript 编译器解析的请求和响应类型,因此可以检查跨仓库的类型兼容性。
- **意图感知。** 在扫描时生成的一到两句话的描述,说明每个函数的作用,并与结构化和类型数据一同存储。
意图层是关键所在。正是它让智能体能够回答“我们在哪里通过电子邮件对用户进行去重”,而不是仅仅回答“哪些函数的名称是 `dedupeUser`”。
## 连接你的智能体
MCP endpoint 位于 `https://api.carrick.tools/mcp`。
```
claude mcp add --scope user --transport http carrick https://api.carrick.tools/mcp
```
推荐的认证方式是使用 Carrick 登录:你的智能体会打开一个浏览器,你只需点击一次“批准”,期间无需交换任何 API 密钥。我们也提供了手动粘贴密钥的备用方案。要开始使用,请在 [app.carrick.tools](https://app.carrick.tools) 注册 —— 完整的设置指南请访问 [docs.carrick.tools](https://docs.carrick.tools)。
## 填充索引
索引是通过在你想要索引的每个 TypeScript 仓库中运行 Carrick GitHub Action 来填充的。在主分支上,该操作会刷新该仓库对索引的贡献内容。在 pull request 中,Carrick App 会为你发布一条偏差评论(无需额外的工作流步骤)。
```
name: Carrick
on:
push:
branches: [main]
pull_request:
branches: [main]
# Lets Carrick re-trigger this repo's main scan when a sibling repo in the
# project changes. Optional today and dormant unless enabled server-side —
# included here so it's already wired if you ever turn it on.
repository_dispatch:
types: [carrick-sibling-updated]
permissions:
id-token: write
contents: read
jobs:
carrick:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: carrick-tools/carrick@v1
```
无需提供任何密钥。`id-token: write` 权限允许该操作生成一个短期的 GitHub Actions OIDC token,Carrick 会使用它来验证仓库身份并授权上传。在 pull request 中,Carrick App 会自行发布偏差评论,因此工作流不需要额外的权限,也不需要发布评论的步骤。只需确保 Carrick GitHub App 已安装在该组织上,并且该仓库已在控制台中连接到某个项目。
从 fork 发起的 pull request 会被妥善跳过:GitHub 不会为 fork 的运行提供 OIDC 凭证,因此该操作只会打印一条通知并成功退出,而不会导致检查失败。当维护者将该分支推送到仓库本身时,扫描就会运行。
## MCP 工具
MCP endpoint 将索引公开为你的智能体可以直接调用的结构化工具。
| 工具 | 用途 |
| :--- | :--- |
| `search_by_intent` | 根据函数的功能查找函数 —— 使用自然语言查询并与意图描述进行匹配 |
| `list_projects` | 列出你工作区中的 Carrick 项目,以及每个项目连接的仓库 |
| `list_services` | Carrick 在你的组织中索引的每一个服务 |
| `list_function_intents` | 导出函数的一到两句话描述,可按服务搜索 |
| `get_api_endpoints` | 获取指定服务声明的 endpoint |
| `get_endpoint_types` | 获取特定 endpoint 解析后的请求和响应类型 |
| `get_type_definition` | 按名称获取整个组织内完全解析的 TypeScript 类型 |
| `get_service_dependencies` | 获取调用了指定生产者的服务 |
| `check_compatibility` | 检查服务 A 对服务 B 的调用是否与生产者的契约匹配 |
| `scaffold` | 生成用于接入仓库的文件:GitHub Actions 工作流、智能体指南以及 `carrick.json` 骨架 |
## 关于 Pull Request
在 pull request 中,Carrick App 会发布一条评论,总结针对已索引服务检测到的偏差:生产者和消费者之间的类型不匹配、不匹配的 HTTP 动词、缺失或孤立的 route,以及 npm 依赖版本冲突。每次推送到 PR 时,它都会原地更新同一条评论。新项目默认开启 PR 评论功能,可以在控制台中按项目进行切换;PR 运行永远不会更改索引。
## 配置说明
在每个被索引的服务中添加一个 `carrick.json`,以帮助对出站调用进行分类。
```
{
"serviceName": "order-service",
"internalEnvVars": ["USER_SERVICE_URL", "INVENTORY_API"],
"externalEnvVars": ["STRIPE_API", "GITHUB_API"],
"internalDomains": ["https://api.yourcompany.com"],
"externalDomains": ["https://api.stripe.com", "https://api.github.com"]
}
```
| 字段 | 描述 |
| :--- | :--- |
| `serviceName` | 该服务的友好名称 |
| `internalEnvVars` | 指向你组织内部其他服务的环境变量。针对这些服务的调用会根据索引进行验证。 |
| `externalEnvVars` | 指向第三方 API 的环境变量。针对这些服务的调用会被忽略。 |
| `internalDomains` | 内部服务的完整 URL 前缀 |
| `externalDomains` | 需要忽略的第三方 API 的完整 URL 前缀 |
当 Carrick 看到类似 `fetch(process.env.ORDER_SERVICE_URL + '/orders')` 的调用时,它需要知道 `ORDER_SERVICE_URL` 是指向内部还是外部。未分类的环境变量将作为配置建议显示在 PR 评论中。
### Monorepos
`carrick.json` 是可选的 —— 如果没有配置(或者像上面那样的扁平配置),Carrick 会将整个仓库作为单个服务进行扫描。如果要为一个仓库中的多个服务(例如一组 lambdas 和一个控制台)建立索引,请改用 `services` 数组来声明它们。每个条目都会被独立扫描,并作为单独的服务进行索引:
```
{
"services": [
{
"name": "check-or-upload",
"directory": "lambdas/check-or-upload",
"include": ["lambdas/_shared"],
"internalEnvVars": ["CARRICK_API_ENDPOINT"]
},
{
"name": "dashboard",
"directory": "app",
"tsconfig": "tsconfig.json"
}
]
}
```
| 字段 | 描述 |
| :--- | :--- |
| `name` | 服务名称(在 `services` 条目中作为 `serviceName` 的别名) |
| `directory` | 服务根目录,相对于 `carrick.json`。不在所有声明目录之内的文件将被忽略 |
| `include` | 用于类型/函数解析的额外源码根目录(例如在构建时复制进来的共享库),路径相对于 `carrick.json` |
| `tsconfig` | 该服务的 `tsconfig.json` 路径,相对于 `directory`。将类型提取范围限定在该服务内 |
每个服务也接受调用分类字段(`internalEnvVars`、`externalEnvVars`、`internalDomains`、`externalDomains`)。当存在 `services` 时,任何同级的顶层扁平字段都会被忽略。在声明的服务之间,就像在跨仓库一样,会检测跨服务的偏差、依赖冲突以及重复的意图。
## 工作原理
1. SWC 将每个 TypeScript 文件解析为 AST。
2. 静态分析阶段会提取函数导出、挂载的 router、通过模式匹配获取的 HTTP 调用、GraphQL schema 和操作,以及 WebSocket 事件契约。
3. LLM 智能体负责处理模式匹配无法覆盖的情况:动态 URL、工厂函数以及特定框架的路由。
4. TypeScript 侧车程序通过实际的 TypeScript 编译器解析请求和响应类型。
5. 第二轮 LLM 处理会编写针对具体函数的意图描述。
6. 组织索引保存在 DynamoDB 和 S3 中,并在每次运行服务的主分支时进行刷新。
## 许可证
[Elastic License 2.0](LICENSE.md)。版权所有 (c) 2026 Far Harbour B.V.
## 开发说明
有关构建、测试和贡献规范,请参阅 [AGENTS.md](AGENTS.md)。
```
cargo test
cargo fmt
cargo clippy
```
安装可选的 pre-commit hook,以便在每次提交前运行格式化和测试:
```
./scripts/install-hooks.sh
```
标签:C2, 可视化界面, 漏洞探索, 通知系统