Skip to main content
Glama
keychain.ts2.81 kB
/** * macOS Keychain integration for reading tokens stored by onboarded-cli. * * Uses the `security` CLI to read generic passwords from Keychain. * This matches the Python CLI's keyring storage format: * - Service: "onboarded-cli" * - Account: "{profile}:token" */ import { execSync } from "node:child_process"; const KEYCHAIN_SERVICE = "onboarded-cli"; export interface KeychainResult { found: boolean; token?: string; error?: string; profile?: string; } export interface GetTokenOptions { profile?: string; } // Alias for backward compatibility export type TokenResult = KeychainResult; /** * Get a token from macOS Keychain for the given profile. * * @param options - Options including profile name * @returns KeychainResult with found=true and token if successful */ export function getToken(options: GetTokenOptions | string = {}): KeychainResult { const profile = typeof options === 'string' ? options : (options.profile ?? 'default'); const account = `${profile}:token`; try { // Use -w flag to output only the password (no other metadata) const command = `security find-generic-password -s "${KEYCHAIN_SERVICE}" -a "${account}" -w 2>/dev/null`; const token = execSync(command, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], }).trim(); if (token) { return { found: true, token, profile }; } return { found: false, error: "Token is empty", profile }; } catch (error) { // security command returns non-zero if password not found return { found: false, error: `No token found for profile "${profile}". Run: onboarded auth login ${profile}`, profile, }; } } /** * Check if a token exists for the given profile without retrieving it. * * @param profile - The profile name * @returns true if token exists, false otherwise */ export function hasToken(profile: string): boolean { const account = `${profile}:token`; try { // Use -l flag to find by label, but we just check exit code const command = `security find-generic-password -s "${KEYCHAIN_SERVICE}" -a "${account}" 2>/dev/null`; execSync(command, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], }); return true; } catch { return false; } } /** * List all profiles that have tokens stored in Keychain. * * Note: This is a best-effort implementation. The macOS security CLI * doesn't have a great way to list all items by service, so we'd need * to know the profile names in advance or scan the config file. * * @param knownProfiles - Array of profile names to check * @returns Array of profile names that have tokens */ export function listProfilesWithTokens(knownProfiles: string[]): string[] { return knownProfiles.filter((profile) => hasToken(profile)); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/OnboardedInc/onboarded-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server