feat(klz-payload-mcp): implement JWT authentication for robust CMS updates

This commit is contained in:
2026-03-05 17:55:59 +01:00
parent 822e8a9d0f
commit aa57e8c48b

View File

@@ -9,23 +9,56 @@ import {
import axios from "axios";
import https from "https";
const PAYLOAD_URL = process.env.PAYLOAD_URL || "https://klz.infra.mintel.me";
const PAYLOAD_URL = process.env.PAYLOAD_URL || "http://localhost:3100";
const PAYLOAD_API_KEY = process.env.PAYLOAD_API_KEY;
if (!PAYLOAD_API_KEY) {
console.error("Warning: PAYLOAD_API_KEY is not set. API calls will fail.");
}
const PAYLOAD_EMAIL = process.env.PAYLOAD_EMAIL || "agent@mintel.me";
const PAYLOAD_PASSWORD = process.env.PAYLOAD_PASSWORD || "agentpassword123";
const httpsAgent = new https.Agent({
rejectUnauthorized: false, // For internal infra
});
let jwtToken: string | null = null;
const payloadClient = axios.create({
baseURL: `${PAYLOAD_URL}/api`,
headers: { Authorization: `users API-Key ${PAYLOAD_API_KEY}` },
headers: PAYLOAD_API_KEY ? { Authorization: `users API-Key ${PAYLOAD_API_KEY}` } : {},
httpsAgent
});
payloadClient.interceptors.request.use(async (config) => {
if (!PAYLOAD_API_KEY && !jwtToken && PAYLOAD_EMAIL && PAYLOAD_PASSWORD) {
try {
const loginRes = await axios.post(`${PAYLOAD_URL}/api/users/login`, {
email: PAYLOAD_EMAIL,
password: PAYLOAD_PASSWORD
}, { httpsAgent });
if (loginRes.data && loginRes.data.token) {
jwtToken = loginRes.data.token;
}
} catch (e) {
console.error("Failed to authenticate with Payload CMS using email/password.");
}
}
if (jwtToken && !PAYLOAD_API_KEY) {
config.headers.Authorization = `JWT ${jwtToken}`;
}
return config;
});
payloadClient.interceptors.response.use(res => res, async (error) => {
const originalRequest = error.config;
// If token expired, clear it and retry
if (error.response?.status === 401 && !originalRequest._retry && !PAYLOAD_API_KEY) {
originalRequest._retry = true;
jwtToken = null; // Forces re-authentication on next interceptor run
return payloadClient(originalRequest);
}
return Promise.reject(error);
});
const SEARCH_PRODUCTS_TOOL: Tool = {
name: "payload_search_products",
description: "Search for technical product specifications (cables, cross-sections) in KLZ Payload CMS",