@withpica/mcp-server
Version:
MCP Server for withPICA — enables AI assistants to interact with your withPICA music catalog
73 lines • 3.15 kB
JavaScript
// Copyright (c) 2025-2026 Withpica Ltd. All rights reserved.
/**
* MCP Server Configuration
*/
import { readCredentials, getDefaultCredentialsPath, } from "@withpica/mcp-utils";
import { createRequire } from "module";
// Single TS-side source of truth for the customer MCP server version,
// AUTO-DERIVED from package.json so the two cannot drift. Past drift
// incidents that motivated this: 2026-04-08 (banner 2.5.0 vs npm 2.6.1),
// 2026-04-19 ADR-181 Phase 2 (banner 2.6.2 vs npm 2.22.0), 2026-04-24
// (publish blocked TWICE by stale literal at 2.27.0 → 2.28.0 bumps).
//
// Implementation note: uses `createRequire` rather than the import-
// attribute syntax (`import pkg from "..." with { type: "json" }`)
// because the package's tsconfig.json sets `module: "Node16"`, which
// doesn't support import attributes. createRequire works in any
// module setting and resolves ../package.json relative to the
// compiled dist/config.js file at runtime — same path semantics, no
// tsconfig change needed.
//
// scripts/lint-mcp-tools.ts version-sync check now accepts both this
// derived form (preferred) and the legacy literal hardcode (still
// version-matched against package.json). Surfaces on stdio via the
// boot banner + MCP `initialize` handshake (loadConfig below) and on
// HTTP via app/api/mcp/route.ts, which imports this const from
// mcp-server/dist/config.js. ADR-180 Phase 2 collapsed the
// duplication; ADR-196 Phase 4b makes it drift-proof.
const pkg = createRequire(import.meta.url)("../package.json");
export const VERSION = pkg.version;
export function loadConfig() {
const credentialsPath = process.env.PICA_CREDENTIALS_PATH || getDefaultCredentialsPath();
const debug = process.env.DEBUG === "true" || process.env.DEBUG === "1";
// Priority 1: env var
let picaApiKey = process.env.PICA_API_KEY || null;
// Priority 2: credentials file
if (!picaApiKey) {
const creds = readCredentials(credentialsPath);
if (creds) {
picaApiKey = creds.api_key;
if (debug) {
console.error(`[MCP Server] Loaded credentials for ${creds.email}`);
}
}
}
const lobbyMode = !picaApiKey;
const discoveryMode = process.env.MCP_LAYERED_DISCOVERY === "1";
if (lobbyMode && debug) {
console.error("[MCP Server] No API key found — starting in lobby mode");
}
if (discoveryMode && debug) {
console.error("[MCP Server] Layered discovery mode enabled");
}
return {
picaApiKey,
picaApiUrl: process.env.PICA_API_URL || "https://withpica.com/api",
serverName: "pica-mcp-server",
version: VERSION,
debug,
lobbyMode,
credentialsPath,
discoveryMode,
};
}
export function validateConfig(config) {
if (!config.lobbyMode &&
(!config.picaApiKey || config.picaApiKey.trim() === "")) {
throw new Error("PICA API key cannot be empty when not in lobby mode");
}
if (!config.picaApiUrl || !config.picaApiUrl.startsWith("http")) {
throw new Error("Invalid PICA API URL");
}
}
//# sourceMappingURL=config.js.map