Extend Siemserva

Your data, your reports, your workflow. Pipe findings from any source into Siemserva's Senserva Trustworthy AI reporting engine, create custom report templates with validation rules, query the SQLite graph database from C#, Python, or PowerShell, and integrate with your SIEM, SOAR, or CI/CD pipeline.

One command. Full SDK.
$ siemserva-win-x64.exe --sdk

Drops the full SDK: API reference, C# / Python / PowerShell samples, and the Senserva JSON wire format.

Build on Siemserva

Query the security graph database, pipe findings to your SIEM, write connectors for third-party tools, and automate Senserva Trustworthy AI-enhanced reporting, all from C#, Python, or PowerShell.

Senserva Security API

Every scan builds a comprehensive security database of your Microsoft 365, Intune, and Entra ID environment. Query findings, entities, relationships, and compliance status from C#, Python, or PowerShell to build custom dashboards, CI/CD quality gates, blast radius analysis, and executive reports.

Composable Pipeline

Split scanning from reporting with --scan and --reporter. Pipe findings to your SIEM, filter with jq, merge multiple tenants, or feed any Senserva JSON source into the full Senserva Trustworthy AI-enhanced dashboard and report engine.

Third-Party Connectors

Already using Maester, Nessus, custom scripts, or other scanners? Write a connector that outputs Senserva JSON or writes directly through the SDK, and get all 6 Senserva Trustworthy AI-enhanced reports, compliance mapping, and the interactive dashboard, without writing any report code.

The end of Click-Ops security.

Claude MCP Integration

Stop clicking through dashboards. Start having conversations.

Connect Siemserva to Claude and query your Microsoft 365 and Entra ID security posture in plain English. One command wires Siemserva into Claude as an MCP server, auto-discovers your scan databases, and writes a ready-to-use config.

Claude Code CLI

Terminal-based Claude for developers. Works on Windows, macOS, and Linux.

1. Install
# Writes .mcp.json + .claude/CLAUDE.md in the current folder
siemserva-win-x64.exe --accept-eula --claude cli-install
2. Use
# Launch Claude Code in the same folder
claude

# Then just ask, in plain English
> what are the critical findings?
> show me users with privileged roles and no MFA
> generate a remediation script for finding #12
What the installer does:
  • Writes .mcp.json in the current directory
  • Writes .claude/CLAUDE.md so Claude knows how to use Siemserva
  • Auto-discovers scan databases and wires --reporter-db args
  • Scoped to this folder only, no global install

Claude Desktop

GUI Claude for security managers and analysts. Supported on Windows and macOS.

1. Install
# Writes claude_desktop_config.json in the right place
siemserva-win-x64.exe --accept-eula --claude mcp-install
2. Use
# Restart Claude Desktop, then ask
> give me a board-ready summary of the latest scan
> which findings block SCuBA compliance?
> draft a remediation plan for our top 5 risks
What the installer does:
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • macOS: ~/Library/Application Support/Claude/
  • Auto-discovers scan databases and wires --reporter-db args
  • On Linux, use the Claude Code CLI option instead

Point Claude at a specific database

Re-run the installer from the folder that holds the scan you want Claude to focus on. Siemserva picks up every .sqlite in that folder automatically. To pin exactly one, pass it as a flag:

# Wire a specific database into the generated config
siemserva-win-x64.exe --accept-eula --claude cli-install --reporter-db .\scans\zava.sqlite

How the Pipeline Works

Siemserva splits into two composable halves. Scan in one terminal, report in another. Filter, transform, and merge in between.

siemserva-win-x64.exe --scan  produces Senserva JSON
        |
  your filter / transform / merge
        |
siemserva-win-x64.exe --reader --pipe  forwards to reporter
        |
siemserva-win-x64.exe --reporter --pipe  consumes Senserva JSON
        |
  6 Senserva Trustworthy AI-enhanced HTML reports
  Interactive TUI dashboard
  PowerShell remediation scripts

Any tool that outputs Senserva JSON can feed the reporter. Your custom scripts, Maester, Nessus, or any scanner, all get the same Senserva Trustworthy AI-enhanced analysis and compliance mapping.

Senserva JSON Format

One JSON format connects everything. Any tool that outputs Senserva JSON gets full access to Siemserva's Senserva Trustworthy AI, reports, compliance mapping, and remediation.

Finding line

{
  "type": "finding",
  "data": {
    "tenantId": "zava.com",
    "tenantName": "Zava",
    "severity": 100,
    "description": "MFA not enforced",
    "systemName": "admin@zava.com"
  }
}

One JSON object per line. Each line is a security finding with severity, description, and the affected entity.

Completion marker

{
  "type": "complete",
  "scanId": "a1b2c3d4...",
  "findingCount": 73,
  "errorCount": 0,
  "tenantIds": [
    "zava.com"
  ]
}

