sgalinski/sg-ai

SGAI by sgalinski is an AI editorial suite for TYPO3 with backend-integrated alt text generation, AI image and text generation, SEO title/description automation, technical/content SEO and accessibility recommendations, queue-based asynchronous processing with Scheduler support, CLI bulk commands, da

Maintainers

Package info

gitlab.sgalinski.de/sg-ai/sg_ai.git

Homepage

Issues

Documentation

Type:typo3-cms-extension

pkg:composer/sgalinski/sg-ai

Transparency log

Statistics

Installs: 9

Dependents: 0

Suggesters: 0

2.4.1 2026-06-17 16:35 UTC

README

sgalinski logo

License: GNU GPL, Version 3

Repository: https://gitlab.sgalinski.de/sg-ai/sg_ai

Please report bugs here: https://gitlab.sgalinski.de/sg-ai/sg_ai/-/work_items

Overview

sg_ai brings AI-assisted editorial workflows directly into TYPO3 backend forms and modules.

The extension covers:

  • Alt text generation for images (sys_file_reference and sys_file_metadata)
  • AI image generation in file fields (including automatic file reference creation)
  • AI text generation in configured text fields
  • SEO title/description generation for pages and social meta fields
  • Technical SEO, content SEO, and accessibility recommendations
  • Queue-based background processing for long-running operations
  • Backend history views for queued/generated AI results
  • Prompt persistence for image generation (including image settings block)
  • Automatic SEO-friendly image filename generation based on alt text

For end-user focused documentation, see:

Requirements

  • TYPO3 v13 LTS (13.4)
  • PHP >= 8.3
  • Valid SG AI API key

Installation

  1. Install extension:
composer require sgalinski/sg_ai
  1. Activate extension in Extension Manager.
  2. Run database schema updates in TYPO3 Install Tool / Admin Tools.
  3. Configure extension settings (see next section).

Configuration

Open:

  • Admin Tools > Settings > Extension Configuration > sg_ai

Available extension settings (ext_conf_template.txt):

  • apiKey
  • useImageAnalysis
  • useBase64Encoding
  • useContextForAltText
  • language
  • watermarkEnabled
  • watermarkOverlayEnabled
  • watermarkPreserveMetadataOnProcessing
  • watermarkBadgeAssetPath
  • watermarkPosition
  • watermarkMargin
  • watermarkRelativeSize
  • watermarkMaxWidth
  • watermarkMaxHeight
  • watermarkOpacity
  • watermarkMinWidth
  • watermarkMinHeight
  • watermarkScreenReaderLabelEnabled
  • watermarkScreenReaderSuffix
  • watermarkOverlayAccessibilityLabel

Recommended API key setup:

  • Preferred: provide SG_AI_API_KEY as environment variable (for example in .env.local)
  • Alternative: set apiKey directly in extension configuration

AI Image Watermarking

  • Watermark overlays are applied via PSR-14 image-rendering events.
  • sg_ai provides a frontend SASS partial for overlay positioning at Resources/Public/Sass/Bootstrap5/_sg-ai.scss.
  • Theme integrations (for example project-theme) should import this partial.

  • watermarkEnabled=1 means watermark logic is active for images marked as AI-generated (tx_sgai_is_ai_generated in metadata or file references).

  • watermarkOverlayEnabled=1 enables frontend HTML/CSS overlay badge rendering (default: 0, disabled).
  • watermarkPreserveMetadataOnProcessing=1 sets SG AI provenance metadata during TYPO3 processing in the same ImageMagick call.
  • Mode-only override is available via sgAiWatermarkMode (on|off).
  • Structured per-call override is available via sgAiWatermarkOverride and supports: mode|enabled (on|off|true|false|1|0), badgeAssetPath, position, margin, relativeSize, maxWidth, maxHeight, opacity, minWidth, minHeight, overlayAccessibilityLabel, screenReaderSuffix, screenReaderLabelEnabled.
  • Default badge asset is a high-resolution PNG (Resources/Public/Icons/ai-watermark-badge.png).
  • Watermark badge sizing uses watermarkRelativeSize and is capped by default via watermarkMaxWidth / watermarkMaxHeight (80/80); set either to 0 for no cap.
  • Accessibility suffix behavior is configurable through watermarkScreenReaderLabelEnabled and watermarkScreenReaderSuffix and keeps alt and aria-label synchronized for non-decorative images.
  • Watermark badge accessibility text (alt/aria-label) is configurable through watermarkOverlayAccessibilityLabel and supports LLL translation references.
  • watermarkScreenReaderSuffix and watermarkOverlayAccessibilityLabel both support LLL translation references.
  • Optional overlay API integration for custom ViewHelpers is documented in Docs/Developer/WatermarkOverlayApi.md.

