Overview

The @atxp/redis package provides a Redis-based OAuth database implementation for the Authorization Token Exchange Protocol (ATXP). It offers distributed OAuth token storage using Redis, designed for scalable applications that need shared token storage across multiple server instances or require high-performance, in-memory token caching.
This package is designed to work seamlessly with @atxp/client and @atxp/express packages when you need distributed storage that can be shared across multiple application instances. For single-instance applications, consider using @atxp/sqlite instead.

Installation

npm install @atxp/redis
The @atxp/redis package includes TypeScript definitions and requires Node.js 16 or higher. It automatically installs @atxp/common as a dependency and requires a Redis server to be running.

API Reference

Classes

RedisOAuthDatabase

The main class for managing OAuth tokens in a Redis database.
import { RedisOAuthDatabase } from '@atxp/redis'
Constructor
new RedisOAuthDatabase(options: RedisOAuthDatabaseOptions)
options
RedisOAuthDatabaseOptions
required
Configuration options for the Redis database connection.
Methods
storeToken
Promise<void>
Stores an OAuth token in Redis with optional expiration.
key
string
required
Unique identifier for the token.
token
string
required
The OAuth token value to store.
expiresAt
Date
Optional expiration date for the token. If provided, Redis will automatically expire the key.
getToken
Promise<string | null>
Retrieves an OAuth token from Redis.
key
string
required
Unique identifier for the token to retrieve.
deleteToken
Promise<boolean>
Deletes an OAuth token from Redis.
key
string
required
Unique identifier for the token to delete.
hasToken
Promise<boolean>
Checks if a token exists in Redis.
key
string
required
Unique identifier for the token to check.
listTokens
Promise<string[]>
Lists all token keys stored in Redis with the configured prefix.
close
Promise<void>
Closes the Redis connection and releases resources.

Interfaces

RedisOAuthDatabaseOptions

Configuration options for the Redis OAuth database.
interface RedisOAuthDatabaseOptions {
  url?: string
  host?: string
  port?: number
  password?: string
  db?: number
  keyPrefix?: string
  connectionTimeout?: number
  retryDelayOnFailover?: number
  maxRetriesPerRequest?: number
}
url
string
Complete Redis connection URL. Takes precedence over individual host/port/password/db options.
host
string
Redis server hostname. Defaults to ‘localhost’.
port
number
Redis server port. Defaults to 6379.
password
string
Redis server password for authentication.
db
number
Redis database number (0-15). Defaults to 0.
keyPrefix
string
Prefix for all Redis keys to avoid conflicts. Defaults to ‘atxp:oauth:’.
connectionTimeout
number
Connection timeout in milliseconds. Defaults to 10000.
retryDelayOnFailover
number
Delay between retry attempts in milliseconds. Defaults to 100.
maxRetriesPerRequest
number
Maximum number of retry attempts per request. Defaults to 3.

Usage Examples

Basic Setup

Create a Redis OAuth database instance:
import { RedisOAuthDatabase } from '@atxp/redis'

// Initialize the database with connection URL
const oauthDb = new RedisOAuthDatabase({
  url: 'redis://localhost:6379'
})

// Store a token with expiration
await oauthDb.storeToken('user_123', 'oauth_token_value', new Date(Date.now() + 3600000))

// Retrieve a token
const token = await oauthDb.getToken('user_123')
console.log('Token:', token)

// Check if token exists
const hasToken = await oauthDb.hasToken('user_123')
console.log('Has token:', hasToken)

// List all tokens
const allTokens = await oauthDb.listTokens()
console.log('All tokens:', allTokens)

// Clean up
await oauthDb.close()

Advanced Configuration

Configure Redis with authentication and custom settings:
import { RedisOAuthDatabase } from '@atxp/redis'

const oauthDb = new RedisOAuthDatabase({
  host: 'redis.example.com',
  port: 6380,
  password: 'your_redis_password',
  db: 1,
  keyPrefix: 'myapp:oauth:',
  connectionTimeout: 15000,
  maxRetriesPerRequest: 5
})

Integration with ATXP Client

Use Redis storage with the ATXP client for distributed token management:
import { atxpClient, ATXPAccount } from '@atxp/client'
import { RedisOAuthDatabase } from '@atxp/redis'

// Create Redis OAuth database
const oauthDb = new RedisOAuthDatabase({
  url: process.env.REDIS_URL || 'redis://localhost:6379'
})

// Create ATXP client with Redis OAuth storage
const client = await atxpClient({
  mcpServer: 'https://browse.mcp.atxp.ai/',
  account: new ATXPAccount(process.env.ATXP_CONNECTION),
  oauthDatabase: oauthDb
})

// Use the client - tokens will be automatically stored in Redis
const result = await client.callTool('browse', {
  url: 'https://example.com'
})

Integration with ATXP Server