One completion marker at the end of each stream. Tells the reporter that all findings have been sent.

How it works

  • 1.Your script or connector outputs one finding per line as JSON
  • 2.Send a completion marker when done so the reporter knows the stream is finished
  • 3.Pipe to siemserva-win-x64.exe --reporter for HTML reports, or --reporter --dashboard for the live TUI
  • 4.Siemserva handles everything else: Senserva Trustworthy AI analysis, compliance mapping, severity grouping, remediation scripts, and all six report types

Severity levels: 100 Critical, 75 High, 50 Medium, 25 Low, 10 Info. Additional fields for entity IDs, audit grouping, timestamps, and custom data are documented in the full SDK. Install Siemserva and run siemserva-win-x64.exe --sdk to get the complete field reference, data types, and working sample scripts.

Integrations

Three working connectors ship with Siemserva as samples. Use them as-is, adapt them for other tools, or write your own from scratch. Each connector shows a different ingestion pattern: Senserva JSON (Maester, Zero Trust Assessment) for findings that belong in the unified dashboard with Senserva Trustworthy AI analysis and compliance mapping, or direct SDK writes (Nessus) to populate patch and CVE graph data for MCP tool queries.

Maester Connector Sample

Converts Maester M365 security test results to Senserva JSON. Every failed Maester test appears in the Siemserva dashboard with Senserva Trustworthy AI analysis, remediation guidance, and compliance mapping. Use as a working sample for building your own connectors.

Zero Trust Assessment Connector Sample

Converts Microsoft Zero Trust Assessment results to Senserva JSON. View Zero Trust maturity findings alongside your Siemserva scan in one unified dashboard with Senserva Trustworthy AI-enhanced reporting and remediation. Another working sample for building custom connectors.

Nessus Importer Sample

Parses a Tenable Nessus .nessus XML export and writes findings into a Siemserva database via the SDK. Creates dashboard-visible audit rows plus graph nodes and edges (Node_Patch, Node_Cve, Edge_DeviceMissingPatch, Edge_CvePatch) tagged Source="Nessus" so they filter separately from native scans. Source: Senserva.Sdk/Samples/CSharp/ImportNessusScan.cs.

Universal Converter: ConvertTo-SiemservaNdjson.ps1

One script handles all supported input formats. Auto-detects whether the input is Maester, ScubaGear, Zero Trust Assessment, or generic JSON, converts it to Siemserva NDJSON, and pipes it into the reporting engine. PowerShell 5.1+ compatible (works on Windows, Linux, macOS).

Supported Formats

Maester
Pester-based M365 security tests. Reads Maester JSON output with test results, tags, and severity.
ScubaGear
CISA SCuBA baseline evaluator. Maps Shall/Should criticality to severity and preserves PolicyId codes.
Zero Trust Assessment
Microsoft's Invoke-ZtAssessment output. Maps TestRisk/TestImpact to severity, preserves pillar and category tags.
Generic JSON
Any JSON array with Severity/Name/Description fields. Flexible field name matching for custom tools.

Quick Start Commands

# Get the converter (included with siemserva-win-x64.exe --sdk)
siemserva-win-x64.exe --sdk

# ── Headless reports (no dashboard, single command) ──

# Convert Maester results and generate all reports
.\Sdk\ConvertTo-SiemservaNdjson.ps1 -Path MaesterResults.json -Stdout | siemserva-win-x64.exe --reporter

# Convert ScubaGear consolidated results
.\Sdk\ConvertTo-SiemservaNdjson.ps1 -Path ScubaResults.json -Stdout | siemserva-win-x64.exe --reporter

# Force a specific format (skip auto-detection)
.\Sdk\ConvertTo-SiemservaNdjson.ps1 -Path results.json -Format Generic -Stdout | siemserva-win-x64.exe --reporter

# ── Interactive dashboard (two terminals, named pipe) ──
# The dashboard needs stdin for keyboard input, so data flows
# through a named pipe instead of stdin.

# Terminal 1: start the dashboard listening on a named pipe
siemserva-win-x64.exe --reporter --reporter-dashboard --pipe my-scan

# Terminal 2: convert and stream into the pipe
.\Sdk\ConvertTo-SiemservaNdjson.ps1 -Path MaesterResults.json -Stdout | siemserva-win-x64.exe --reader --pipe my-scan

# Same pattern for Zero Trust Assessment
.\Sdk\ConvertTo-SiemservaNdjson.ps1 -Path ZeroTrustAssessment.json -Stdout | siemserva-win-x64.exe --reader --pipe my-scan

# Pipe Maester output directly (no intermediate file)
Invoke-Maester -PassThru | ConvertTo-Json -Depth 10 | .\Sdk\ConvertTo-SiemservaNdjson.ps1 -Stdout | siemserva-win-x64.exe --reader --pipe my-scan

