bc-webclient-mcp
Version:
Model Context Protocol (MCP) server for Microsoft Dynamics 365 Business Central via WebUI protocol. Enables AI assistants to interact with BC through the web client protocol, supporting Card, List, and Document pages with full line item support and server
59 lines • 2.15 kB
JavaScript
/**
* Business Central WebSocket Response Decompression
*
* BC compresses WebSocket responses using standard gzip and base64 encoding.
* This utility decompresses responses to access LogicalForm data.
*
* Based on protocol analysis - see docs/tell-me-search-protocol.md
*/
import { gunzipSync } from 'zlib';
import { DecompressionError } from '../core/errors.js';
import { ok, err } from '../core/result.js';
/**
* Decompresses a BC WebSocket response payload.
*
* BC responses with "message": "compressed" contain gzip-compressed,
* base64-encoded JSON data.
*
* @param compressedData - Base64 string from WebSocket response
* @returns Decompressed JSON object or error
*/
export function decompressBCPayload(compressedData) {
try {
// Step 1: Decode base64 to binary buffer
const buffer = Buffer.from(compressedData, 'base64');
// Step 2: Decompress with gzip
const decompressed = gunzipSync(buffer);
// Step 3: Convert to UTF-8 string
const jsonString = decompressed.toString('utf8');
// Step 4: Parse JSON
const parsed = JSON.parse(jsonString);
return ok(parsed);
}
catch (error) {
return err(new DecompressionError(`Failed to decompress BC payload: ${error instanceof Error ? error.message : String(error)}`, { originalError: error }));
}
}
/**
* Decompresses a BC WebSocket message if it's compressed.
*
* @param message - WebSocket message object
* @returns Decompressed payload or original message if not compressed
*/
export function decompressIfNeeded(message) {
const typedMessage = message;
// Check if message is compressed
if (typedMessage?.message === 'compressed' && typedMessage?.payload) {
return decompressBCPayload(typedMessage.payload);
}
// Return as-is if not compressed
return ok(message);
}
/**
* Type guard to check if a WebSocket message is compressed.
*/
export function isCompressedMessage(message) {
const typedMessage = message;
return typedMessage?.message === 'compressed' && typeof typedMessage?.payload === 'string';
}
//# sourceMappingURL=decompression.js.map