What the HTML overlay does:

  • It appends additional markup (<span class="sgai-watermark-overlay">...) to the rendered image/picture HTML.
  • CSS positions this badge absolutely on top of the image.
  • No image pixels are changed in this mode.
  • The required CSS contract and fallback examples are documented in Docs/Developer/WatermarkOverlayApi.md.

Integrator Example (Event-Based Integration)

After generating image markup, dispatch AfterImageRenderingEvent:

$event = new \SGalinski\SgAi\Event\AfterImageRenderingEvent(
	$imageHtml,
	$file,
	[
		'width' => $width,
		'height' => $height,
		'accessibleText' => $alternative,
		'isDecorative' => $alternative === '',
		'sgAiWatermarkOverride' => [
			'mode' => 'on',
			'badgeAssetPath' => 'EXT:site_package/Resources/Public/Icons/custom-ai-badge.svg',
			'maxWidth' => 40,
			'maxHeight' => 40,
		],
	]
);
$event = $eventDispatcher->dispatch($event);
$imageHtml = $event->getImageHtml();

Integrating Into Any Renderer (Recommended)

Use your existing image rendering pipeline and dispatch SGalinski\SgAi\Event\AfterImageRenderingEvent after generating image HTML. SG AI listens to this event and applies overlay/accessibility updates.

This keeps image rendering in one place and avoids duplicate integration paths.

Implementation outline:

  1. Render your image markup (<img> or <picture>) in your own ViewHelper/renderer.
  2. Create and dispatch AfterImageRenderingEvent with:
    • the rendered HTML
    • the resolved FileInterface
    • render context (width, height, accessibleText, isDecorative, optional override keys)
  3. Return getImageHtml() from the dispatched event object.

Integrator Example (Direct Overlay API)

For rendering pipelines without events, use:

$overlayService = GeneralUtility::makeInstance(\SGalinski\SgAi\Service\AiImageWatermarkOverlayService::class);
$overlayResult = $overlayService->buildPictureOverlayResult($file, [
	'width' => $width,
	'height' => $height,
	'accessibleText' => $alternative,
	'isDecorative' => $alternative === '',
	'sgAiWatermarkOverride' => [
		'mode' => 'on',
	],
]);

$overlayMarkup = (string) ($overlayResult['overlayMarkup'] ?? '');
if ($overlayMarkup !== '') {
	$imageHtml .= $overlayMarkup;
}

Why this pattern is recommended:

  • It avoids full-page HTML middleware scanning.
  • It keeps SG AI decision logic centralized and reusable.
  • It supports per-render overrides without custom data attributes.

Required Queue Setup (2.x)

Queue processing must be active for asynchronous tasks.

Required scheduler command:

vendor/bin/typo3 sg_ai:process-queue

Recommended execution interval:

  • every 5 minutes (*/5 * * * *)

Setup options:

  1. Backend shortcut:
    • Open module group AI Assistant > Dashboard
    • Click Create scheduler task now if inactive warning is shown for the queue worker
    • Optionally create additional tasks directly there:
      • sg_ai:cleanup-queue (daily)
      • sg_ai:generate-seo-meta (nightly)
      • sg_ai:generate-alt-texts (early morning)
      • sg_ai:generate-ai-recommendations --limit=25 (weekly, can consume many credits)
  2. Manual scheduler setup:
    • Open TYPO3 Scheduler module and create Execute console commands tasks in group SGAI
    • Use the same command/interval recommendations as shown in the dashboard cards

SGAI MCP Auto-API Setup