# ── Options ──

# Override tenant info
.\Sdk\ConvertTo-SiemservaNdjson.ps1 -Path results.json -TenantId zava.com -TenantName "Zava" -Stdout | siemserva-win-x64.exe --reporter

# Include passed tests as Info-severity findings
.\Sdk\ConvertTo-SiemservaNdjson.ps1 -Path MaesterResults.json -IncludePassed -Stdout | siemserva-win-x64.exe --reporter

# Convert to a file (for later use or sharing)
.\Sdk\ConvertTo-SiemservaNdjson.ps1 -Path MaesterResults.json

Parameters

-Path Input JSON file. Omit to read from stdin (pipe).
-OutputPath Output NDJSON file path. Default: auto-generated (e.g., Siemserva_Maester_20260406.json).
-Stdout Write NDJSON to stdout instead of a file. Required when piping to siemserva-win-x64.exe --reporter.
-Format Force input format: Auto (default), Maester, ScubaGear, ZeroTrust, Generic.
-IncludePassed Include passed/compliant tests as Info-severity findings. Off by default.
-IncludeSkipped Include skipped/not-implemented tests as Info-severity findings. Off by default.
-TenantId Override tenant ID on all findings.
-TenantName Override tenant display name on all findings.

Auto-detection: The converter examines the JSON structure to determine the format. Maester files have MaesterConfig or PesterConfig keys. ScubaGear has MetaData.ProductsAssessed. Zero Trust has TestResultSummary with pillar scores. Everything else falls back to Generic.

After converting: Open the dashboard, press R to generate reports, then A for Senserva Trustworthy AI-enhanced analysis, or press Enter on any finding for remediation details.

Build Your Own

Two paths to bring any data source into Siemserva:

Write New Scripts

Write scripts that output Senserva JSON directly. PowerShell, Python, C#, or any language. Your custom security checks get the same Senserva Trustworthy AI analysis, compliance mapping, and six report types as a native Siemserva scan.

Write an Importer

Already have scripts or a scanner that outputs its own format? Write an importer that converts the output to Senserva JSON, or writes directly through the SDK for richer graph data. The Maester, Zero Trust, and Nessus connectors are working examples of these patterns.

SIEM & SOAR

Pipe scan output directly to Splunk, Sentinel, Elastic, or any SIEM that ingests JSON. Filter for the severities you care about.

CI/CD Quality Gates

Query the scan database in your pipeline. Fail the build if Critical or High findings exceed your threshold. No dashboard needed, just a script and an exit code.

Named Pipe IPC

Use --pipe for real-time streaming to the dashboard. Multiple scanners and connectors can write to the same pipe simultaneously. The --reader command bridges filtered stdin into the pipe.

Siemserva as your tool chain hub

Your scripts, your runbooks, one hub.

You already have PowerShell, Graph queries, Intune remediations, scheduled jobs. Keep them. Siemserva becomes the center point that runs them, reasons over them, reports on them, and fixes what they find.

Want your scripts driven by Claude? See how MCP turns them into conversational tools.

Optional

Pre-create the app registration.

SDK users who automate Siemserva from scripts or CI often want the app registration created up front with the read-only Graph scopes Siemserva needs. Run this PowerShell script once to create a multi-tenant "Siemserva Application," add the public-client redirect URIs, and print the launch command to paste.

SiemservaAppRegistrationSetupScript.ps1 Show script
View source on GitHub
####################################

# Senserva Siemserva App Registration Setup Script
# Copyright 2026 Senserva, LLC
# Author: Thomas (TJ) Dolan

####################################

# Install Microsoft Graph Module, this piece can take a minute. Can omit if you have the module already
Install-Module Microsoft.Graph

Connect-MgGraph -Scopes "Domain.Read.All, Application.ReadWrite.All"

$TenantId = (Get-MgOrganization).Id

# Create the App Registration properties

# Necessary API Permissions

