@dinko/adonis-mcp
adonis-oauth-mcp
Monorepo für zwei AdonisJS-Pakete. Sie werden gemeinsam versioniert und veröffentlicht, sodass Änderungen am Ressourcen-Registrierungsvertrag nie eine repo-übergreifende Koordination erfordern.
Paket | Zuständig für |
| OAuth-2.1-Autorisierungsserver: token / approve / deny, Redirect-URI-Validierung, Autorisierungscode-Speicherung, Autorisierungsserver-Metadaten und ein generischer Metadaten-Endpunkt für geschützte Ressourcen, der von einer Ressourcen-Registry gesteuert wird. Weiß nichts über MCP. |
| MCP-Server: Request-Handler, Controller, Tool-Vertrag, Auth-Middleware. Registriert sich selbst als geschützte OAuth-Ressource und deklariert seine Ressourcen-URL, Scopes, Clients, |
Die Abhängigkeit verläuft nur in eine Richtung: mcp → oauth. Nichts in oauth darf aus mcp importieren.
Layout
Jedes Paket folgt der AdonisJS-Paketkonvention:
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
Entwicklung
npm install # links the workspaces
npm run build # tsc + copy stubs, per package
npm run typecheck
npm test # runs against build/, so build firstInstallieren Sie während der Entwicklung in eine App aus diesem Checkout (npm link, file: oder eine Git-Abhängigkeit) statt aus der Registry.
@dinko/adonis-oauth
Ein OAuth-2.1-Autorisierungsserver mit PKCE für AdonisJS-Anwendungen, die Drittanbieter-Clients Zugriffstokens aushändigen müssen.
Das Paket besitzt das Protokoll. Die Anwendung besitzt drei Dinge, die sie nicht delegieren kann: den Zustimmungsbildschirm, welches Token ausgestellt wird und die Routen.
npm i @dinko/adonis-oauth
node ace configure @dinko/adonis-oauthDie Konfiguration erzeugt drei Dateien und überschreibt niemals eine vorhandene:
Datei | Was damit zu tun ist |
| Deklarieren Sie Ihre Ressourcen, deren Clients und |
| Passen Sie die |
| Ab hier gehört es Ihnen: Es delegiert an das Paket und ist der Ort, an dem Sie alles hinzufügen, was es nicht abdeckt. |
Routen
Nicht automatisch registriert — wo sie leben und welche Middleware sie schützt, ist Ihre Entscheidung. Fügen Sie sie zu start/routes.ts hinzu:
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 und deny müssen authentifiziert sein: Der Autorisierungscode ist an den Benutzer gebunden, der den Zugriff gewährt. Der Token-Endpunkt ist laut Spezifikation öffentlich und ist der Ort, an dem Autorisierungscodes eingelöst werden, daher ist er ein guter Ort für eine Drosselung.
Die Weiterleitung zurückgeben
Approve und deny antworten standardmäßig mit 200 { redirect_to }, und der Zustimmungsbildschirm navigiert selbst:
window.location.assign(response.redirect_to)Das ist es, was ein Bildschirm braucht, der seine Entscheidung mit fetch oder axios übermittelt. Ein XHR folgt einer 302, indem es die Anfrage erneut ausführt, sodass die Seite nie navigiert: Der Benutzer bleibt auf dem Zustimmungsbildschirm, während die Anfrage Cross-Origin auf dem Callback des Clients landet und an CORS scheitert.
Setzen Sie redirectMode: 'http', wenn der Zustimmungsbildschirm ein einfaches HTML-Formular ist. Dort navigiert der Browser das Dokument, folgt also der 302 nativ, und der Benutzer landet beim Client.
Tokens ausstellen
Der Tokentyp hängt von der aufgerufenen Ressource ab, daher liegt diese Entscheidung bei jeder Ressource und nicht im Controller. Sobald das Paket die Anfrage validiert, den Autorisierungscode verbraucht und den PKCE-Verifier verifiziert hat, ruft es auf:
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 ist das, was mit dem Autorisierungscode gespeichert wurde: Das Paket hat keine Kenntnis von Ihrem Benutzermodell und lädt es nie.
Der Zustimmungsbildschirm
Die GET /oauth/authorize-Seite gehört Ihnen — Edge, Inertia oder ein separates Frontend. Das Paket validiert nur die Anfrage dahinter:
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
})Optional: Anwendungen, die den Bildschirm woanders rendern, können es überspringen, da approve und deny die Anfrage selbst erneut validieren.
Konfiguration
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],
})Jede Ressource deklariert:
Feld | |
| Slug, der in |
| Kanonischer Ressourcenindikator, den Clients als |
| Menschenlesbarer Name, der über Discovery beworben wird. |
| Jeder Scope, den die Ressource versteht. |
|
|
| Erzeugt das Zugriffstoken. |
Loopback-Redirect-URIs (http://localhost/callback) matchen auf jedem Port, gemäß RFC 8252, und redirectUriPatterns erlaubt ein einzelnes :param-Segment für Clients, deren Callback eine ID trägt.
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