sg_ai can automatically expose a site-scoped MCP API (sgai_mcp) via sg_apicore.

Important: there are two different MCP servers

To avoid confusion, treat these as separate integrations:

  • SGAI Cloud MCP: your existing MCP for SG AI platform functions (external to TYPO3).
  • SGAI TYPO3 MCP: the MCP auto-generated by this extension for TYPO3 content/data access.

They use different endpoints and usually different tokens. Tokens are not interchangeable.

Recommended client naming:

  • sgai for SG AI platform MCP (existing/released name)
  • sgai_typo3 for TYPO3 MCP (sgai_mcp)

Setup flow:

  1. Open AI Assistant > Dashboard
  2. In SGAI TYPO3 MCP, review the entitlement state shown in the card:
    • Included: TYPO3 MCP is available on the current SG AI subscription
    • Trial: a 14-day TYPO3 MCP trial is active
    • Upgrade required: TYPO3 MCP is not available until the SG AI account is upgraded to Silver or higher
    • Expired: previously active TYPO3 MCP access is no longer active
  3. If the card shows Upgrade required and the account is eligible, click Start 14-day TYPO3 MCP trial.
  4. Once the card shows Included or Trial, choose the target site and click Enable SGAI TYPO3 MCP
  5. Copy the one-time token shown in the modal (it is not shown again on reruns)

Canonical MCP endpoint:

  • /api/sgai_mcp/v1/mcp

Compatibility alias endpoint:

  • /sgai_mcp/mcp

Behavior:

  • v1 supports one active target site per TYPO3 instance.
  • TYPO3 MCP access is driven by the locally stored package and trial state in TYPO3.
  • TYPO3 MCP setup and runtime usage are available only when the locally stored state allows it:
    • paid access on Silver or higher, or
    • an active 14-day TYPO3 MCP trial
  • Permissions are compiled from backend group SGAI MCP (tables_select, tables_modify, non_exclude_fields).
  • Permission changes on that group trigger immediate sync; fallback sync is available via scheduler/CLI:
    • vendor/bin/typo3 sg_ai:mcp:sync
  • Fail-closed: if the managed SGAI MCP backend group is missing, compiled MCP resources are cleared until setup/sync is run again.
  • Opening the SG AI dashboard refreshes the local package snapshot from /v1/credits.
  • MCP runtime uses only the local snapshot and never performs a remote entitlement request in the request path.
  • If the local trial is expired or the last known package state is stale or not eligible, setup and runtime usage stay blocked until the dashboard refreshes the package snapshot again.

How MCP setup works internally

When you click Enable SGAI TYPO3 MCP, sg_ai performs a deterministic sync, not a one-time wizard:

  1. Resolves the selected site (or auto-selects when exactly one site exists).
  2. Creates or updates backend group SGAI MCP with default table/field permissions and DB mount.
  3. Compiles MCP resources and scopes from that group:
    • tables_select -> list,get
    • tables_modify -> create,update,delete
    • special case: sys_file stays a read-only MCP resource, but tables_modify=sys_file still compiles the write scope sgai_mcp:sys_file:write for upload tools
  4. Creates or reuses one token for API sgai_mcp and synchronizes its scopes.
  5. Persists setup state (site/group/token/resource/signature/timestamp) in TYPO3 registry.
  6. Invalidates API/discovery caches.

Repeated clicks are safe and expected:

  • If configuration changed, they resynchronize state/resources/scopes.
  • If token already exists and is reusable, it is reused (no historical plaintext token is shown again).
  • A new plaintext token is returned only when a new token record had to be created.

Dashboard behavior:

  • Before setup, the dashboard card shows one of four entitlement states:
    • Included
    • Trial
    • Upgrade required
    • Expired
  • Depending on that entitlement state, the primary action becomes:
    • Enable SGAI TYPO3 MCP
    • Start 14-day TYPO3 MCP trial
    • or a disabled setup button plus Manage plan
  • After setup, the card switches to Disable SGAI TYPO3 MCP and exposes compact TYPO3 MCP client configuration examples inline.
  • Disabling MCP hides the managed backend group, revokes the active token, clears compiled MCP state, and removes the MCP surface until setup is run again.
  • The card also shows the current plan, optional trial end timestamp, and the last successful entitlement check.

