UNPKG

@hackle-io/hackle-mcp

Version:

Model Context Protocol server for Hackle

108 lines (107 loc) 3.31 kB
const BASE_URL = "https://admin-api.hackle.io"; const ENVIRONMENT_KEY = process.env.ENVIRONMENT_KEY || "PRODUCTION"; const API_KEY = process.env.API_KEY || ""; // Deprecation notice — this local npm package is deprecated in favor of the remote MCP server. console.error( [ '', '⚠️ [DEPRECATED] The local @hackle-io/hackle-mcp npm package is deprecated.', ' The Hackle MCP server is now available as a remote server (no npm/Node.js setup,', ' auto-updates, and where all new tools ship). This package will no longer receive', ' updates or new tools.', '', ' ➡️ Remote server URL: https://mcp.hackle.io/mcp', ' ➡️ Migration guide: https://docs.hackle.io/external-link/model-context-protocol/migration', '', ].join('\n'), ); if (!API_KEY) { console.warn("API_KEY environment variable is not set"); } const DEFAULT_HEADERS = { accept: "application/json", "Content-Type": "application/json", "X-HACKLE-ADMIN-API-KEY": API_KEY, "X-HACKLE-TIME-ZONE": Intl.DateTimeFormat().resolvedOptions().timeZone, "X-Hackle-Client": "hackle-local-mcp" }; class WebClient { static async request(method, path, options = {}) { const url = new URL(`${BASE_URL}${path}`); url.searchParams.set("environmentKey", ENVIRONMENT_KEY); if (typeof fetch === "undefined") { return WebClient.fetchFallback(method, url, options); } const response = await fetch(url, { method, ...options, headers: { ...DEFAULT_HEADERS, ...options.headers } }); if (!response.ok) { const errorText = await response.text(); throw new Error(`Hackle API error! status: ${response.status} - ${errorText}`); } return await response.json(); } static async fetchFallback(method, url, options) { const { default: nodeFetch } = await import("node-fetch"); const { body, ...otherOptions } = options; if (body !== null && body !== void 0 && typeof body !== "string") { throw new Error(`[ERROR] Invalid body type: ${body}`); } const response = await nodeFetch(url, { method, headers: { ...DEFAULT_HEADERS, ...options.headers }, body, ...otherOptions }); if (!response.ok) { const errorText = await response.text(); throw new Error(`Hackle API error! status: ${response.status} - ${errorText}`); } return await response.json(); } static async get(path, options) { return this.request("GET", path, options); } static async post(path, body, options) { return this.request("POST", path, { ...options, body: JSON.stringify(body), headers: { ...options?.headers } }); } static async put(path, body, options) { return this.request("PUT", path, { ...options, body: JSON.stringify(body), headers: { ...options?.headers } }); } static async delete(path, options) { return this.request("DELETE", path, options); } static async patch(path, body, options) { return this.request("PATCH", path, { ...options, body: JSON.stringify(body), headers: { ...options?.headers } }); } } var WebClient_default = WebClient; export { WebClient_default as default };