关于 adonis-mcp
adonis-mcp 是用于在 AdonisJS 应用中构建 MCP 服务的库,面向 AdonisJS 开发者。它会从指定目录自动发现工具、资源和提示词类,并支持验证、权限控制与协议处理。
主要功能
- 01自动发现工具、资源和提示词类
- 02通过 Ace 命令生成类模板
- 03支持工具、资源和提示词响应
- 04集成 VineJS 验证与依赖注入
- 05提供补全、权限和协议上下文
适用场景
- 01在 AdonisJS 应用中创建 MCP 服务
- 02向 MCP 客户端提供工具、资源和提示词
- 03为处理器添加验证与授权逻辑
- 04测试 MCP 请求并处理协议差异
MCP 相关
该库用于在 AdonisJS 应用中构建 MCP 服务,向 MCP 客户端提供工具、资源和提示词。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ batosai/ adonis-mcp --skill adonis-mcp安装后在 Claude Code 中输入/adonis-mcp确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/authentication.mdsetup.mdtesting.md详细介绍
AdonisJS MCP (@jrmc/adonis-mcp)
在 AdonisJS 应用中构建 Model Context Protocol 服务端。工具、资源和提示词均为类,会从 app/mcp/{tools,resources,prompts}/ 中自动发现。
尚未安装? 请参阅 references/setup.md — 安装、config/mcp.ts、路由注册、排除 CSRF、无状态中间件、旧版会话、stdio 传输。
身份验证与权限? 请参阅 references/authentication.md — 身份验证中间件、Bouncer abilities/policies、类型扩展。
测试与调试? 请参阅 references/testing.md — 使用 FakeTransport 的 Japa 集成测试、MCP Inspector。
关键约定
- 文件命名是自动发现的必要条件:文件必须以
_tool.ts、_resource.ts或_prompt.ts结尾,并放在app/mcp/tools/、app/mcp/resources/或app/mcp/prompts/下(路径可通过adonisrc.ts中的directories.mcp配置)。命名错误的文件会被静默忽略。 - 始终使用 ace 生成框架代码(会使用正确的模板,包括应用使用 VineJS 时对应的 VineJS 变体):
node ace make:mcp-tool my_tool node ace make:mcp-resource my_resource node ace make:mcp-prompt my_prompt - Schema 是 JSON Schema,必须从
schema()返回为as Schema。可使用 Zod(z.toJSONSchema(zodSchema, { io: "input" }))或 VineJS ≥ v4(vine.create(vineSchema).toJSONSchema())生成。 - 将多个内容作为数组返回。没有
response.send()方法:return [response.text('First'), response.text('Second')]。 - 始终对 bouncer 调用使用
await— 忘记await会使授权错误变成未处理的拒绝,而不是 JSON-RPC 错误。
工具
import type { ToolContext } from '@jrmc/adonis-mcp/types/context'
import type { BaseSchema } from '@jrmc/adonis-mcp/types/method'
import { Tool } from '@jrmc/adonis-mcp'
type Schema = BaseSchema<{
title: { type: "string" }
url: { type: "string" }
}>
export default class AddBookmarkTool extends Tool<Schema> {
name = 'create_bookmark' // required, unique
title = 'Create Bookmark' // optional
description = 'Create a new bookmark'
async handle({ args, response, auth, bouncer, request }: ToolContext<Schema>) {
return response.text(JSON.stringify({ title: args?.title }))
}
schema() {
return {
type: "object",
properties: {
title: { type: "string", description: "Bookmark title" },
url: { type: "string", description: "Bookmark URL" }
},
required: ["title", "url"]
} as Schema
}
}
对于不需要输入的工具,完全省略 schema() 和 <Schema> 泛型。
工具注解(来自 @jrmc/adonis-mcp/tool_annotations)
可组合的类装饰器:@isReadOnly()、@isOpenWorld()、@isDestructive()、@isIdempotent()。每个装饰器都接受可选的布尔值(@isReadOnly(false))。
资源
import type { ResourceContext } from '@jrmc/adonis-mcp/types/context'
import { Resource } from '@jrmc/adonis-mcp'
type Args = { id: string }
export default class UserDocumentResource extends Resource<Args> {
name = 'user_document'
uri = 'document:///{id}' // required, unique; RFC 6570 template
mimeType = 'text/plain'
title = 'User Document'
description = 'Access user documents by ID'
async handle({ args, response }: ResourceContext<Args>) {
const content = await loadDocument(args?.id)
this.size = content.length // set size when known
return response.text(content) // or response.blob(buffer) for binary
}
}
- URI 模板运算符:
{name}、{/name}、{?name}、{&name}、{#name}、{+name}、{.name}。模板变量会以类型化形式传入args。 - 资源注解(来自
@jrmc/adonis-mcp/annotations):@priority(0.0–1.0)、@audience(Role.USER | Role.ASSISTANT | [both])(Role 来自@jrmc/adonis-mcp/enums/role)、@lastModified('ISO-8601')。
提示词
import type { PromptContext } from '@jrmc/adonis-mcp/types/context'
import type { BaseSchema } from '@jrmc/adonis-mcp/types/method'
import { Prompt } from '@jrmc/adonis-mcp'
type Schema = BaseSchema<{
code: { type: "string" }
language: { type: "string" }
}>
export default class CodeReviewPrompt extends Prompt<Schema> {
name = 'code_review'
title = 'Code Review'
description = 'Review code and provide feedback'
async handle({ args, response }: PromptContext<Schema>) {
return [
response.text(`Please review this ${args?.language} code:`),
response.text(args?.code),
response.embeddedResource('file:///guidelines/coding-standards.md'),
]
}
schema() { /* same JSON Schema pattern as tools */ }
}
响应
| 方法 | 处理器 | 用途 |
|---|---|---|
response.text(string) | 工具、资源、提示词 | 纯文本 |
response.image(base64, mime) / response.audio(base64, mime) | 工具、提示词 | 媒体 |
response.structured(object) | 工具 | 结构化 JSON |
response.blob(stringOrBuffer) | 资源 | 文本或 Buffer,由包编码为 base64 |
response.resourceLink(uri) | 工具 | 指向已注册资源的链接 |
response.embeddedResource(uri) | 工具、提示词 | 嵌入已注册资源 |
response.error(message) | 工具、资源 | 工具错误或 JSON-RPC 资源错误 |
对于多个工具或提示词内容,直接返回数组。文本、图像、音频、blob、资源链接、嵌入式资源和错误内容支持 .withMeta({ ... });结构化内容不支持。
错误
若要指定 JSON-RPC 错误代码或附加数据,请抛出异常,而不要使用 response.error():
import JsonRpcException from '@jrmc/adonis-mcp/exceptions'
import { ErrorCode } from '@jrmc/adonis-mcp/enums/error'
throw new JsonRpcException('Not found', ErrorCode.InvalidParams, request.id, { resource: 'user' })
可用的 ErrorCode 值包括 ConnectionClosed (-32000)、RequestTimeout (-32001)、HeaderMismatch (-32020)、MissingRequiredClientCapability (-32021)、UnsupportedProtocolVersion (-32022)、ParseError (-32700)、InvalidRequest (-32600)、MethodNotFound (-32601)、InvalidParams (-32602) 和 InternalError (-32603)。工具、资源和提示词中均可使用异常(request.id 来自上下文)。
感知协议的处理器
处理器可以从其上下文中检查 protocolEra、protocolVersion、clientCapabilities、clientInfo 和
logLevel。现代 2026-07-28 请求是无状态的;旧版客户端使用
initialize 和 MCP-Session-Id。更改生成的中间件或缓存策略之前,请阅读
references/setup.md。
基本工具参数可以要求与之对应的 HTTP 标头:
region: { 'type': 'string', 'x-mcp-header': 'Region' }
对于现代 tools/call,请求正文中的值必须与 Mcp-Param-Region 一致。此注解仅限于基本类型的 string、integer 或 boolean 属性。
在处理器中使用 VineJS 验证
如果已注册 VineJS 提供程序(adonisrc.ts 中的 @jrmc/adonis-mcp/vinejs_provider),请复用应用的验证器——验证错误会自动转换为 JSON-RPC 错误,无需 try/catch:
async handle({ request, response }: ToolContext) {
const payload = await request.validateUsing(ArticleValidator)
// ...
}
补全(提示词参数/资源模板变量的自动补全)
需要在 config/mcp.ts 中设置 completions: true。在提示词或资源上实现 complete():
import type { CompleteContext } from '@jrmc/adonis-mcp/types/context'
async complete({ args, response }: CompleteContext<Args>) {
if (args?.language !== undefined) {
return response.complete({ values: ['typescript', 'python'] }) // + optional hasMore, total
}
return response.complete({ values: [] })
}
依赖注入
标准 AdonisJS @inject() 可用于工具/资源/提示词的构造函数和 handle() 方法。
事件
mcp:request 和 mcp:response 会在 AdonisJS 发射器上触发(@jrmc/adonis-mcp/types/jsonrpc 中的 JsonRpcRequest/JsonRpcResponse)。