When a new token is created

A new MCP token is created only if no reusable token can be found:

  • The stored preferred token UID is missing/invalid/revoked/deleted, and
  • No active reusable token exists for api_id=sgai_mcp + selected tenant/site.

Otherwise the existing token is reused and updated (scopes, tenant, pid, label).

MCP client configuration (Codex, Cursor, Junie, ...)

sg_ai exposes a standard HTTP MCP endpoint. For Codex-style clients, configure:

  • URL: canonical /api/sgai_mcp/v1/mcp (or alias /sgai_mcp/mcp)
  • Auth: use bearer_token_env_var

Recommended: use the canonical endpoint in clients and keep alias only for backward compatibility.

Use separate environment variables for the two MCP tokens:

  • SGAI_API_TOKEN for SG AI platform MCP (existing)
  • SGAI_TYPO3_API_TOKEN for TYPO3 MCP

Example shell exports:

export SGAI_API_TOKEN="..."
export SGAI_TYPO3_API_TOKEN="..."

Example (Codex-style TOML, TYPO3 MCP only):

[mcp_servers.sgai_typo3]
bearer_token_env_var = "SGAI_TYPO3_API_TOKEN"
transport = "http"
url = "https://your-site.example/api/sgai_mcp/v1/mcp"

Example (Codex-style TOML, both MCP servers):

[mcp_servers.sgai]
bearer_token_env_var = "SGAI_API_TOKEN"
transport = "http"
url = "https://sgai.mateevsolutions.com/api/sgai/v1/mcp"

[mcp_servers.sgai_typo3]
bearer_token_env_var = "SGAI_TYPO3_API_TOKEN"
transport = "http"
url = "https://your-site.example/api/sgai_mcp/v1/mcp"

Example (JSON-style clients such as Cursor/Junie variants, TYPO3 MCP only):

{
  "mcpServers": {
    "sgai_typo3": {
      "transport": "http",
      "url": "https://your-site.example/api/sgai_mcp/v1/mcp",
      "bearer_token_env_var": "SGAI_TYPO3_API_TOKEN"
    }
  }
}

tt_content positioning for MCP clients

When creating TYPO3 content elements through sgai_typo3, the default TYPO3 behavior is position=top.

For tt_content create endpoints, the generated MCP/OpenAPI description now exposes two optional request fields:

  • position: top, bottom, or after
  • afterUid: required when position=after

Behavior:

  • top: insert at the top of the target placement context
  • bottom: insert after the last sibling in the same pid, colPos, and sys_language_uid context
  • after: insert directly after an existing tt_content record

Notes for MCP clients:

  • position defaults to top if omitted.
  • afterUid must reference an existing tt_content record.
  • If position=after and pid, colPos, or sys_language_uid are omitted, they are inherited from the referenced record.
  • For column-aware placement, pass colPos when that field is available in the resource schema.

AI image generation flow for MCP clients

sgai_typo3 now exposes one dedicated MCP tool for TYPO3 content images:

  • generate_and_attach_image_to_content
  • generate_and_attach_image_to_page

This is the preferred image workflow for MCP clients. The TYPO3 backend uses its configured SG AI API key, generates the image server-side, stores it in TYPO3 FAL, creates the sys_file_reference, and attaches it to the correct TYPO3 media field for the target record.

Recommended flow for adding an image to tt_content.image:

  1. Create the target content element.
  2. Call generate_and_attach_image_to_content in sgai_typo3.

Example tool arguments:

{
  "contentUid": 456,
  "prompt": "Editorial hero image about TYPO3 AI workflows, modern office scene, realistic, clean composition",
  "imageSize": "landscape_16_9",
  "outputFormat": "png"
}

Expected result:

{
  "contentUid": 456,
  "fileUid": 123,
  "fileReferenceUid": 987,
  "publicUrl": "/fileadmin/user_upload/ai_generated/editorial-hero-image.png",
  "altText": "Editorial hero image about TYPO3 AI workflows"
}

