← Files Qeemah (قيمة)ARCHIVED FILE
dist/server.js
12.8 KB · Nov 13, 2026 · 18:11 UTC
// src/server/index.ts
import { readFile } from "node:fs/promises";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
registerAppResource,
RESOURCE_MIME_TYPE
} from "@modelcontextprotocol/ext-apps/server";
import {
OpenAIExtensions as OpenAIExtensions2
} from "@openai/mcp-extensions/server";
import { z as z2 } from "zod";
// src/server/tools.ts
import { registerAppTool } from "@modelcontextprotocol/ext-apps/server";
import {
OpenAIFileEntrypointInputSchema
} from "@openai/mcp-extensions/server";
import { z } from "zod";
var ZATCA_VIEWER_URI = "ui://qeemah/zatca-viewer";
function registerQeemahTools(server, extensions) {
registerAppTool(
server,
"qeemah_zatca_viewer",
{
description: "Open, inspect, and verify Saudi ZATCA e-invoices (XML and PDF) with Phase 2 cryptographic verification, TLV QR code decoding, and VAT calculation.",
inputSchema: OpenAIFileEntrypointInputSchema,
_meta: {
ui: { resourceUri: ZATCA_VIEWER_URI, visibility: ["app"] },
"openai/ui": {
entrypoints: [
// Opens automatically when user clicks a .xml or .pdf in ChatGPT
{ type: "file", extensions: [".xml", ".pdf"] },
// Available as a tab in conversation threads
{ type: "thread" },
// Available fullscreen in sidebar
{ type: "global" }
]
}
}
},
async () => {
return {
content: []
};
}
);
const CreateDraftInputSchema = z.object({
customerName: z.string().optional().describe("Customer or company name"),
customerVat: z.string().optional().describe("15-digit customer VAT number (required for B2B)"),
isB2B: z.boolean().optional().default(true).describe("True for B2B Standard Tax Invoice, False for B2C Simplified"),
items: z.array(
z.object({
name: z.string().describe("Item or service name"),
quantity: z.number().default(1).describe("Quantity"),
unitPrice: z.number().describe("Unit price in SAR"),
taxRate: z.number().default(15).describe("VAT rate (15 or 0)")
})
).optional().describe("Initial line items for the invoice draft"),
notes: z.string().optional().describe("Optional notes or payment terms")
});
registerAppTool(
server,
"qeemah_create_invoice_draft",
{
description: "Draft and calculate a new Saudi ZATCA e-invoice (B2B or B2C) with real-time VAT calculation in the ChatGPT side panel.",
inputSchema: CreateDraftInputSchema,
_meta: {
ui: { resourceUri: ZATCA_VIEWER_URI, visibility: ["app", "model"] },
"openai/ui": {
entrypoints: [{ type: "thread" }]
}
}
},
async (args) => {
void args;
return {
content: [
{
type: "text",
text: "The invoice draft is ready in the Qeemah side panel."
}
],
structuredContent: { mode: "draft" }
};
}
);
const CfoInputSchema = z.object({
quarter: z.string().optional().describe("Quarter to review (e.g. Q3 2026, Q4 2026)")
});
registerAppTool(
server,
"qeemah_cfo_dashboard",
{
description: "Open the Qeemah AI CFO Dashboard to review quarterly VAT liability, Phase 2 clearance stats, cashflow pulse, and compliance health in Saudi Arabia.",
inputSchema: CfoInputSchema,
_meta: {
ui: { resourceUri: ZATCA_VIEWER_URI, visibility: ["app", "model"] },
"openai/ui": {
entrypoints: [{ type: "global" }, { type: "thread" }]
}
}
},
async (args) => {
const q = args.quarter || "\u0627\u0644\u0631\u0628\u0639 \u0627\u0644\u062B\u0627\u0644\u062B 2026";
return {
content: [
{
type: "text",
text: `\u062A\u0645 \u0641\u062A\u062D \u0644\u0648\u062D\u0629 \u062A\u062D\u0643\u0645 \u0627\u0644\u0645\u062F\u064A\u0631 \u0627\u0644\u0645\u0627\u0644\u064A \u0648\u0627\u0644\u0632\u0643\u0627\u0629 (${q}) \u0641\u064A \u0627\u0644\u0644\u0648\u062D\u0629 \u0627\u0644\u062C\u0627\u0646\u0628\u064A\u0629 \u0644\u0642\u064A\u0645\u0629. \u0635\u0627\u0641\u064A \u0627\u0644\u0636\u0631\u064A\u0628\u0629 \u0627\u0644\u0645\u0633\u062A\u062D\u0642\u0629 \u0644\u0644\u0633\u062F\u0627\u062F: 26,750.00 \u0631.\u0633. \u0646\u0633\u0628\u0629 \u0627\u0645\u062A\u062B\u0627\u0644 \u0627\u0644\u0641\u0648\u0627\u062A\u064A\u0631 \u0644\u0640 ZATCA: 98.6%.`
}
],
structuredContent: {
mode: "cfo",
cfoData: {
period: q,
dueDate: "2026-10-31",
currency: "SAR",
taxableSales: 301333.33,
taxablePurchases: 123e3,
outputVat: 45200,
inputVat: 18450,
netPayableVat: 26750,
totalInvoices: 148,
compliantInvoices: 146,
flaggedInvoices: 2,
clearanceRate: 98.6,
receivables: 185400,
overdueReceivables: 12500,
payables: 64200
}
}
};
}
);
server.registerTool(
"qeemah_audit_invoice_xml",
{
description: "Perform a compliance audit on a Saudi Arabian ZATCA UBL 2.1 e-invoice XML string, verifying VAT numbers, line item calculations, and Phase 2 requirements.",
inputSchema: {
xmlContent: z.string().describe("The raw UBL 2.1 XML content of the Saudi e-invoice")
}
},
async ({ xmlContent }) => {
try {
const hasInvoiceTag = xmlContent.includes("<Invoice");
const hasVatTag = xmlContent.includes("PartyTaxScheme");
const hasQrTag = xmlContent.includes("cac:AdditionalDocumentReference");
if (!hasInvoiceTag) {
return {
content: [
{
type: "text",
text: "Error: The provided string is not a valid UBL 2.1 Invoice XML document."
}
],
isError: true
};
}
const idMatch = xmlContent.match(/<cbc:ID>([^<]+)<\/cbc:ID>/);
const invoiceTypeMatch = xmlContent.match(/<cbc:InvoiceTypeCode[^>]*>([^<]+)<\/cbc:InvoiceTypeCode>/);
const payableMatch = xmlContent.match(/<cbc:PayableAmount[^>]*>([^<]+)<\/cbc:PayableAmount>/);
const vatAmountMatch = xmlContent.match(/<cbc:TaxAmount[^>]*>([^<]+)<\/cbc:TaxAmount>/);
const summary = {
invoiceNumber: idMatch ? idMatch[1] : "Unknown",
invoiceTypeCode: invoiceTypeMatch ? invoiceTypeMatch[1] : "388",
payableAmount: payableMatch ? payableMatch[1] : "0.00",
vatAmount: vatAmountMatch ? vatAmountMatch[1] : "0.00",
hasQrCode: hasQrTag,
hasTaxScheme: hasVatTag,
status: "Passed basic structure check. For full cryptographic and TLV verification, view in the Qeemah ZATCA Inspector."
};
return {
content: [
{
type: "text",
text: JSON.stringify(summary, null, 2)
}
]
};
} catch (err) {
return {
content: [
{
type: "text",
text: `Audit failed: ${err instanceof Error ? err.message : "Unknown error"}`
}
],
isError: true
};
}
}
);
}
// src/server/index.ts
var __filename = fileURLToPath(import.meta.url);
var __dirname = path.dirname(__filename);
async function getAppHtml() {
const possiblePaths = [
path.resolve(__dirname, "./app.html"),
path.resolve(__dirname, "../dist/app.html"),
path.resolve(process.cwd(), "dist/app.html")
];
for (const p of possiblePaths) {
try {
const html = await readFile(p, "utf8");
return html;
} catch {
}
}
return `<!DOCTYPE html><html><body><div id="root"><h2>Qeemah ZATCA Inspector Loading...</h2></div></body></html>`;
}
async function main() {
const server = new McpServer({
name: "qeemah",
version: "1.0.0"
});
const extensions = new OpenAIExtensions2(server);
let currentSettings = {
environment: "sandbox",
autoCalculateVat: true
};
extensions.settings?.register({
fields: {
environment: {
schema: z2.enum(["sandbox", "simulation", "production"]),
title: "\u0628\u064A\u0626\u0629 \u0647\u064A\u0626\u0629 \u0627\u0644\u0632\u0643\u0627\u0629 (ZATCA Environment)",
description: "ZATCA integration tier: sandbox, simulation, or production"
},
autoCalculateVat: {
schema: z2.boolean(),
title: "\u0627\u0644\u062D\u0633\u0627\u0628 \u0627\u0644\u062A\u0644\u0642\u0627\u0626\u064A \u0644\u0636\u0631\u064A\u0628\u0629 \u0627\u0644\u0642\u064A\u0645\u0629 \u0627\u0644\u0645\u0636\u0627\u0641\u0629 (15%)",
description: "Automatically calculate standard 15% VAT on invoice line items"
}
},
layout: [
{
kind: "group",
title: "\u0628\u064A\u0626\u0629 \u0627\u0644\u0631\u0628\u0637 \u0648\u0627\u0644\u062A\u0643\u0627\u0645\u0644 (Integration & System)",
items: [
{ kind: "property", property: "environment" },
{ kind: "property", property: "autoCalculateVat" }
]
}
],
read: async () => {
return {
environment: currentSettings.environment,
autoCalculateVat: currentSettings.autoCalculateVat
};
},
update: async (set) => {
currentSettings = { ...currentSettings, ...set };
return {
environment: currentSettings.environment,
autoCalculateVat: currentSettings.autoCalculateVat
};
}
});
extensions.mentions?.setHandler(async ({ query }) => {
const q = (query || "").toLowerCase();
const allMentions = [
{
type: "resource_link",
uri: ZATCA_VIEWER_URI,
name: "zatca_inspector",
title: "\u0641\u0627\u062D\u0635 \u0627\u0644\u0641\u0648\u0627\u062A\u064A\u0631 ZATCA (Qeemah Inspector)",
description: "\u0641\u062D\u0635 \u0648\u062A\u062F\u0642\u064A\u0642 \u0627\u0644\u0641\u0648\u0627\u062A\u064A\u0631 \u0627\u0644\u0625\u0644\u0643\u062A\u0631\u0648\u0646\u064A\u0629 XML \u0648 PDF \u0648\u0627\u0644\u062A\u062D\u0642\u0642 \u0645\u0646 \u0627\u0644\u062A\u0648\u0642\u064A\u0639 \u0627\u0644\u0631\u0642\u0645\u064A \u0648\u0631\u0645\u0632 \u0627\u0644\u0627\u0633\u062A\u062C\u0627\u0628\u0629 \u0627\u0644\u0633\u0631\u064A\u0639\u0629 TLV"
},
{
type: "resource_link",
uri: ZATCA_VIEWER_URI,
name: "invoice_drafter",
title: "\u0645\u0646\u0634\u0626 \u0645\u0633\u0648\u062F\u0627\u062A \u0627\u0644\u0641\u0648\u0627\u062A\u064A\u0631 (Invoice Drafter)",
description: "\u062A\u062C\u0647\u064A\u0632 \u0648\u062D\u0633\u0627\u0628 \u0645\u0633\u0648\u062F\u0629 \u0641\u0627\u062A\u0648\u0631\u0629 \u0636\u0631\u064A\u0628\u064A\u0629 \u062C\u062F\u064A\u062F\u0629 B2B \u0623\u0648 \u0645\u0628\u0633\u0637\u0629 B2C \u0648\u062D\u0633\u0627\u0628 \u0627\u0644\u0636\u0631\u064A\u0628\u0629 15% \u0645\u0628\u0627\u0634\u0631\u0629"
},
{
type: "resource_link",
uri: ZATCA_VIEWER_URI,
name: "cfo_dashboard",
title: "\u0644\u0648\u062D\u0629 \u0627\u0644\u0645\u062F\u064A\u0631 \u0627\u0644\u0645\u0627\u0644\u064A \u0648\u0627\u0644\u0632\u0643\u0627\u0629 (AI CFO & Tax Return)",
description: "\u0645\u0624\u0634\u0631\u0627\u062A \u0627\u0644\u0631\u0628\u0639 \u0627\u0644\u062D\u0627\u0644\u064A \u0648\u0635\u0627\u0641\u064A \u0627\u0644\u0636\u0631\u064A\u0628\u0629 \u0627\u0644\u0645\u0633\u062A\u062D\u0642\u0629 \u0644\u0644\u062F\u0641\u0639 \u0648\u0646\u0628\u0636 \u0627\u0644\u0633\u064A\u0648\u0644\u0629 \u0627\u0644\u0646\u0642\u062F\u064A\u0629 \u0648\u0646\u0633\u0628\u0629 \u0627\u0644\u0627\u0645\u062A\u062B\u0627\u0644"
}
];
if (!q) {
return { items: allMentions };
}
const filtered = allMentions.filter(
(m) => m.name.toLowerCase().includes(q) || m.title.toLowerCase().includes(q) || m.description && m.description.toLowerCase().includes(q)
);
return { items: filtered.length ? filtered : allMentions };
});
registerAppResource(
server,
"qeemah-zatca-viewer-resource",
ZATCA_VIEWER_URI,
{},
async () => {
const html = await getAppHtml();
return {
contents: [
{
uri: ZATCA_VIEWER_URI,
mimeType: RESOURCE_MIME_TYPE,
text: html,
_meta: {
"openai/ui": {
preferredDisplayMode: "fullscreen",
availableDisplayModes: ["inline", "fullscreen"]
}
}
}
]
};
}
);
registerQeemahTools(server, extensions);
const transport = new StdioServerTransport();
await server.connect(transport);
}
main().catch((err) => {
console.error("Fatal error starting Qeemah MCP server:", err);
process.exit(1);
});
SHA-256: 64000e8a5d927cf2d3e39f011097e3e4139f8fcbd851ce3763113d802207b19e