@dinko/adonis-mcp
adonis-oauth-mcp
2つのAdonisJSパッケージのためのモノレポです。これらは一緒にバージョン管理・リリースされるため、リソース登録コントラクトの変更にクロスリポジトリの調整は不要です。
パッケージ | 担当 |
| OAuth 2.1認可サーバー: token / approve / deny、redirect-URI検証、認可コードの保存、認可サーバーメタデータ、およびリソースレジストリによって駆動される汎用の保護リソースメタデータエンドポイント。MCPについては何も知りません。 |
| MCPサーバー: リクエストハンドラー、コントローラー、ツールコントラクト、認証ミドルウェア。自身をOAuth保護リソースとして登録し、リソースURL、スコープ、クライアント、 |
依存関係は一方向です: mcp → oauth。oauth内の何もmcpからインポートしてはいけません。
レイアウト
各パッケージはAdonisJSパッケージ規約に従います:
index.ts re-exports `configure` and `stubsRoot` (what `node ace configure` imports)
configure.ts the configure hook, driving codemods and stubs
stubs/ .stub templates rendered into the target app
src/ runtime code the app imports
providers/ service providers registered by the configure hook
services/ container services, for code that cannot use dependency injectionRelated MCP server: mcpauth
開発
npm install # links the workspaces
npm run build # tsc + copy stubs, per package
npm run typecheck
npm test # runs against build/, so build first開発中は、レジストリではなく、このチェックアウトからアプリにインストールしてください(npm link、file:、またはgit依存関係)。
@dinko/adonis-oauth
サードパーティのクライアントにアクセストークンを渡す必要があるAdonisJSアプリケーション向けの、PKCE対応OAuth 2.1認可サーバー。
パッケージはプロトコルを所有します。アプリケーションは委任できない3つのものを所有します: 同意画面、発行するトークン、ルート。
npm i @dinko/adonis-oauth
node ace configure @dinko/adonis-oauth設定すると3つのファイルが生成され、既存のファイルを上書きすることはありません:
ファイル | 対処方法 |
| リソース、そのクライアント、 |
|
|
| ここからはあなたのものです: パッケージに委任し、パッケージがカバーしないものを追加する場所です。 |
ルート
自動登録はされません — どこに配置し、どのミドルウェアで保護するかはあなたの判断です。start/routes.tsに追加してください:
router.get('.well-known/oauth-authorization-server', [OauthController, 'getAuthorizationServer'])
router.get('.well-known/oauth-protected-resource/:resource', [OauthController, 'getProtectedResource'])
router
.group(() => {
router.post('token', [OauthController, 'token'])
router
.group(() => {
router.post('authorize/approve', [OauthController, 'approveAuthorization'])
router.post('authorize/deny', [OauthController, 'denyAuthorization'])
})
.use(middleware.auth())
})
.prefix('oauth')approveとdenyは必ず認証されている必要があります: 認可コードはアクセスを許可するユーザーに紐づいています。トークンエンドポイントは仕様上公開されており、認可コードが引き換えられる場所なので、スロットルを設定するのに適した場所です。
リダイレクトの返却
approveとdenyはデフォルトで200 { redirect_to }を返し、同意画面が自分でナビゲートします:
window.location.assign(response.redirect_to)これはfetchやaxiosで決定を送信する画面が必要とするものです。XHRはリクエストを再発行して302に従うため、ページはナビゲートされません: リクエストがクロスオリジンでクライアントのコールバックに到達してCORSに失敗する間、ユーザーは同意画面に留まります。
同意画面がプレーンなHTMLフォームの場合は、redirectMode: 'http'を設定してください。その場合ブラウザはドキュメントをナビゲートするため、302にネイティブに従い、ユーザーはクライアントに到達します。
トークンの発行
トークンの種類はアクセスされるリソースに依存するため、その決定はコントローラーではなく各リソースにあります。パッケージがリクエストを検証し、認可コードを消費し、PKCEベリファイアを検証すると、次のものを呼び出します:
issueToken: async ({ userId, scopes, client, resource, ctx }) => {
const user = await User.find(userId)
if (!user) return null // rejects the exchange with invalid_grant
const expiresIn = 30 * 24 * 60 * 60
const token = await User.accessTokens.create(user, scopes, {
name: `oauth:${client.id}`,
expiresIn,
})
return { accessToken: token.value!.release(), expiresIn }
}userIdは認可コードとともに保存されたものです: パッケージはユーザーモデルについての知識を持たず、それをロードすることもありません。
同意画面
GET /oauth/authorizeページはあなたのものです — Edge、Inertia、または別のフロントエンド。パッケージはその背後でリクエストを検証するだけです:
const validation = server.validateAuthorizationRequest(request.qs())
if (!validation.valid) {
return view.render('oauth/authorize', { error: validation.error })
}
return view.render('oauth/authorize', {
client: validation.client,
requestedScopes: validation.scopes,
authorizationFields: validation.fields, // post these back to approve
})任意: 画面を別の場所でレンダリングするアプリケーションはこれをスキップできます。approveとdenyがリクエストを独自に再度検証するためです。
設定
export default defineConfig({
issuer: env.get('APP_URL'),
authorizationEndpoint: `${env.get('APP_URL')}/oauth/authorize`,
tokenEndpoint: `${env.get('APP_URL')}/oauth/token`,
// optional
redirectMode: 'json', // or 'http'
tokenEndpointAuthMethods: ['none'],
authorizationCodeTtlSeconds: 10 * 60,
authorizationCodesTable: 'oauth_authorization_codes',
authenticatedUserId: (ctx) => ctx.auth.user?.id, // defaults to this
resources: [mcpResource],
})各リソースは次のものを宣言します:
フィールド | |
|
|
| クライアントが |
| 人間が読める名前。ディスカバリーを通じて公開されます。 |
| リソースが理解するすべてのスコープ。 |
|
|
| アクセストークンを発行します。 |
ループバックリダイレクトURI(http://localhost/callback)はRFC 8252に従い任意のポートで一致し、redirectUriPatternsはコールバックにidを含むクライアントのために単一の:paramセグメントを許可します。
This server cannot be deployed
Maintenance
Related MCP Connectors
One OAuth connector for your team's remote MCP servers, with Tool Packs, guardrails and logs.
Self-hosted federated MCP gateway: one OAuth 2.1 MCP server in front of N apps, user-level scopes.
MCP server for verifying EUDI/Talao wallet data via OIDC4VP (pull) for AI agents.
Hosted MCP server with managed OAuth for 15+ toolkits: Google Workspace, Fitbit, Oura, Kalshi, etc.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceA complete OAuth 2.1 server implementation for FastMCP with PKCE support, enabling secure authentication and authorization flows. Provides authorization code exchange, token management, and refresh capabilities for building authenticated MCP applications.-
- AlicenseNot gradedqualityFmaintenanceDrop-in OAuth 2.1 + Dynamic Client Registration for MCP servers, providing authentication middleware and token verification.12 npm1MIT
- AlicenseNot gradedqualityDmaintenanceImplements an MCP server with OAuth 2.1 Protected Resource Metadata, enabling token-based authentication for MCP tools like ping.MIT
- AlicenseBqualityDmaintenanceA production-grade Model Context Protocol (MCP) resource server with OAuth 2.1 authorization, provider-agnostic and supporting multiple MCP specification versions.18MIT