@dinko/adonis-mcp
adonis-oauth-mcp
两个 AdonisJS 包的 monorepo。它们一起版本化和发布,因此对资源注册契约的更改永远不需要跨仓库协调。
包 | 负责 |
| 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: OAuth MCP Server
开发
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
一个带 PKCE 的 OAuth 2.1 授权服务器,适用于需要向第三方客户端发放访问令牌的 AdonisJS 应用。
该包负责协议。应用拥有三件无法委托的事情:同意屏幕、发放哪个令牌以及路由。
npm i @dinko/adonis-oauth
node ace configure @dinko/adonis-oauth配置会生成三个文件,并且永远不会覆盖已有文件:
文件 | 如何处理 |
| 声明你的资源、它们的客户端和 |
| 将 |
| 从这里开始就是你的了:委托给该包,也是你添加它未覆盖的任何内容的地方。 |
路由
不会自动注册——它们放在哪里以及由哪个中间件保护,由你决定。将它们添加到 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],
})每个资源声明:
字段 | |
| 用于 |
| 客户端作为 |
| 人类可读的名称,通过发现机制公布。 |
| 资源理解的每个作用域。 |
|
|
| 铸造访问令牌。 |
根据 RFC 8252,环回重定向 URI(http://localhost/callback)匹配任何端口,并且 redirectUriPatterns 允许单个 :param 段,用于回调携带 id 的客户端。
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
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.
MCP server for secureFlows: token-free URL builders and integration-linting tools for AI agents.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA self-hostable OAuth 2.0 server designed for the Model-Context-Protocol (MCP) that enables you to secure your MCP applications with a robust implementation you control.3,607112ISC
- 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 gradedqualityDmaintenanceDrop-in OAuth 2.1 + Dynamic Client Registration for MCP servers, providing authentication middleware and token verification.20MIT
- AlicenseNot gradedqualityCmaintenanceImplements an MCP server with OAuth 2.1 Protected Resource Metadata, enabling token-based authentication for MCP tools like ping.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Dyoma3/adonis-oauth-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server