$requiredGrants = New-Object -TypeName System.Collections.Generic.List[Microsoft.Graph.PowerShell.Models.MicrosoftGraphRequiredResourceAccess]
$requiredGraphResourceAccess = New-Object -TypeName Microsoft.Graph.PowerShell.Models.MicrosoftGraphRequiredResourceAccess
$requiredGraphResourceAccess.ResourceAppId = "00000003-0000-0000-c000-000000000000"
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "e4c9e354-4dc5-45b8-9e7c-e1393b0b1a20"; Type = "Scope" } # AuditLog.Read.All
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "f1493658-876a-4c87-8fa7-edb559b3476a"; Type = "Scope" } # DeviceManagementConfiguration.Read.All
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "314874da-47d6-4978-88dc-cf0d37f0bb82"; Type = "Scope" } # DeviceManagementManagedDevices.Read.All
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "49f0cc30-024c-4dfd-ab3e-82e137ee5431"; Type = "Scope" } # DeviceManagementRBAC.Read.All
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "0e263e50-5827-48a4-b97c-d940288653c7"; Type = "Scope" } # Directory.AccessAsUser.All
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "06da0dbc-49e2-44d2-8312-53f166ab848a"; Type = "Scope" } # Directory.Read.All
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "5f8c59db-677d-491f-a6b8-5f174b11ec1d"; Type = "Scope" } # Group.Read.All
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "bc024368-1153-4739-b217-4326f2e966d0"; Type = "Scope" } # GroupMember.Read.All
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "8f6a01e7-0391-4ee5-aa22-a3af122cef27"; Type = "Scope" } # IdentityRiskEvent.Read.All
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "ea5c4ab0-5a73-4f35-8272-5d5337884e5d"; Type = "Scope" } # IdentityRiskyServicePrincipal.Read.All
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "d04bb851-cb7c-4146-97c7-ca3e71baf56c"; Type = "Scope" } # IdentityRiskyUser.Read.All
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "7427e0e9-2fba-42fe-b0c0-848c9e6a8182"; Type = "Scope" } # offline_access
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "37f7f235-527c-4136-accd-4a02-d197296e"; Type = "Scope" } # openid
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "572fea84-0151-49b2-9301-11cb16974376"; Type = "Scope" } # Policy.Read.All
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "a6ff13ac-1851-4993-8ca9-a671d70de2d5"; Type = "Scope" } # Policy.Read.AuthenticationMethod
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "633e0fce-8c58-4cfb-9495-12bbd5a24f7c"; Type = "Scope" } # Policy.Read.ConditionalAccess
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "14dad69e-099b-42c9-810b-d002981feec1"; Type = "Scope" } # profile
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "02e97553-ed7b-43d0-ab3c-f8bace0d040c"; Type = "Scope" } # Reports.Read.All
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "48fec646-b2ba-4019-8681-8eb31435aded"; Type = "Scope" } # RoleManagement.Read.All
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "cce71173-f76d-446e-97ff-efb2d82e11b1"; Type = "Scope" } # RoleManagementAlert.Read.Directory
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "7e26fdff-9cb1-4e56-bede-211fe0e420e8"; Type = "Scope" } # RoleManagementPolicy.Read.AzureADGroup
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "2ef70e10-5bfd-4ede-a5f6-67720500b258"; Type = "Scope" } # SharePointTenantSettings.Read.All
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "205e70e5-aba6-4c52-a976-6d2d46c48043"; Type = "Scope" } # Sites.Read.All
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d"; Type = "Scope" } # User.Read
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "a154be20-db9c-4678-8ab7-66f6cc099a59"; Type = "Scope" } # User.Read.All
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "1f6b61c5-2f65-4135-9c9f-31c0f8d32b52"; Type = "Scope" } # UserAuthenticationMethod.Read
$requiredGraphResourceAccess.ResourceAccess += @{ Id = "aec28ec7-4d02-4e8c-b864-50163aea77eb"; Type = "Scope" } # UserAuthenticationMethod.Read.All

$requiredGrants.Add($requiredGraphResourceAccess)

# Create the App registration, use MultipleOrgs so can be multi-tenant scan if desired
$app = New-MgApplication -DisplayName 'Siemserva Application' -RequiredResourceAccess $requiredGrants -SignInAudience "AzureADMultipleOrgs"


# Public Client Redirect, Needed to finish the Consent process
# Patch in after App Registration creation, we need the GUID from the Id property to properly construct the URI

$publicClient = New-Object -TypeName Microsoft.Graph.PowerShell.Models.MicrosoftGraphPublicClientApplication
$publicClient.RedirectUris = @("https://login.microsoftonline.com/common/oauth2/nativeclient", "ms-appx-web://microsoft.aad.brokerplugin/$($app.AppId)")

Update-MgApplication -ApplicationId $($app.Id) -PublicClient $publicClient

Write-Host "Siemserva App Registration Complete!"
Write-Host "You can use this App Registration with the Siemserva Executable with the following command:"
Write-Host "./Siemserva.exe --eula-approved true --tenantids $($app.TenantId) --client WamLogin --clientid $($app.AppId) --interactive-login false"

Get the Full SDK

Register on the Microsoft Marketplace and we will email you a login location for the signed binaries. Then run siemserva-win-x64.exe --sdk to get the complete SDK documentation, API reference, sample scripts in C#, Python, and PowerShell, and the full Senserva JSON wire format specification. Every build is digitally signed: Notarized for macOS, Azure Artifact Signed for Windows.

Free for up to 100 users. Free unlimited for non-profits, MVPs, and MISA members.

From the blog

Reading from the Senserva team.