szmyt151/src/js/webmcp.js
Adrian Miesikowski f4e5594882
All checks were successful
Build and Deploy WebMCP Stack / build-and-push (push) Successful in 39s
fix webmcp
2026-02-15 17:17:46 +01:00

210 lines
5.3 KiB
JavaScript

// WebMCP Contact Form Tools
// Implementation based on GoogleChromeLabs webmcp-tools demo
// Extend Navigator interface if needed, but in JS we can just check
if (typeof window !== "undefined") {
// Assuming modelContext might be added by extension
}
const registeredTools = {
submitContact: false,
getContactFormData: false,
resetContactForm: false,
};
function dispatchAndWait(
eventName,
detail = {},
successMessage = "Action completed successfully",
timeoutMs = 5000,
) {
return new Promise((resolve, reject) => {
const requestId = Math.random().toString(36).substring(2, 15);
const completionEventName = `tool-completion-${requestId}`;
const timeoutId = setTimeout(() => {
window.removeEventListener(completionEventName, handleCompletion);
reject(
new Error(
`Timed out waiting for UI to update (requestId: ${requestId})`,
),
);
}, timeoutMs);
const handleCompletion = () => {
clearTimeout(timeoutId);
window.removeEventListener(completionEventName, handleCompletion);
resolve(successMessage);
};
window.addEventListener(completionEventName, handleCompletion);
// Dispatch original event with requestId
const event = new CustomEvent(eventName, {
detail: { ...detail, requestId },
});
window.dispatchEvent(event);
});
}
async function submitContact(params) {
const data = {
name: params.name,
email: params.email,
subject: params.subject,
message: params.message,
};
try {
const response = await fetch("api/send-email.php", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Source": "web_form",
},
body: JSON.stringify(data),
});
const result = await response.json();
if (result.success) {
return result.message;
} else {
throw new Error(result.message || "Failed to send message.");
}
} catch (error) {
throw new Error(`Error submitting contact: ${error.message}`);
}
}
const submitContactTool = {
execute: submitContact,
name: "submitContact",
description:
"Submits the contact form with the provided information. All fields are required.",
inputSchema: {
type: "object",
properties: {
name: {
type: "string",
description: "Full name of the person submitting the form",
minLength: 1,
maxLength: 100,
},
email: {
type: "string",
description: "Email address of the person",
format: "email",
minLength: 1,
maxLength: 100,
},
subject: {
type: "string",
description: "Subject of the message",
minLength: 1,
maxLength: 200,
},
message: {
type: "string",
description: "The message content",
minLength: 1,
maxLength: 1000,
},
},
required: ["name", "email", "subject", "message"],
},
outputSchema: {
type: "string",
description:
"A message describing the result of the contact form submission",
},
annotations: {
readOnlyHint: "false",
},
};
function getContactFormData() {
const form = document.getElementById("contactForm");
if (!form) {
return { error: "Contact form not found" };
}
const formData = new FormData(form);
const data = {};
for (let [key, value] of formData.entries()) {
data[key] = value;
}
return data;
}
const getContactFormDataTool = {
execute: getContactFormData,
name: "getContactFormData",
description: "Retrieves the current data from the contact form fields.",
inputSchema: {},
outputSchema: {
type: "object",
description: "The current form data or an error message",
},
annotations: {
readOnlyHint: "true",
},
};
async function resetContactForm() {
return dispatchAndWait(
"resetContactForm",
{},
"Contact form reset successfully.",
);
}
const resetContactFormTool = {
execute: resetContactForm,
name: "resetContactForm",
description: "Resets all fields in the contact form to their default values.",
inputSchema: {},
outputSchema: {
type: "string",
description: "A message confirming the form reset",
},
annotations: {
readOnlyHint: "false",
},
};
function registerContactFormTools() {
const modelContext = window.navigator.modelContext;
if (modelContext) {
if (!registeredTools.submitContact) {
modelContext.registerTool(submitContactTool);
registeredTools.submitContact = true;
}
if (!registeredTools.getContactFormData) {
modelContext.registerTool(getContactFormDataTool);
registeredTools.getContactFormData = true;
}
if (!registeredTools.resetContactForm) {
modelContext.registerTool(resetContactFormTool);
registeredTools.resetContactForm = true;
}
}
}
function unregisterContactFormTools() {
const modelContext = window.navigator.modelContext;
if (modelContext) {
modelContext.unregisterTool(submitContactTool.name);
modelContext.unregisterTool(getContactFormDataTool.name);
modelContext.unregisterTool(resetContactFormTool.name);
registeredTools.submitContact = false;
registeredTools.getContactFormData = false;
registeredTools.resetContactForm = false;
}
}
// Auto-register if modelContext is available
if (typeof window !== "undefined" && window.navigator.modelContext) {
registerContactFormTools();
}