Notes:

  • sgai_typo3 still exposes sys_file as a read-only resource so stored files can be listed and found later.
  • The tool requires a configured SG AI API key in the TYPO3 backend.
  • It requires sgai_mcp:tt_content:write, sgai_mcp:sys_file:write, sgai_mcp:sys_file_reference:write, and sgai_mcp:sys_file_metadata:write.
  • For CType=textmedia, generate_and_attach_image_to_content writes to tt_content.assets. For standard image-based content elements, it usually writes to tt_content.image.
  • tt_content.image is a built-in non-exclude field in TYPO3, so no separate non_exclude_fields entry is required for it.
  • generate_and_attach_image_to_page works for pages.media and pages.og_image, defaults to media, and requires sgai_mcp:pages:write plus the same file-related write scopes. Because both page fields are exclude fields, the managed backend group must allow pages:media and/or pages:og_image for the targets you want to use.

Localize a page before editing translated fields

Use localize_page to create or reuse the translated page record first. Then call pages.update on the returned localizedPageUid.

Example flow:

  1. localize_page with:
    {
      "pageUid": 123,
      "languageUid": 1
    }
    
  2. pages.update on the returned localized page UID with translated fields such as title, slug, description, or seo_title.

Filtering examples for MCP clients

List endpoints use the filter shape filter[field]=value.

Typical pages examples:

{
  "filter": {
    "title": "News"
  }
}
{
  "filter": {
    "slug": "/news"
  }
}

Do not send title or slug as top-level arguments for list tools. They must be nested inside filter.

Client notes:

  • Keep tokens in environment variables or client secret storage. Do not hardcode credentials in VCS.
  • If you rotate/revoke token records in TYPO3, update client configs with the new token.
  • Effective tool/resource exposure is driven by the SGAI MCP backend group's permissions and token scopes.

Backend Usage

Modules

  • AI Assistant (/module/web/ai-assistant)
    • Backend module group for SG AI workflows
  • Dashboard (/module/web/sg-ai-dashboard)
    • Overview for all SG AI modules, onboarding checklist, scheduler status/setup
  • AI Page Insights (/module/web/sg-ai)
    • Unified workspace for analysis and history (tabs in one module)
    • Run URL checks, trigger recommendation tasks, monitor active queue work, and inspect/reuse past results
  • Legacy AI History URL (/module/web/sg-ai-history)
    • Redirects to the unified AI Page Insights history tab for backward compatibility

Field Controls

Depending on TCA configuration and field type, backend forms can show:

  • Generate alt text button
  • Generate image button
  • Generate text button
  • Generate SEO title/description buttons
  • Generate technical/content/a11y recommendation buttons

Generated images are marked as AI-generated in TYPO3 metadata/reference flags (tx_sgai_is_ai_generated) and receive automatic alt text handling. If the SG AI image response provides provenance/generation metadata, sg_ai preserves it for generated originals by mapping values into sys_file_metadata (for example creator, creator_tool, source, copyright, description, title). Additionally, sg_ai writes AI provenance markers for generated originals:

  • IPTC/XMP Digital Source Type (trainedAlgorithmicMedia URI)
  • AI system fields (system name/version and model name) when provided by the API response
  • A normalized provenance summary in TYPO3 sys_file_metadata.note

For processed image variants, SG AI can add this provenance metadata within TYPO3's processing command (watermarkPreserveMetadataOnProcessing, default 1). Metadata persistence in image binaries depends on file format and ImageMagick/GraphicsMagick capabilities. In practice, PNG/JPEG usually keep more metadata than WEBP in many environments. SG AI still attempts metadata embedding for all processed target formats as best effort.

EU AI Act transparency support is declared at extension metadata level (ext_emconf.php and composer.json), not as an image-embedded compliance statement.

EU AI Act (Pragmatic Note)

This extension provides technical support for transparency workflows:

  • AI-generated image marking (tx_sgai_is_ai_generated)
  • Optional visual watermark overlays in frontend output
  • Accessible label suffixes for non-decorative AI images
  • Provenance metadata best effort during image processing
  • Prompt/result traces in TYPO3 data structures for editorial review
  • AI-generated text/recommendation outputs are persisted in TYPO3 records and queue/history tables for review before publication

