内容
# Letta MCP 适配器 Mod
Letta Code 的一个 Mod,通过一个紧凑的 `mcp` 代理工具暴露 MCP 服务器,并带有可选的缓存支持的直接工具。该适配器旨在避免在模型上下文中转储每个 MCP 工具模式,同时仍然允许代理连接到服务器、刷新元数据、搜索工具、描述模式和按需调用 MCP 工具。
## 本 Mod 提供的内容
- 一个紧凑的、可调用模型的 `mcp` 工具,用于状态、搜索、描述、连接、OAuth 和工具调用。
- 一个人类可用的 `/lmcp` 斜杠命令,用于设置、状态、缓存工具列表、重新连接和 OAuth 操作。
- 延迟 MCP 连接:激活时读取本地配置/缓存,但不启动 MCP 服务器进程或执行 HTTP MCP 网络工作。
- `~/.letta/mcp-adapter/cache.json` 下的元数据缓存。
- Stdio、流式 HTTP 和 SSE MCP 传输。
- HTTP 承载身份验证和 OAuth 授权码/客户端凭证流。
- 可选的直接工具注册,仅限缓存。
- 保护的 Letta 权限叠加层,以及主机支持时的状态/面板 UI 集成。
## 要求
- 带有本地 Mod 支持的 Letta Code。
- 用于本地开发/构建的 Bun。
- 可用于使用 Node 命令的 stdio MCP 服务器的 Node.js。
## 安装和构建
克隆仓库并安装依赖项:
```bash
git clone <此仓库网址> letta-mcp-mod
cd letta-mcp-mod
bun install
```
运行检查:
```bash
bun test
bun run typecheck
```
构建捆绑的 Mod 文件:
```bash
bun run build
```
构建写入:
```text
dist/letta-mcp-adapter.mjs
```
`dist/` 是故意被 git 忽略的;请在源代码更改时在本地重新构建。
## 将 Mod 安装到 Letta Code
Letta Code 从以下位置加载本地 Mod:
```text
~/.letta/mods/
```
如有需要,请创建目录:
```bash
mkdir -p ~/.letta/mods
```
### 复制构建的捆绑包
Letta Code 目前通过文件系统目录条目发现 Mod 文件,这些条目必须是常规文件。不要将此捆绑包安装为符号链接:符号链接的 Mod 被加载器忽略。
```bash
bun run build
cp dist/letta-mcp-adapter.mjs ~/.letta/mods/letta-mcp-adapter.mjs
```
在稍后重新构建时,请再次复制文件并重新加载 Letta Code。
### 重新加载 Letta Code
安装或重新构建 Mod 后,请重新启动 Letta Code 或运行:
```text
/reload
```
## MCP 配置文件
适配器按合并顺序读取 JSON 配置文件:
1. `~/.config/mcp/mcp.json`
2. `~/.letta/mcp-adapter/mcp.json`
3. `<项目>/.mcp.json`
4. `<项目>/.letta/mcp.json`
后面的文件会覆盖前面的文件中相同的服务器名称和设置。对于项目特定的设置,请在项目根目录中放置一个 `.mcp.json`。
您可以使用以下命令检查 Letta 看到的路径:
```text
/lmcp setup
```
使用以下命令创建启动项目配置:
```text
/lmcp setup create
```
## `.mcp.json` 示例
### Stdio 服务器
使用_stdio_用于作为子进程启动的本地 MCP 服务器:
```json
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."]
}
}
}
```
然后刷新元数据:
```text
/lmcp reconnect filesystem
```
### 带 Bearer Auth 的 HTTP 服务器
优先使用 `bearerTokenEnv` 而不是内联令牌:
```json
{
"mcpServers": {
"remote": {
"url": "https://mcp.example.com/mcp",
"transport": "streamable-http",
"auth": "bearer",
"bearerTokenEnv": "MCP_REMOTE_TOKEN",
"headers": {
"X-Client": "letta-code"
}
}
}
}
```
在环境中运行 Letta Code,并使用 `MCP_REMOTE_TOKEN`,然后:
```text
/lmcp reconnect remote
```
您可以强制使用 SSE 代替。如果省略或设置为 `"auto"`,适配器将尝试流式 HTTP 并降级为 SSE。
### OAuth 授权码服务器
使用授权码 OAuth 进行用户登录流程:
```json
{
"mcpServers": {
"linear": {
"url": "https://mcp.linear.app/mcp",
"auth": "oauth",
"oauth": {
"grantType": "authorization_code",
"clientId": "${LINEAR_CLIENT_ID}",
"clientSecret": "$env:LINEAR_CLIENT_SECRET",
"redirectUri": "http://127.0.0.1:3334/callback",
"scope": "read write",
"clientName": "Letta MCP Adapter"
}
}
}
}
```
启动登录:
```text
/lmcp auth-start linear
```
在浏览器中打开返回的授权 URL。登录后,复制完整的重定向 URL 并运行:
```text
/lmcp auth-complete linear <完整的重定向 URL>
```
检查本地身份验证状态:
```text
/lmcp auth-status linear
```
清除存储的 OAuth 材料:
```text
/lmcp auth-clear linear
```
最后刷新元数据:
```text
/lmcp reconnect linear
```
### OAuth 客户端凭证
使用客户端凭证进行机器到机器的 OAuth 服务器:
```json
{
"mcpServers": {
"machine": {
"url": "https://mcp.example.com/mcp",
"auth": "oauth",
"oauth": {
"grantType": "client_credentials",
"clientId": "${MCP_CLIENT_ID}",
"clientSecret": "$env:MCP_CLIENT_SECRET",
"tokenUrl": "https://auth.example.com/oauth/token",
"audience": "https://mcp.example.com",
"scope": "read"
}
}
}
}
```
获取并存储令牌:
```text
/lmcp auth-start machine
```
然后刷新元数据:
```text
/lmcp reconnect machine
```
### 可选的直接工具
默认情况下,只注册紧凑的 `mcp` 代理工具。直接 MCP 工具是可选的,并在 Mod 激活期间从本地元数据缓存注册。
全局启用所有缓存的工具:
```json
{
"settings": {
"directTools": true,
"toolPrefix": "server"
},
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."]
}
}
}
```
仅为一个服务器启用直接工具:
```json
{
"settings": {
"directTools": false
},
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."],
"directTools": true
}
}
}
```
允许特定直接工具:
```json
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"directTools": ["search_repositories", "get_file_contents"]
}
}
}
```
直接工具工作流程:
1. 配置服务器。
2. 运行 `/lmcp reconnect <server>` 以缓存元数据。
3. 运行 `/reload` 以便 Letta Code 重新激活 Mod 并从缓存中注册直接工具。
`toolPrefix` 控制直接/代理公开的名称:
- `"server"`(默认):`github_search_repositories`
- `"short"`:从服务器名称中删除后缀 `-mcp` 前缀
- `"none"`:在有效且非冲突时使用原始 MCP 工具名称
## `/lmcp` 命令参考
| 命令 | 目的 |
| --- | --- |
| `/lmcp` | 显示 MCP 适配器状态。 |
| `/lmcp status` | 与 `/lmcp` 相同。显示配置的服务器/缓存状态和提示。 |
| `/lmcp tools` | 列出缓存的 MCP 工具和资源支持的合成工具。不连接。 |
| `/lmcp reconnect` | 依次连接到每个配置的服务器并刷新元数据缓存。 |
| `/lmcp reconnect <server>` | 连接到一个服务器并刷新其元数据缓存。 |
| `/lmcp auth-start <server>` | 启动 OAuth 登录,或为该服务器获取客户端凭证令牌。 |
| `/lmcp auth-complete <server> <redirectUrl>` | 使用复制的重定向 URL 完成授权码 OAuth。 |
| `/lmcp auth-status <server>` | 显示本地 OAuth 令牌/客户端信息/待定身份验证/发现状态是否存在。 |
| `/lmcp auth-clear <server>` | 清除为服务器存储的 OAuth 材料。 |
| `/lmcp setup` | 显示配置路径和示例 `.mcp.json`。 |
| `/lmcp setup create` | 如果不存在,则创建启动项目 `.mcp.json`。 |
| `/lmcp help` | 显示命令用法。 |
当 Letta Code 暴露面板 UI 支持时,命令可能会打开一个短暂的过渡面板。完整详细信息保留在命令输出中。
## 面向模型的 `mcp` 代理快速参考
面向代理的代理接受一个小对象:
```ts
mcp({
search?: string,
regex?: boolean,
includeSchemas?: boolean,
describe?: string,
server?: string,
connect?: string,
tool?: string,
args?: string,
action?: "auth-start" | "auth-complete" | "auth-status" | "auth-clear"
})
```
示例:
```ts
// 仅限本地配置/缓存的状态
mcp({})
// 刷新一个服务器的元数据
mcp({ connect: "filesystem" })
// 搜索缓存的元数据
mcp({ search: "read file", includeSchemas: false })
// 缓存名称/描述的有界正则搜索
mcp({ search: "/read|list/i", regex: true, includeSchemas: false })
// 描述缓存的工具模式
mcp({ describe: "filesystem_read_file" })
// 调用 MCP 工具。参数必须是 JSON 字符串。
mcp({ tool: "filesystem_read_file", args: "{\"path\":\"README.md\"}" })
// OAuth 操作
mcp({ action: "auth-status", server: "linear" })
mcp({ action: "auth-clear", server: "linear" })
```
模式优先级为:
```text
action > tool > connect > describe > search > server > status
```
## 权限行为
当 Letta Code 暴露权限 API 时,Mod 注册一个权限叠加层。紧凑的 `mcp` 工具和直接工具也声明 `requiresApproval: true`;叠加层提供更精确的允许/询问/拒绝决定。
默认行为:
- 仅允许只读状态、搜索、描述、缓存的服务器列表和 `/lmcp tools`。
- 连接或重新连接配置的服务器会询问,因为它可能会启动进程或发出网络请求。
- 默认情况下,未知的实时目标被拒绝。
- `auth-status` 被允许,因为它仅报告本地状态。
- `auth-start`、`auth-complete` 和 `auth-clear` 会询问,因为它们会更改身份验证状态或存储的凭证。
- 缓存的工具调用除非看起来有风险,否则会被允许。
- 包含 `delete`、`write`、`update`、`exec`、`run`、`shell` 或 `browser` 等词的工具名称默认情况下会询问。
- 具有路径类似键(`path`、`file`、`dir`、`cwd`、`target`、`destination` 等)的工具参数如果解析到当前工作目录之外,则会询问。
- 直接工具使用与代理工具调用相同的风险检查。
- 如果在批准阶段批准了有风险的调用,但在执行时参数发生变化,则该调用将被拒绝。
使用 `settings.approval` 调整权限默认值:
```json
{
"settings": {
"approval": {
"dangerousTools": "ask",
"unknownServers": "deny",
"configWrites": "alwaysAsk"
}
},
"mcpServers": {}
}
```
有效决定为 `allow`、`ask`、`alwaysAsk` 和 `deny`。
注意:
- `dangerousTools` 控制危险的工具名称和工作目录外的路径参数。
- `unknownServers` 控制尝试连接/调用未知服务器。
- `configWrites` 保留用于未来的模型可调用的配置写入操作;当前的 `/lmcp setup create` 命令是人类调用的。
## UI 和资源
当 Letta Code 暴露状态值时,Mod 注册一个紧凑的 `mcp` 状态值,总结配置的服务器、缓存的工具、过时/丢失的缓存和警告。 将 `settings.ui.status` 设置为 `false` 以禁用此状态值。
MCP UI 资源提示(例如 `_meta["openai/outputTemplate"]` / `_meta.uiResourceUri`)保存在缓存的元数据中,并在列表/搜索/描述输出中显示。 从 MCP 调用返回的文本资源在输出中渲染;二进制/ blob 资源被总结而不是转储。
## 安全性和局限性
- 激活不会急切地连接到 MCP 服务器。
- 搜索/列表/描述仅从本地缓存操作。
- 正则搜索受模式长度限制,默认为 200 个字符的最大值。如有需要,请使用 `settings.regexSearch.maxPatternLength` 覆盖。
- 采样和诱导设置已保留,但尚未宣传给 MCP 服务器。当前的 Letta Mod API 不提供在管理器拥有的 MCP 请求处理程序内安全范围的对话/表单输入机制。
- 应通过环境变量提供机密。不要提交 `.env`、承载令牌、OAuth 客户端机密或生成的身份验证存储。