Skip to main content
Glama
fireflyClient.ts13.5 kB
interface LoginArgs { accessKey?: string; secretKey?: string; } export interface InventoryArgs { assetTypes?: string[]; assetState?: "managed" | "unmanaged" | "ghost" | "modified"; providerIds?: string[]; responseSize?: number; assetNames?: string[]; arns?: string[]; modifiedSince?: string; freeTextSearch?: string; includeConfigration?: boolean; } export interface CodifyArgs { assetType: string; assetId: string; iacType: string; provider: string; accountNumber: string; } export interface GetInsightsArgs { fields?: string; query?: string; labels?: string[]; frameworks?: string[]; category?: string; isDefault?: boolean; onlySubscribed?: boolean; onlyProduction?: boolean; onlyMatchingAssets?: boolean; onlyEnabled?: boolean; onlyAvailableProviders?: boolean; showExclusion?: boolean; type?: string[]; providers?: string[]; integrations?: string[]; severity?: number[]; id?: string[]; page?: number; page_size?: number; sorting?: string[]; providersAccounts?: string[]; } export interface CreateInsightArgs { name: string; description?: string; code: string; type: string[]; providerIds: string[]; labels?: string[]; severity?: number; category?: string; frameworks?: string[]; } export interface UpdateInsightArgs { id: string; name: string; description?: string; code: string; type: string[]; providerIds: string[]; labels?: string[]; severity?: number; category?: string; frameworks?: string[]; } export interface DeleteInsightArgs { id: string; } export class FireflyClient { private baseUrl: string = "https://api.firefly.ai/api/v1.0"; private accessToken: string | null = null; private logger: any; constructor(logger: any, private isHosted: boolean, private accessKey?: string, private secretKey?: string) { this.logger = logger; // Use environment variables if not provided as constructor arguments this.accessKey = accessKey || process.env.FIREFLY_ACCESS_KEY; this.secretKey = secretKey || process.env.FIREFLY_SECRET_KEY; if (!this.accessKey || !this.secretKey) { throw new Error("Access key and secret key are required for authentication"); } this.accessToken = null; } private getAuthHeaders() { if (!this.accessToken) { throw new Error("Not authenticated or token expired. Call login() first."); } return { Authorization: `Bearer ${this.accessToken}`, "Content-Type": "application/json", "firefly-mcp-server": "true", "firefly-mcp-server-version": "1.0.0", "firefly-mcp-server-hosted": this.isHosted ? "true" : "false", }; } async login(accessKey?: string, secretKey?: string): Promise<any> { const key = accessKey || this.accessKey; const secret = secretKey || this.secretKey; if (!key || !secret) { throw new Error("Access key and secret key are required for authentication"); } try { const response = await fetch(`${this.baseUrl}/login`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ accessKey: key, secretKey: secret, }), }); if (!response.ok) { const errorText = await response.text(); throw new Error(`Authentication failed: ${response.status} ${errorText}`); } const data = await response.json(); this.accessToken = data.accessToken; this.logger.info("Logged in to Firefly successfully"); return { success: true, message: "Successfully authenticated", }; } catch (error) { this.logger.error("Login error:", error); throw error; } } async inventory(args: InventoryArgs): Promise<any> { try { const response = await fetch(`${this.baseUrl}/inventory`, { method: "POST", headers: this.getAuthHeaders(), body: JSON.stringify({ includeConfigration: args.includeConfigration || false, size: args.responseSize || 50, // Only include parameters in the request if they are provided ...(args.assetTypes ? { assetTypes: args.assetTypes } : {}), ...(args.assetState ? { state: args.assetState } : {}), ...(args.providerIds ? { providerIds: args.providerIds } : {}), ...(args.assetNames ? { names: args.assetNames } : {}), ...(args.arns ? { arns: args.arns } : {}), ...(args.modifiedSince ? { modifiedSince: args.modifiedSince } : {}), ...(args.freeTextSearch ? { freeTextSearch: args.freeTextSearch } : {}), }), }); if (!response.ok) { if (response.status === 401) { this.logger.info("Unauthorized. Attempting to re-login..."); await this.login(); return this.inventory(args); } const errorText = await response.text(); throw new Error(`Inventory query failed: ${response.status} ${errorText}`); } this.logger.info("Inventory query successful"); return await response.json(); } catch (error) { this.logger.error("Inventory error:", error); throw error; } } async codify(args: CodifyArgs): Promise<any> { try { const response = await fetch(`${this.baseUrl}/codify`, { method: "POST", headers: this.getAuthHeaders(), body: JSON.stringify({ assetType: args.assetType, assetId: args.assetId, iacType: args.iacType, provider: args.provider, accountNumber: args.accountNumber, }), }); if (!response.ok) { if (response.status === 401) { await this.login(); return this.codify(args); } const errorText = await response.text(); throw new Error(`Codification failed: ${response.status} ${errorText}`); } this.logger.info("Codification successful"); return await response.json(); } catch (error) { this.logger.error("Codify error:", error); throw error; } } async getInsights(args: GetInsightsArgs): Promise<any> { try { const response = await fetch(`https://api.firefly.ai/v2/governance/insights`, { method: "POST", headers: this.getAuthHeaders(), body: JSON.stringify({ ...(args.fields ? { fields: args.fields } : {}), ...(args.query ? { query: args.query } : {}), ...(args.labels ? { labels: args.labels } : {}), ...(args.frameworks ? { frameworks: args.frameworks } : {}), ...(args.category ? { category: args.category } : {}), ...(args.isDefault !== undefined ? { isDefault: args.isDefault } : {}), ...(args.onlySubscribed !== undefined ? { onlySubscribed: args.onlySubscribed } : {}), ...(args.onlyProduction !== undefined ? { onlyProduction: args.onlyProduction } : {}), ...(args.onlyMatchingAssets !== undefined ? { onlyMatchingAssets: args.onlyMatchingAssets } : {}), ...(args.onlyEnabled !== undefined ? { onlyEnabled: args.onlyEnabled } : {}), ...(args.onlyAvailableProviders !== undefined ? { onlyAvailableProviders: args.onlyAvailableProviders } : {}), ...(args.showExclusion !== undefined ? { showExclusion: args.showExclusion } : {}), ...(args.type ? { type: args.type } : {}), ...(args.providers ? { providers: args.providers } : {}), ...(args.integrations ? { integrations: args.integrations } : {}), ...(args.severity ? { severity: args.severity } : {}), ...(args.id ? { id: args.id } : {}), ...(args.page ? { page: args.page } : {}), ...(args.page_size ? { page_size: args.page_size } : {}), ...(args.sorting ? { sorting: args.sorting } : {}), ...(args.providersAccounts ? { providersAccounts: args.providersAccounts } : {}), }), }); if (!response.ok) { if (response.status === 401) { await this.login(); return this.getInsights(args); } const errorText = await response.text(); throw new Error(`Get policy failed: ${response.status} ${errorText}`); } this.logger.info("Get policy successful"); return await response.json(); } catch (error) { this.logger.error("Get policy error:", error); throw error; } } async createInsight(args: CreateInsightArgs): Promise<any> { try { const response = await fetch(`https://api.firefly.ai/v2/governance/insights/create`, { method: "POST", headers: this.getAuthHeaders(), body: JSON.stringify({ name: args.name, ...(args.description ? { description: args.description } : {}), code: args.code, type: args.type, providerIds: args.providerIds, ...(args.labels ? { labels: args.labels } : {}), ...(args.severity ? { severity: args.severity } : {}), ...(args.category ? { category: args.category } : {}), ...(args.frameworks ? { frameworks: args.frameworks } : {}), }), }); if (!response.ok) { if (response.status === 401) { await this.login(); return this.createInsight(args); } const errorText = await response.text(); throw new Error(`Create policy failed: ${response.status} ${errorText}`); } this.logger.info("Create policy successful"); return await response.json(); } catch (error) { this.logger.error("Create policy error:", error); throw error; } } async updateInsight(args: UpdateInsightArgs): Promise<any> { try { const response = await fetch(`https://api.firefly.ai/v2/governance/insights/${args.id}`, { method: "PUT", headers: this.getAuthHeaders(), body: JSON.stringify({ name: args.name, ...(args.description ? { description: args.description } : {}), code: args.code, type: args.type, providerIds: args.providerIds, ...(args.labels ? { labels: args.labels } : {}), ...(args.severity ? { severity: args.severity } : {}), ...(args.category ? { category: args.category } : {}), ...(args.frameworks ? { frameworks: args.frameworks } : {}), }), }); if (!response.ok) { if (response.status === 401) { await this.login(); return this.updateInsight(args); } const errorText = await response.text(); throw new Error(`Update policy failed: ${response.status} ${errorText}`); } this.logger.info("Update policy successful"); return await response.json(); } catch (error) { this.logger.error("Update policy error:", error); throw error; } } async deleteInsight(args: DeleteInsightArgs): Promise<any> { try { const response = await fetch(`https://api.firefly.ai/v2/governance/insights/${args.id}`, { method: "DELETE", headers: this.getAuthHeaders(), }); if (!response.ok) { if (response.status === 401) { await this.login(); return this.deleteInsight(args); } const errorText = await response.text(); throw new Error(`Delete policy failed: ${response.status} ${errorText}`); } this.logger.info("Delete policy successful"); return { success: true, message: "policy deleted successfully" }; } catch (error) { this.logger.error("Delete policy error:", error); throw error; } } }

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/gofireflyio/firefly-mcp'

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