Authdog

MCP SDK: Node.js

Last updated Oct 13, 2026
View as Markdown

AuthdogVerifier from @authdog/mcp-sdk verifies the bearer token an MCP client presents to your Node.js MCP server. It calls GET {baseUrl}/v1/userinfo with the token and returns an AuthInfo (subject, username, email, expiry, full user). Source is `node/` in authdog/mcp-sdk. The package is ESM, uses axios, and declares node >=16.

This is the MCP token verifier, not the runtime package of the same name used inside the Authdog platform. See MCP SDK for how the language SDKs relate.

Availability

These packages are source-available in github.com/authdog/mcp-sdk and may not resolve from registries yet. At the time of writing @authdog/mcp-sdk returns 404 on npm, and the repository has no release tags. The package version in package.json is 0.1.0. Install from source until a release is published.

The name @authdog/mcp-sdk also belongs to a separate private runtime package inside the Authdog platform monorepo (trust store, AuthZEN, telemetry). That package is not this verifier. See MCP SDK.

Install

From source:

git clone https://github.com/authdog/mcp-sdk.git
cd mcp-sdk/node
npm install
npm run build

npm run build runs tsc and writes dist/, which is what main and types point at. Then add the built directory to your server project:

npm install /path/to/mcp-sdk/node

Once a release is published, the README gives these commands:

deno add npm:@authdog/mcp-sdk
npm install @authdog/mcp-sdk

Configure

import { AuthdogVerifier } from "@authdog/mcp-sdk"

const verifier = new AuthdogVerifier({
  baseUrl: "https://api.authdog.com",
  timeout: 10000,
})
Option Type Default Behavior
baseUrl string required Authdog API base URL. Trailing slashes are stripped. A missing or blank value throws TypeError.
timeout number 10000 Request timeout in milliseconds. A falsy value (including 0) falls back to 10000.

Each request sends Content-Type: application/json and User-Agent: authdog-mcp-node-sdk/0.1.0.

Verify a token

import { AuthdogVerifier, AuthenticationError, APIError } from "@authdog/mcp-sdk"

const authInfo = await verifier.verifyToken("the-access-token")
console.log(authInfo.subject, authInfo.username, authInfo.email)

verifyToken(accessToken: string, signal?: AbortSignal): Promise<AuthInfo> sends Authorization: Bearer <accessToken>. Pass an AbortSignal to cancel the in-flight request, for example when the incoming MCP request is cancelled. An empty or whitespace-only token throws AuthenticationError before any request is made.

AuthInfo:

Field Type Value
token string The token you passed in
subject string user.id
username string user.userName
email string | null First user.emails[].value, or null
scopes string[] Always []
expiresAt Date | null Now plus session.remainingSeconds, only when that value is a number greater than 0. Otherwise null.
user UserInfoResponse["user"] Full user object from the response

scopes is empty because the userinfo endpoint does not return scopes; the SDK hard-codes []. Do not use it for scope-based authorization. Authentication identifies the caller; apply authorization separately.

Types AuthInfo, AuthdogVerifierConfig, and UserInfoResponse are exported alongside AuthdogVerifier.

Wire into an MCP server

The MCP TypeScript SDK protects HTTP transports with requireBearerAuth, which delegates to a token verifier. Adapt AuthdogVerifier in a few lines:

import express from "express"
import { requireBearerAuth } from "@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js"
import type { OAuthTokenVerifier } from "@modelcontextprotocol/sdk/server/auth/provider.js"
import type { AuthInfo as McpAuthInfo } from "@modelcontextprotocol/sdk/server/auth/types.js"
import { AuthdogVerifier } from "@authdog/mcp-sdk"

const authdog = new AuthdogVerifier({ baseUrl: "https://api.authdog.com" })

// Adapt the Authdog verifier to MCP's TokenVerifier interface
const verifier: OAuthTokenVerifier = {
  async verifyAccessToken(token: string): Promise<McpAuthInfo> {
    const info = await authdog.verifyToken(token)
    return {
      token: info.token,
      clientId: info.subject,
      scopes: info.scopes,
      expiresAt: info.expiresAt
        ? Math.floor(info.expiresAt.getTime() / 1000) // MCP expects epoch seconds
        : undefined,
      extra: { username: info.username, email: info.email },
    }
  },
}

const app = express()

// Protect your MCP HTTP endpoint with Authdog-backed bearer auth
app.use("/mcp", requireBearerAuth({ verifier }))

When the token is missing, invalid, or expired, verifyToken throws AuthenticationError, which requireBearerAuth surfaces to the client as HTTP 401.

Errors

All three classes are exported and extend Error. name is set to the class name.

Class Thrown when
AuthdogError Base class for the others
AuthenticationError Empty or blank token, or HTTP 401 (Unauthorized - invalid or expired token)
APIError Timeout (Request timed out: ...), other non-2xx (HTTP error <status>: <body>), network failure (Request failed: ...), or a 2xx response with no user (Invalid response: missing user in userinfo payload)
try {
  await verifier.verifyToken(token)
} catch (error) {
  if (error instanceof AuthenticationError) {
    // reject with 401
  } else if (error instanceof APIError) {
    // upstream or transport failure
  } else {
    throw error
  }
}