sgcWebSockets 2026.10 is out. Three threads run through it: sgcHTML grew the parts a business web application needs and stops you writing by hand, the cryptography went post-quantum without adding a single external library, and a new set of Enterprise authentication components took over the login screen.
Web Applications: the Boring Parts, Done
Sessions, login and CSRF. The new TsgcHTMLAuth component and its session stores keep the cookie, answer the login and logout requests, close idle sessions and throttle failed logins. The CSRF token travels in a meta tag, htmx adds it to every request on its own, and the server rejects a post that does not carry it.
FAuth := TsgcHTMLAuth.Create(Self);
FAuth.SessionStore := TsgcHTMLSessionStore_Memory.Create(Self);
FAuth.CookieName := 'app_session';
FEngine.Auth := FAuth;
Routes that read like routes. Path parameters, a method filter, and access to the headers, the cookies and the body:
with FRouter.Routes.Add do
begin
Path := '/customers/{id}/edit';
Methods := [hrmGet, hrmPost];
RequireLogin := True;
RequireRoles := 'admin,sales';
end;
Pages you can test. DispatchDirect answers a request with no socket behind it, and a new unit reads the generated HTML, finds elements by id, class, tag or attribute and compares a page against a saved copy, so an unintended change in the markup is noticed by a test rather than by a customer.
Navigation that feels like an application. Pages change without a full reload and keep the scroll position and what the user was typing, with a loading bar, a dialog when the connection drops and a message when a request fails. All of it off by default.
A page designed on a form, with zero code. Drop a TsgcWebSocketHTTPServer, a TsgcHTMLDesignServer, a TsgcHTMLDesignSurface and some sgcHTML components on a VCL form, and WSServer.Active := True is the only line to write. The design server builds the page from the form and serves Bootstrap, htmx and Chart.js from the executable. Surface actions run Delphi code when the user clicks or submits: set Source and Target in the Object Inspector, double-click OnExecute, and the target is updated in place without a page reload. Six QuickStart demos in Demos\60.HTML\00.QuickStart teach it one step at a time, the Getting Started guide (PDF) explains them, and the sgcHTML quick start shows the 5-minute path.
The Four Headline Features
Each of these has an article of its own, linked at the end, so here is only what it is:
- MCP Apps. An MCP tool that answers with a page instead of a paragraph, rendered inside ChatGPT, Claude or VS Code, built from the same components as any other sgcHTML page.
- The AI page generator. Describe a page, or hand the designer a screenshot, and it builds it out of your registered components as a candidate you accept or discard.
- The CRUD component. List, search, paging, form, delete and the write path of one dataset, over a TDataSet or over your own SQL, with an IDE wizard and a command line generator.
- The AI Data Pack. Ask a grid, a data table or a pivot a question in plain language, with a rule based parser that answers when there is no API key at all.
Push, Two Ways
Server sent events can now carry the updates instead of a WebSocket, with replay of what was missed while disconnected, and it works with the plain HTTP server. Web Push reaches a browser that is closed. A notification inbox and a preferences table come with them, and the notification component decides which channel a given user gets.
An EventSource Client for Delphi
The new TsgcSSEClient consumes any Server-Sent Events stream and ships in every edition. It reconnects on its own and sends Last-Event-ID, so the server resumes where the stream stopped. The retry: field sent by the server is honoured, OnEvent hands you the event type, the data and the id, and ReconnectOptions adds backoff and jitter. TLS, proxy and authentication are set in OnBeforeConnect, which hands you the HTTP client the component uses.
FSSE := TsgcSSEClient.Create(Self);
FSSE.URL := 'https://example.com/events';
FSSE.ReconnectOptions.Backoff := True;
FSSE.ReconnectOptions.MaxInterval := 30000;
FSSE.ReconnectOptions.Jitter := 0.2;
FSSE.OnEvent := DoSSEEvent;
FSSE.Open;
procedure TForm1.DoSSEEvent(Sender: TObject; const aEvent: TsgcSSEEvent);
begin
Memo1.Lines.Add(aEvent.EventType + ': ' + aEvent.Data);
end;
The parser behind it, TsgcSSEParser, is public. Feed it the bytes of any text/event-stream in chunks of any size, which is exactly what an LLM streaming response or an MCP Streamable HTTP reply is.
FParser := TsgcSSEParser.Create;
FParser.OnEvent := DoSSEEvent;
FParser.Feed('event: delta' + #10 + 'data: {"text":"Hel"}' + #10#10);
A new demo, Demos\20.HTTP_Protocol\17.SSE_Client_Component, shows it end to end.
AI: Answers You Can Act On
TsgcAIChat can ask for JSON that follows a schema you supply, on OpenAI, Anthropic, Gemini, DeepSeek, Ollama, Grok and Mistral, through the new ChatJSON method, which parses the answer and asks once more with the parse error attached when it cannot be read. The chat component also sends and receives images now, and BaseUrl is honoured by every provider rather than only by Ollama, so any of them can be pointed at a proxy or a local gateway.
Document Extraction: From PDF to Validated JSON
The new TsgcAIDocumentExtractor takes a PDF or an image and a JSON schema, and hands back JSON that has been checked against that schema. OpenAI, Anthropic and Gemini read the PDF directly, the other vision models read images. Built in presets cover invoices, receipts and identity documents (dpInvoice, dpReceipt, dpIDCard), and every field comes with a confidence, so OnLowConfidence tells you which values below MinConfidence deserve a second look. When the answer does not validate, the component asks once more with the errors attached (ValidationRetries).
FExtractor := TsgcAIDocumentExtractor.Create(Self);
FExtractor.AIChat := AIChat1;
FExtractor.Preset := dpInvoice;
FExtractor.MinConfidence := 0.8;
FExtractor.OnLowConfidence := DoLowConfidence;
Memo1.Lines.Text := FExtractor.ExtractFile('invoice.pdf');
if FExtractor.LastResult.FieldConfidence('total') < 0.8 then
ShowMessage('Check the total by hand');
Link a TsgcAIOCRTesseract, or a TsgcAIOCRWindows that uses the OCR built into Windows 10 and later with nothing to install, and set OCRMode to domFallback or domAlways, and the text is recognised locally first, so even a text only model running on Ollama can do the extraction. For your own prompts, TsgcAIChat gains ChatWithDocument, ChatWithDocumentBase64, ChatWithAttachments and ChatJSONWithAttachments, which send one or several files, held in a TsgcAIChatAttachments list, with the message.
A Voice Agent That Listens, Talks Back and Calls Tools
The new TsgcAIVoiceAgent is one component that listens, detects when the user has finished a turn, answers with its own voice and calls your tools, over OpenAI Realtime or Gemini Live. It speaks WebSocket, or WebRTC with OpenAI, and runs on Windows, Android and iOS. Turns are detected by server VAD, semantic VAD, a client side VAD or by hand (vtdServerVAD, vtdSemanticVAD, vtdClientVAD, vtdManual). With BargeIn the user can interrupt, and the agent stops talking and truncates its answer where it was cut off. OnTranscript delivers live transcripts of both the user and the agent.
FAgent := TsgcAIVoiceAgent.Create(Self);
FAgent.Provider := vapOpenAI;
FAgent.OpenAIOptions.ApiKey := 'sk-...';
FAgent.Instructions := 'You are the shop assistant. Keep answers short.';
FAgent.TurnDetection.Mode := vtdSemanticVAD;
FAgent.BargeIn := True;
oTool := FAgent.Tools.Add;
oTool.Name := 'find_product';
oTool.Description := 'Looks up a product by name';
oTool.Parameters :=
'{"type":"object","properties":{"name":{"type":"string"}}}';
FAgent.OnTranscript := DoTranscript;
FAgent.OnToolCall := DoToolCall;
FAgent.Start;
procedure TForm1.DoToolCall(Sender: TObject; const aCallId, aName,
aArguments: string; var aResult: string; var aHandled: Boolean);
begin
if aName = 'find_product' then
begin
aResult := FindProduct(aArguments);
aHandled := True;
end;
end;
Tools come from OnToolCall, and when a TsgcWSAPI_Client_MCP is assigned to MCPClient the tools of that MCP server are offered to the model automatically. For telephony, Audio.Format switches to G.711 mu-law or A-law at 8 kHz (vafG711ULaw, vafG711ALaw). The voice agent is available for Delphi 7 to Delphi 13 and for .NET, and a new demo turns it into a voice shop assistant over a TDataSet.
MCP: the 2026-07-28 Specification
The MCP server and client now speak the 2026-07-28 revision of the Model Context Protocol. The same server answers the new stateless clients and the existing 2025-11-25 clients such as VS Code and Claude, so nothing changes for the clients you already have. On the client, MCPOptions.ProtocolEra set to Auto tries the new protocol first, falls back when the server does not support it and remembers the answer per server.
- Discovery and headers.
server/discover, the protocol version and client details sent with every request, theMcp-MethodandMcp-Namerequest headers checked by the server, cache hints on list results and the new error codes. Tool parameters marked withx-mcp-headertravel as request headers. - One stream for every change. With
subscriptions/listena client opens one long lived stream and receives tools, prompts and resources list changes and resource updates. The Send notification methods you already call reach these clients too. - Multi round trip requests. A tool, prompt or resource can ask the client for input, a form, a web page, an AI answer or the client roots, and continue when the client calls again with the answers. The state kept between calls is signed and expires (
MCPOptions.MRTR). On the client,OnMCPInputRequiredanswers them, and the existing roots, sampling and elicitation handlers answer on their own. - Tasks. A long running tool returns a task that the client follows until it finishes, answers when the task needs input, and can cancel. On the server it is
MCPOptions.TaskswithCreateTask, on the clientOnMCPTaskCreated,OnMCPTaskStatusandOnMCPTaskCompleted. - Client authorization. With
MCPOptions.Authorizationenabled, a 401 is no longer the end of the road: the client finds the authorization server by itself, registers with a client id metadata document or dynamic registration, signs in with PKCE, checks the issuer and refreshes the token when it expires.
Cryptography: Post-Quantum, in Object Pascal
ML-KEM (FIPS 203), ML-DSA (FIPS 204) and SLH-DSA (FIPS 205), X-Wing hybrid key encapsulation, post-quantum X.509 certificates and certificate authorities, and JWT signed with ML-DSA. All of it written in Object Pascal in the sgcCrypto pack, with no external library, validated against the NIST known answer vectors.
On top of that sits a native TLS 1.3 and TLS 1.2 engine, also pure Pascal: a client or a server speaks TLS without OpenSSL and without SChannel, negotiating the hybrid post-quantum groups of RFC 10024, with ALPN, S N I, client certificates and optional use of the operating system trust store. TLS 1.2 is there for the peers that cannot do TLS 1.3 yet, with forward secret AES-GCM and ChaCha20-Poly1305 suites by default, extended master secret and downgrade protection, and TLSOptions.Version sets the lowest version allowed. The hybrid groups stay on TLS 1.3.
The classical side was hardened in the same pass: blinded constant time RSA, constant time elliptic curve scalar multiplication and Ed25519, table free AES and GHASH, imported private keys checked against their public half, and non minimal DER signatures rejected.
TLS on the Server, Your Way
Plain and TLS on the same port. SSLOptions.AllowPlainText lets a TLS server also accept plain HTTP and WebSocket connections on the same port, telling them apart by the first byte the client sends. SSLOptions.PlainTextPolicy serves them, redirects them with a 308 to https, or rejects them with a 400, and Server.IsTLS(AContext) tells you in OnCommandGet which transport a request came on. It works with the default, IOCP and EPOLL IOHandlers.
HSTS for an A+. SecurityOptions.HSTS_Options adds the Strict-Transport-Security header to every response sent over TLS, which is what SSL Labs needs to give an A+ grade. It is never sent over plain HTTP, and it is not added twice when your code already sets it.
Bring your own TLS library. The IOCP and EPOLL servers are no longer tied to OpenSSL. Write a TLS provider for your library, SecureBlackbox for example, and the event driven engine drives it exactly like the built in one.
Authentication: the Login Everyone Asks For
A new set of authentication components answers the questions every customer asks about the login screen. They ship in the Enterprise and All-Access editions and in the sgcAuth pack, and the same components are part of sgcWebSockets .NET.
- Passkeys. The WebAuthn server signs a user in with no user name to type, offers the passkeys in the browser's own autofill list, keeps several passkeys per user, tells a synced passkey from one bound to a single device, and raises an event so the credentials live in your own database.
- SAML single sign-on.
TsgcSAMLServiceProviderturns your application into a SAML 2.0 service provider for Entra ID, Okta, AD FS, Google Workspace, Keycloak or any other identity provider. - Active Directory and LDAP.
TsgcLDAPClientsigns users in with their directory password over LDAPS or StartTLS, and reads their group membership, nested groups included. - Codes from an authenticator app.
TsgcTOTPAuthenticatorissues and checks the codes of Google Authenticator, Microsoft Authenticator and the like, with the enrolment link for the QR code, replay protection and recovery codes. - OpenID Connect.
TsgcHTTP_OIDC_Clientsigns users in with any OpenID provider through its discovery document, and validates the ID tokens and the bearer tokens that reach your own API. - Mail without a stored password.
TsgcMailOAuth2obtains and refreshes the Microsoft 365 and Gmail OAuth2 tokens that SMTP, IMAP and POP3 now expect.
Smaller Things That Add Up
- Right-to-left pages. sgcHTML pages switch to a right-to-left layout on their own for Arabic, Hebrew, Persian, Urdu and the other right-to-left languages, load the right-to-left Bootstrap stylesheet now included in the library, and mirror the components from the sidebar to the grid.
HtmlDirandDirforce a direction when you need one. New demo 22.RTL. - Geolocation.
TsgcHTMLComponent_Geolocationreads the GPS position of the browser once or continuously and sends latitude, longitude, accuracy, altitude, heading and speed to the server. - A grid that sorts and filters on the server.
SortMode := gsmServerandServerFiltersend the sort and one filter input per column over htmx, with a text or a range filter per column (gfkText,gfkRange). Pagination and AutoComplete gained the same htmx path over plain HTTP. - Camera scanner on iPhone.
PolyfillURLloads a barcode decoder on browsers that have none built in, andRedirectURLopens a page with the scanned code. - Lazarus. The sgcHTML run time demos are now available for Lazarus and Free Pascal, and the Lazarus package includes the CRUD and MCP Apps units.
- Why was I refused? When a server refuses a WebSocket connection, for example with a 401 because the token expired, the body of its answer is available in
OnExceptionthroughTsgcWSConnectionClient(Connection).HandshakeResponseBody. - Your own data on the connection thread.
QueueOptions.DrainedMode := qdmEveryPassraisesOnQueueDrainedon every pass of the connection loop, on the connection's own thread, so the application can send its pending data from there. - Keep-alive on WinHTTP. The WinHTTP WebSocket client gains
OnBeforeHeartBeatto send your own keep-alive message every HeartBeat interval. - AI Chat.
ImageOutputlets Gemini answer with images and keep editing them message after message, the OpenAI image edit request accepts the gpt-image-1 options and several input images, andTLSOptionschooses the OpenSSL version used by the provider requests. - OpenAPI client.
TsgcOpenAPI_Client.UserAgentsets the User-Agent header of every request, or omits it when empty.
Fixes Worth Naming
- JWT signing and validation with RSA and ECDSA keys, and memory corruption in 32-bit applications, when OpenSSL is linked statically.
- The SChannel handler leaving a copy of the private key in the Windows key store for every connection using a PFX file, and not sending the client certificate on recent Windows versions.
- Concurrent SChannel connections using a certificate from the Windows store failing the handshake.
- The OAuth2 server rejecting DPoP proofs signed with RSA keys.
- CloudFront signed URLs whose signature was not URL safe encoded.
.NET
The .NET library keeps pace: auth and sessions with a ClaimsPrincipal bridge for ASP.NET Core, the router, the testing helpers, SPA navigation, the SSE transport with a native endpoint, structured output, document extraction with both OCR engines, the realtime voice agent, the AI Data Pack, Web Push, MCP Apps, the CRUD component with its adapters and the new TsgcSSEClient, all with the same API names as Delphi.
Razor Tag Helpers for ASP.NET Core. sgcHTML now fits an MVC or Razor Pages application the way Telerik UI and DevExpress do. Tag Helpers such as <sgc-grid>, <sgc-form>, <sgc-autocomplete>, <sgc-dialog> and <sgc-chart>, and their fluent twins under Html.Sgc(), render Bootstrap 5 on the server and talk to your controllers over htmx, with no JavaScript framework. The grid pages, sorts, filters, searches and exports to XLSX and PDF over an IQueryable, so EF Core runs it all as SQL:
<sgc-grid name="orders" key="Id" items="Model"
asp-action="Read" asp-export-action="Export" export="xlsx,pdf"
page-size="15" sortable="true" filterable="true"
searchable="true" push-url="true">
<sgc-column field="Reference" searchable="true" />
<sgc-column field="Customer" searchable="true" />
<sgc-column field="OrderDate" title="Date" format="{0:yyyy-MM-dd}" filter="range" />
<sgc-column field="Total" format="{0:N2}" align="right" filter="range" />
</sgc-grid>
// OrdersController
public IActionResult Read(SgcDataRequest request) => this.SgcGrid(request, Rows());
Inputs bind with asp-for and show the ModelState errors, and this.SgcCloseDialog("edit-order", refresh: "orders") closes an edit dialog and reloads the grid. The part the others do not have is server push: a chart with live="true" redraws in every open browser when a background service calls hub.BroadcastChartAsync(...), over the sgcHTML WebSocket and with no SignalR code. It ships in the esegece.sgcHTML.AspNetCore NuGet package, Community edition included, and the 22.RazorMvc demo is the familiar orders sample rebuilt with it.
Upgrading
Everything new is additive and off by default. Drop in the new units, rebuild your packages, and an existing application behaves exactly as it did.
The Long Versions
- Run Your Delphi App Inside ChatGPT and Claude
- Turn a Screenshot Into a Delphi Web Page
- Delphi TLS 1.3 Without OpenSSL DLLs
- A Delphi Web CRUD Page in Five Minutes
- Ask Your Delphi Grid a Question in Plain English
- Reach a Browser That Is Closed, From Delphi
- Delphi Login With Passkeys, SAML SSO, LDAP and TOTP 2FA
- SAML Single Sign-On in Delphi With Entra ID, Okta and AD FS
- Passkeys in Delphi: Passwordless Login With WebAuthn
Watch It
There is a short video of this on the eSeGeCe channel.
Questions, feedback or migration help? Get in touch — you will get a reply from the people who wrote the code.