Integrators are responsible for deciding where and when labels/disclosures are shown, based on their legal and organizational requirements. This extension does not provide legal advice.

Not Yet Added: C2PA Manifest Signing

sg_ai does not yet add a C2PA manifest to generated images.

What this would provide:

  • A cryptographically signed provenance manifest embedded in or bound to the image
  • Verifiable claim of origin and transformation chain (tamper-evident)
  • Stronger interoperability with Content Credentials / C2PA-aware verification tools

Why this is separate from ordinary metadata:

  • XMP/IPTC fields are editable metadata and are not cryptographically protected by default
  • C2PA requires a signing pipeline (private key management, certificates, manifest generation, and signature validation strategy)
  • Operationally this introduces trust infrastructure and key-rotation requirements that must be configured per environment

Planned scope for a future implementation:

  • Optional C2PA signer integration (disabled by default)
  • Configurable key/certificate handling and signer identity
  • Fail-safe behavior (image generation still succeeds if signing is unavailable, with explicit logging)

Queue and History Behavior

  • Long-running tasks are enqueued and processed asynchronously.
  • Queue records are persisted in tx_sgai_queue.
  • Results/history are persisted in tx_sgai_url_check.
  • Remote background processing (HTTP 202/message ID) is supported and finalized via queue polling.
  • Queue entries store cloud tracking metadata (remote_message_id, remote_status) for remote runs.
  • History views support search, sorting, pagination, and result preview via View action.
  • If the cloud API rate limits (HTTP 429), processing is deferred and retried safely.

Image Generation Behavior

  • The last image prompt is persisted and reused per record/field (tx_sgai_last_image_prompt).
  • Prompt persistence keeps the image settings comment block, including image_size and output_format.
  • Generated images are automatically marked as AI-generated (tx_sgai_is_ai_generated).
  • AI-generated images can be watermarked automatically during rendering based on extension configuration.
  • Generated images can be renamed from alt text to SEO-friendly slugs.
  • Renamed files are capped at 60 characters total (including hash suffix and extension).

TCA Configuration Example (AI Image Generation)

'images' => [
	'config' => [
		'sg_ai' => [
			'promptProvider' => 'Vendor\\Extension\\PromptProvider\\CustomPromptProvider',
			'promptTemplate' => 'Generate an image for ###title### with ###category### theme',
			'disabled' => true,
			'image_size' => 'landscape_16_9',
			'output_format' => 'png',
		],
		'type' => 'file',
	],
],

Supported image size presets:

  • square_hd
  • square
  • portrait_4_3
  • portrait_16_9
  • landscape_4_3
  • landscape_16_9

You can also pass custom dimensions:

  • ['width' => 1280, 'height' => 720]

CLI Commands

Alt text generation

vendor/bin/typo3 sg_ai:generate-alt-texts

Options:

  • --limit
  • --dry-run

SEO meta generation

vendor/bin/typo3 sg_ai:generate-seo-meta [page-uid]

Options include:

  • --force
  • --title-only
  • --description-only
  • --limit
  • --exclude-hidden
  • --exclude-deleted

AI recommendations generation

vendor/bin/typo3 sg_ai:generate-ai-recommendations [page-uid]

Options include:

  • --force
  • --accessibility-only
  • --content-seo-only
  • --technical-seo-only
  • --limit
  • --exclude-hidden
  • --exclude-deleted

Queue operations

Process queue:

vendor/bin/typo3 sg_ai:process-queue

List queue:

vendor/bin/typo3 sg_ai:list-queue

Cleanup queue/results:

vendor/bin/typo3 sg_ai:cleanup-queue

Troubleshooting

  • Tasks stay pending:
    • verify scheduler task exists and is enabled
    • run one manual queue cycle: vendor/bin/typo3 sg_ai:process-queue --limit=5
  • API key error:
    • check SG_AI_API_KEY / extension configuration
  • URL/page checks fail:
    • ensure target pages are publicly reachable for checks that require rendered output

Testing

Run extension checks from the project root:

composer phpunit vendor/sgalinski/sg-ai
composer phpstan vendor/sgalinski/sg-ai
composer ecs vendor/sgalinski/sg-ai