adonis-mcp について
adonis-mcpは、AdonisJSアプリケーション内でMCPサーバーを構築するライブラリで、AdonisJS開発者向けです。指定ディレクトリからツール、リソース、プロンプトのクラスを自動検出し、バリデーション、認可、プロトコル対応のハンドラーを提供します。
主な機能
- 01ツール・リソース・プロンプトのクラスを自動検出
- 02Aceコマンドによるクラスのひな形生成
- 03ツール・リソース・プロンプトの応答に対応
- 04VineJSバリデーションと依存性注入
- 05補完・認可・プロトコル情報を提供
活用シーン
- 01AdonisJSアプリ内でのMCPサーバー構築
- 02MCPクライアントへのツール・リソース・プロンプト公開
- 03ハンドラーへのバリデーションと認可の追加
- 04MCPリクエストのテストとプロトコル差異への対応
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 のアビリティ/ポリシー、型拡張。
テストとデバッグについて? 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 - スキーマは 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()。それぞれ省略可能な boolean を受け取ります (@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() の代わりに throw してください:
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、および
log を検査できます。モダンな 2026-07-28 リクエストはステートレスです。レガシークライアントは
initialize と MCP-Session-Id を使用します。ミドルウェアやキャッシュポリシーを変更する前に
references/setup.md をお読みください。
プリミティブツールの引数は、ミラーリングされた HTTP を要求できます:
region: { 'type': 'string', 'x-mcp-header': 'Region' }
モダンな tools/c では、ボディの値が Mcp-Param-Reg と一致する必要があります。このアノテーションは
プリミティブな 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 は Adonis エミッター上で発行されます(@jrmc/adonis-mcp/types/jsonrpc の JsonRpcRequest / JsonRpcResponse)。