Use Redis storage with the ATXP server for distributed session management:
import { atxpExpress, ATXPPaymentDestination } from '@atxp/express'
import { RedisOAuthDatabase } from '@atxp/redis'
import express from 'express'

// Create Redis OAuth database
const oauthDb = new RedisOAuthDatabase({
  url: process.env.REDIS_URL || 'redis://localhost:6379',
  keyPrefix: 'server:oauth:'
})

const app = express()

// Use ATXP server with Redis OAuth storage
app.use('/mcp', atxpExpress({
  paymentDestination: new ATXPPaymentDestination(process.env.ATXP_CONNECTION),
  payeeName: 'My MCP Server',
  oauthDatabase: oauthDb
}))

app.listen(3000, () => {
  console.log('Server running on port 3000')
})

Configuration

Connection Options

Redis supports multiple connection methods:
// Using connection URL (recommended)
const oauthDb = new RedisOAuthDatabase({
  url: 'redis://username:password@host:port/database'
})

// Using individual options
const oauthDb = new RedisOAuthDatabase({
  host: 'localhost',
  port: 6379,
  password: 'password',
  db: 0
})

// Using Redis Cloud or other hosted services
const oauthDb = new RedisOAuthDatabase({
  url: 'rediss://username:password@host:port' // Note: rediss:// for SSL
})

Environment Variables

Configure Redis connection using environment variables:
# .env file
REDIS_URL=redis://localhost:6379
REDIS_PASSWORD=your_password
REDIS_DB=0
REDIS_KEY_PREFIX=atxp:oauth:
import { RedisOAuthDatabase } from '@atxp/redis'

const oauthDb = new RedisOAuthDatabase({
  url: process.env.REDIS_URL,
  password: process.env.REDIS_PASSWORD,
  db: parseInt(process.env.REDIS_DB || '0'),
  keyPrefix: process.env.REDIS_KEY_PREFIX || 'atxp:oauth:'
})

Key Management

Redis keys are automatically prefixed to avoid conflicts:
// With default prefix 'atxp:oauth:'
await oauthDb.storeToken('user_123', 'token_value')
// Stored as: atxp:oauth:user_123

// With custom prefix
const oauthDb = new RedisOAuthDatabase({
  url: 'redis://localhost:6379',
  keyPrefix: 'myapp:auth:'
})
await oauthDb.storeToken('user_123', 'token_value')
// Stored as: myapp:auth:user_123

Troubleshooting

Common Issues

If you encounter connection refused errors:
  • Ensure Redis server is running
  • Check if the host and port are correct
  • Verify firewall settings allow Redis connections
  • Test connection with redis-cli
# Test Redis connection
redis-cli -h localhost -p 6379 ping
// Increase connection timeout
const oauthDb = new RedisOAuthDatabase({
  url: 'redis://localhost:6379',
  connectionTimeout: 30000
})
If you’re experiencing authentication failures:
  • Verify the password is correct
  • Check if Redis requires authentication
  • Ensure the username format is correct for Redis 6+
// Use proper authentication format
const oauthDb = new RedisOAuthDatabase({
  url: 'redis://username:password@localhost:6379'
})
For applications with many tokens:
  • Monitor Redis memory usage
  • Configure appropriate eviction policies
  • Consider token cleanup for expired entries
  • Use Redis clustering for horizontal scaling
// Implement token cleanup
const allTokens = await oauthDb.listTokens()
for (const key of allTokens) {
  const token = await oauthDb.getToken(key)
  // Check if token is expired and delete if necessary
}
If you’re experiencing network timeouts:
  • Increase connection timeout values
  • Check network stability between application and Redis
  • Consider using connection pooling
  • Monitor Redis server performance
const oauthDb = new RedisOAuthDatabase({
  url: 'redis://localhost:6379',
  connectionTimeout: 30000,
  retryDelayOnFailover: 200,
  maxRetriesPerRequest: 5
})

Performance Considerations

For optimal Redis performance:
  • Use Redis clustering for high availability and horizontal scaling
  • Configure appropriate memory eviction policies
  • Monitor Redis memory usage and implement cleanup strategies
  • Use connection pooling for high-concurrency applications
  • Consider Redis persistence settings based on your requirements

Migration from Other Storage

If you’re migrating from another OAuth storage solution:
  1. Export tokens from your current system
  2. Set up Redis server
  3. Import tokens using the storeToken method
  4. Update your application to use the Redis database
// Example migration script
import { RedisOAuthDatabase } from '@atxp/redis'

const oauthDb = new RedisOAuthDatabase({
  url: 'redis://localhost:6379'
})

// Import tokens from your existing system
const existingTokens = await getTokensFromOldSystem()
for (const token of existingTokens) {
  await oauthDb.storeToken(token.key, token.value, token.expiresAt)
}