@aauth/mcp-server
Server-side AAuth for MCP. Verifies signed requests, validates agent and auth tokens, builds AAuth challenge headers, creates resource tokens, and manages 202 interaction flows.
Part of aauth-dev/packages-js. Protocol spec: dickhardt/AAuth.
Install
npm install @aauth/mcp-server
Usage
verifyToken(options): Promise<VerifiedToken>
Verifies a JWT from a signed request. Supports both aa-agent+jwt and aa-auth+jwt token types. Fetches issuer metadata and JWKS automatically (cached).
import { verifyToken } from '@aauth/mcp-server'
const result = await verifyToken({
jwt: tokenFromSignatureKeyHeader,
httpSignatureThumbprint: thumbprintFromVerifiedSignature,
})
if (result.type === 'agent') {
console.log(`Agent: ${result.sub}`)
}
if (result.type === 'auth') {
console.log(`Authorized agent: ${result.agent}, scope: ${result.scope}`)
}
Throws AAuthTokenError with a spec-defined error code on failure:
invalid_agent_token | Agent token verification failed |
invalid_auth_token | Auth token verification failed |
key_binding_failed | Request signing key doesn't match token cnf.jwk |
Builds an AAuth-Requirement response header.
import { buildAAuthHeader } from '@aauth/mcp-server'
const header = buildAAuthHeader('auth-token', { resourceToken: '...' })
response.setHeader('aauth-requirement', header)
buildAAuthHeader('interaction', { url: 'https://example.com/interact', code: 'ABCD1234' })
buildAAuthHeader('approval')
buildAAuthHeader('clarification')
buildAAuthHeader('claims')
Builds an AAuth-Access response header for two-party mode. The token is opaque to the agent — the resource wraps its own authorization state.
import { buildAAuthAccessHeader } from '@aauth/mcp-server'
response.setHeader('aauth-access', buildAAuthAccessHeader(wrappedToken))
Parses an AAuth-Capabilities request header.
import { parseCapabilitiesHeader } from '@aauth/mcp-server'
const caps = parseCapabilitiesHeader(request.headers.get('aauth-capabilities'))
Parses an AAuth-Mission request header into a Mission object that can be passed directly to createResourceToken.
import { parseMissionHeader } from '@aauth/mcp-server'
const mission = parseMissionHeader(request.headers.get('aauth-mission'))
createResourceToken(options, sign): Promise<string>
Creates an aa-resource+jwt token for inclusion in 401 AAuth challenges.
import { createResourceToken } from '@aauth/mcp-server'
const resourceToken = await createResourceToken(
{
resource: 'https://api.example.com',
authServer: 'https://ps.example',
agent: 'aauth:claude@user.github.io',
agentJkt: thumbprint,
scope: 'files.read',
mission: parseMissionHeader(request.headers.get('aauth-mission')),
lifetime: 300,
},
async (payload, header) => {
return signedJwtString
}
)
InteractionManager
Manages pending requests for 202 deferred response flows.
import { InteractionManager } from '@aauth/mcp-server'
const manager = new InteractionManager({
baseUrl: 'https://api.example.com',
pendingPath: '/pending',
codeLength: 8,
ttl: 600,
})
const { headers, pending } = manager.createPending()
manager.resolve(pending.id, { granted: true })
manager.reject(pending.id, 'denied')
manager.cleanup()
clearMetadataCache()
Clears the cached issuer metadata and JWKS used by verifyToken.
import { clearMetadataCache } from '@aauth/mcp-server'
clearMetadataCache()
License
MIT