Includes: API (Express/TypeScript), Astro site, Python workers, document generators, FCC compliance tools, Canada CRTC formation, Ansible infrastructure, and deployment scripts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
72 lines
1.8 KiB
TypeScript
72 lines
1.8 KiB
TypeScript
/**
|
|
* HTTP client for the Performance West API.
|
|
* All MCP tools delegate to the API — this keeps the MCP server
|
|
* stateless and avoids duplicating business logic.
|
|
*/
|
|
|
|
const DEFAULT_BASE_URL = "https://api.performancewest.net";
|
|
|
|
const baseUrl = process.env.PW_API_URL ?? DEFAULT_BASE_URL;
|
|
const apiKey = process.env.PW_API_KEY ?? "";
|
|
|
|
function buildUrl(
|
|
path: string,
|
|
params?: Record<string, string | number | undefined>,
|
|
): string {
|
|
const url = new URL(path, baseUrl);
|
|
if (params) {
|
|
for (const [k, v] of Object.entries(params)) {
|
|
if (v !== undefined && v !== "") {
|
|
url.searchParams.set(k, String(v));
|
|
}
|
|
}
|
|
}
|
|
return url.toString();
|
|
}
|
|
|
|
export interface ApiResponse<T = unknown> {
|
|
ok: boolean;
|
|
status: number;
|
|
data: T;
|
|
}
|
|
|
|
export async function apiGet<T = unknown>(
|
|
path: string,
|
|
params?: Record<string, string | number | undefined>,
|
|
): Promise<ApiResponse<T>> {
|
|
const url = buildUrl(path, params);
|
|
const headers: Record<string, string> = {
|
|
Accept: "application/json",
|
|
"User-Agent": "performancewest-mcp-server/0.1.0",
|
|
};
|
|
if (apiKey) {
|
|
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
}
|
|
|
|
const res = await fetch(url, { headers });
|
|
const data = (await res.json()) as T;
|
|
return { ok: res.ok, status: res.status, data };
|
|
}
|
|
|
|
export async function apiPost<T = unknown>(
|
|
path: string,
|
|
body: Record<string, unknown>,
|
|
): Promise<ApiResponse<T>> {
|
|
const url = buildUrl(path);
|
|
const headers: Record<string, string> = {
|
|
Accept: "application/json",
|
|
"Content-Type": "application/json",
|
|
"User-Agent": "performancewest-mcp-server/0.1.0",
|
|
};
|
|
if (apiKey) {
|
|
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
}
|
|
|
|
const res = await fetch(url, {
|
|
method: "POST",
|
|
headers,
|
|
body: JSON.stringify(body),
|
|
});
|
|
const data = (await res.json()) as T;
|
|
return { ok: res.ok, status: res.status, data };
|
|
}
|