Skip to main content
Glama
Dyoma3

@dinko/adonis-mcp

by Dyoma3

adonis-oauth-mcp

두 개의 AdonisJS 패키지를 위한 모노레포입니다. 두 패키지는 함께 버전을 올리고 릴리스되므로, 리소스 등록 계약의 변경에 크로스-레포 조정이 필요하지 않습니다.

패키지

담당

packages/oauth (@dinko/adonis-oauth)

OAuth 2.1 인가 서버: token / approve / deny, redirect-URI 검증, 인가 코드 저장, 인가 서버 메타데이터, 그리고 리소스 레지스트리에 기반한 범용 보호 리소스 메타데이터 엔드포인트. MCP에 대해 아무것도 알지 못합니다.

packages/mcp (@dinko/adonis-mcp)

MCP 서버: 요청 핸들러, 컨트롤러, 도구 계약, 인증 미들웨어. 자신을 OAuth 보호 리소스로 등록하며, 리소스 URL, 스코프, 클라이언트, resource_name 및 토큰 제공자를 선언합니다. 아직 시작되지 않았습니다.

의존성은 한 방향으로만 흐릅니다: mcp → oauth. oauth의 어떤 것도 mcp에서 import할 수 없습니다.

구조

각 패키지는 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 injection

Related 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

AdonisJS 애플리케이션이 제3자 클라이언트에게 액세스 토큰을 전달해야 할 때 사용하는, PKCE를 지원하는 OAuth 2.1 인가 서버입니다.

이 패키지는 프로토콜을 소유합니다. 애플리케이션은 위임할 수 없는 세 가지를 소유합니다: 동의 화면, 발급할 토큰, 그리고 라우트.

npm i @dinko/adonis-oauth
node ace configure @dinko/adonis-oauth

설정 시 세 개의 파일이 생성되며 기존 파일을 덮어쓰지 않습니다:

파일

처리 방법

config/oauth.ts

리소스, 해당 클라이언트 및 issueToken을 선언합니다.

database/migrations/..._create_oauth_authorization_codes_table.ts

user_id 컬럼을 사용자 테이블에 맞게 조정한 후 마이그레이션합니다.

app/controllers/oauth_controller.ts

이제 여러분의 몫입니다: 패키지에 위임하며, 패키지가 다루지 않는 모든 것을 추가하는 곳입니다.

라우트

자동으로 등록되지 않습니다 — 라우트가 어디에 있고 어떤 미들웨어가 보호하는지는 여러분의 결정입니다. 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로 결정을 POST하는 화면에 필요한 것입니다. 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],
})

각 리소스는 다음을 선언합니다:

필드

id

/.well-known/oauth-protected-resource/<id>에서 사용되는 슬러그.

resource

클라이언트가 resource 매개변수로 보내는 표준 리소스 표시자.

resourceName

사람이 읽을 수 있는 이름, 디스커버리를 통해 광고됩니다.

scopes

리소스가 이해하는 모든 스코프.

clients

id, redirectUris, redirectUriPatterns, allowedScopes.

issueToken

액세스 토큰을 발행합니다.

루프백 리다이렉트 URI(http://localhost/callback)는 RFC 8252에 따라 모든 포트에서 일치하며, redirectUriPatterns는 콜백에 id가 포함된 클라이언트를 위해 단일 :param 세그먼트를 허용합니다.

Maintenance

ActivityMaintained
ResponsivenessNo issues

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

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    A 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,607
    112
    ISC
  • F
    license
    Not graded
    quality
    D
    maintenance
    A 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.
  • A
    license
    Not graded
    quality
    D
    maintenance
    Drop-in OAuth 2.1 + Dynamic Client Registration for MCP servers, providing authentication middleware and token verification.
    20
    MIT

Latest Blog Posts

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