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
185 lines • 5.78 kB
TypeScript
/**
* BC Raw WebSocket Client (Week 2 Refactored)
*
* This is the transitional state after Week 2 refactoring:
* Uses BCAuthenticationService (extracted)
* Uses BCHandlerEventEmitter (extracted)
* Uses BCProtocolAdapter (extracted)
* Still contains WebSocket management (Week 3 will extract)
* Still contains session management (Week 4 will extract)
* Still contains filter cache (Week 4 will extract)
*
* After Week 4, this will become a thin facade (< 200 lines).
*/
import { type TimeoutsConfig } from '../../core/timeouts.js';
import type { ConnectionRequest, BCConfig } from '../../types.js';
/**
* BC Raw WebSocket Client
*
* Week 3 refactored version - delegates WebSocket management too.
* - Week 2: Extracted auth, events, protocol
* - Week 3: Extracted WebSocket management
* - Week 4: Will extract session & filter cache
*/
export declare class BCRawWebSocketClient {
private readonly authService;
private readonly eventEmitter;
private readonly wsManager;
private protocolAdapter;
private config;
private timeouts;
private serverSessionId;
private sessionKey;
private companyName;
private roleCenterFormId;
private clientSequenceCounter;
private openFormIds;
private spaInstanceId;
private filterMetadataCache;
constructor(config: BCConfig, username: string, password: string, tenantId?: string, timeouts?: Partial<TimeoutsConfig>);
/**
* Get the server session ID (for use with Copilot API)
*/
getServerSessionId(): string | null;
/**
* Get the company name from the current session
*/
getCompanyName(): string | null;
/**
* Get the tenant ID
*/
getTenantId(): string;
/**
* Get the role center form ID (for use with InvokeSessionAction)
*/
getRoleCenterFormId(): string | null;
/**
* Step 1: Authenticate via web login
*
* Delegates to BCAuthenticationService
*/
authenticateWeb(): Promise<void>;
/**
* Step 2: Connect to WebSocket with session cookies
*
* Week 3: Delegates to BCWebSocketManager
*/
connect(options?: {
signal?: AbortSignal;
timeoutMs?: number;
}): Promise<void>;
/**
* Check if client is ready (authenticated + connected)
*/
isReady(): boolean;
/**
* Disconnect WebSocket
*
* Week 3: Delegates to BCWebSocketManager
*/
disconnect(): Promise<void>;
/**
* Subscribe to handler events
*
* Delegates to BCHandlerEventEmitter
*/
onHandlers(listener: (handlers: unknown[]) => void): () => void;
/**
* Wait for handlers that match a predicate
*
* Delegates to BCHandlerEventEmitter
*/
waitForHandlers<T>(predicate: (handlers: unknown[]) => {
matched: boolean;
data?: T;
}, options?: {
timeoutMs?: number;
signal?: AbortSignal;
}): Promise<T>;
/**
* Send JSON-RPC request and wait for response
*
* Week 3: Delegates to BCWebSocketManager
*/
private sendRpcRequest;
/**
* Step 3: Open BC session
*
* Week 4 TODO: Extract to BCSessionManager
*/
openSession(connectionRequest: ConnectionRequest): Promise<unknown[]>;
/** Build the full OpenSession request matching browser format */
private buildOpenSessionRequest;
/** Calculate DST period for timezone information */
private calculateDstPeriod;
/** Extract session info (ServerSessionId, SessionKey, CompanyName) from handlers */
private extractSessionInfo;
/** Extract role center form ID from FormToShow handler */
private extractRoleCenterFormId;
/**
* Add a form to the openFormIds list.
* Must be called when a new form is opened (FormToShow event).
* BC requires ALL open forms to be listed in openFormIds for actions to work.
*/
addOpenForm(formId: string): void;
/**
* Remove a form from the openFormIds list.
* Should be called when a form is closed.
*/
removeOpenForm(formId: string): void;
/**
* Invoke BC action
*
* Week 4 TODO: Extract to BCSessionManager
*/
invoke(options: {
interactionName: string;
namedParameters: string | object;
controlPath?: string;
formId?: string;
systemAction?: number;
openFormIds?: string[];
sequenceNo?: string;
lastClientAckSequenceNumber?: number;
signal?: AbortSignal;
timeoutMs?: number;
}): Promise<unknown[]>;
/**
* Decompress handler response if needed
*
* Week 2: Still using local implementation (BCProtocolAdapter handles WebSocket messages)
* Week 4 TODO: Remove this when session manager is extracted
*/
private decompressIfNeeded;
/**
* Cache filter metadata from handler response
*
* Week 4 TODO: Extract to BCFilterMetadataCache
*/
cacheFilterMetadata(formId: string, handlers: unknown[]): number;
/**
* Resolve filter field ID from column caption
*
* Week 4 TODO: Extract to BCFilterMetadataCache
*/
resolveFilterFieldId(formId: string, caption: string): string | null;
/**
* Get available filter captions for a form
*
* Week 4 TODO: Extract to BCFilterMetadataCache
*/
getAvailableFilterCaptions(formId: string): string[] | null;
/**
* Apply filter to a list control
*
* Week 4 TODO: Extract to BCFilterMetadataCache
*/
applyFilter(params: {
formId: string;
listControlPath: string;
columnCaption: string;
filterValue?: string;
signal?: AbortSignal;
}): Promise<readonly unknown[]>;
}
//# sourceMappingURL=BCRawWebSocketClient.d.ts.map