Spaces:
Sleeping
Sleeping
File size: 1,220 Bytes
7dc28be | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | import { Firestore } from '@google-cloud/firestore';
import type { TokenStorage } from 'fastmcp/auth';
const COLLECTION = 'mcp-oauth-tokens';
/**
* Firestore-backed TokenStorage for FastMCP's OAuth proxy.
* Tokens survive container restarts and redeployments.
* On Cloud Run, authentication is automatic via the service account.
*/
export class FirestoreTokenStorage implements TokenStorage {
private db: Firestore;
constructor(projectId?: string) {
this.db = new Firestore({ projectId });
}
async save(key: string, value: unknown, _ttl?: number): Promise<void> {
const doc = this.db.collection(COLLECTION).doc(encodeKey(key));
await doc.set({ value, createdAt: Date.now() });
}
async get(key: string): Promise<unknown | null> {
const doc = await this.db.collection(COLLECTION).doc(encodeKey(key)).get();
if (!doc.exists) return null;
return doc.data()!.value;
}
async delete(key: string): Promise<void> {
await this.db.collection(COLLECTION).doc(encodeKey(key)).delete();
}
async cleanup(): Promise<void> {
// FastMCP handles token expiry internally via delete() calls.
}
}
function encodeKey(key: string): string {
return key.replace(/\//g, '__');
}
|