包含 extensions、skills、prompts、settings、auth、models、mcp 等配置。 排除 node_modules、npm 缓存、sessions 等运行时数据。
58 lines
1.7 KiB
TypeScript
58 lines
1.7 KiB
TypeScript
// oauth-handler.ts - OAuth token management for MCP servers
|
|
import { existsSync, readFileSync } from "node:fs";
|
|
import type { OAuthTokens } from "@modelcontextprotocol/sdk/shared/auth.js";
|
|
import { getAuthEntryFilePath } from "./mcp-auth.ts";
|
|
|
|
// Token storage path for a server
|
|
function getTokensPath(serverName: string): string {
|
|
return getAuthEntryFilePath(serverName);
|
|
}
|
|
|
|
/**
|
|
* Get stored OAuth tokens for a server (if any).
|
|
* Returns undefined if no tokens or tokens are expired.
|
|
*
|
|
* Token file location: $MCP_OAUTH_DIR/sha256-<server-hash>/tokens.json when set,
|
|
* otherwise <Pi agent dir>/mcp-oauth/sha256-<server-hash>/tokens.json
|
|
*
|
|
* Expected format:
|
|
* {
|
|
* "access_token": "...",
|
|
* "token_type": "bearer",
|
|
* "refresh_token": "...", // optional
|
|
* "expires_in": 3600, // optional, seconds
|
|
* "expiresAt": 1234567890 // optional, absolute timestamp ms
|
|
* }
|
|
*/
|
|
export function getStoredTokens(serverName: string): OAuthTokens | undefined {
|
|
const tokensPath = getTokensPath(serverName);
|
|
|
|
if (!existsSync(tokensPath)) return undefined;
|
|
|
|
try {
|
|
const stored = JSON.parse(readFileSync(tokensPath, "utf-8"));
|
|
|
|
// Validate required field
|
|
if (!stored.access_token || typeof stored.access_token !== "string") {
|
|
return undefined;
|
|
}
|
|
|
|
// Check expiration if expiresAt is set
|
|
if (stored.expiresAt && typeof stored.expiresAt === "number") {
|
|
if (Date.now() > stored.expiresAt) {
|
|
// Token expired
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
return {
|
|
access_token: stored.access_token,
|
|
token_type: stored.token_type ?? "bearer",
|
|
refresh_token: stored.refresh_token,
|
|
expires_in: stored.expires_in,
|
|
};
|
|
} catch {
|
|
return undefined;
|
|
}
|
|
}
|