Your first program
Let’s create a simple program that queries system information using the Draconis++ library.
Create a new project directory
mkdir draconis-demo
cd draconis-demo
Create main.cpp
Create a file called main.cpp with the following code: #include <print>
#include <Drac++/Core/System.hpp>
#include <Drac++/Utils/CacheManager.hpp>
using namespace draconis :: core :: system ;
using namespace draconis :: utils :: cache ;
using namespace draconis :: utils :: types ;
int main () {
// Create a cache manager for improved performance
CacheManager cache;
// Get operating system information
Result < OSInfo > osInfo = GetOperatingSystem (cache);
if (osInfo) {
std :: println ( "OS: {} {}" , osInfo -> name , osInfo -> version );
} else {
std :: println ( "Failed to get OS info: {}" , osInfo . error (). message );
}
// Get kernel version
Result < String > kernel = GetKernelVersion (cache);
if (kernel) {
std :: println ( "Kernel: {}" , * kernel);
}
// Get CPU information
Result < String > cpu = GetCPUModel (cache);
if (cpu) {
std :: println ( "CPU: {}" , * cpu);
}
// Get memory usage
Result < ResourceUsage > memory = GetMemInfo (cache);
if (memory) {
double usedGB = BytesToGiB ( memory -> usedBytes );
double totalGB = BytesToGiB ( memory -> totalBytes );
std :: println ( "Memory: {:.2f} GiB / {:.2f} GiB" , usedGB, totalGB);
}
// Get disk usage
Result < ResourceUsage > disk = GetDiskUsage (cache);
if (disk) {
double usedGB = BytesToGiB ( disk -> usedBytes );
double totalGB = BytesToGiB ( disk -> totalBytes );
std :: println ( "Disk: {:.2f} GiB / {:.2f} GiB" , usedGB, totalGB);
}
return 0 ;
}
This program demonstrates:
Creating a CacheManager to avoid redundant system queries
Using Result<T> for type-safe error handling
Querying OS, kernel, CPU, memory, and disk information
Converting bytes to human-readable GiB format
Create meson.build
project('draconis-demo', 'cpp',
version: '0.1.0',
default_options: ['cpp_std=c++26']
)
# Find the Draconis++ dependency
draconis_dep = dependency('draconis++', required: true)
# Build the executable
executable('demo',
'main.cpp',
dependencies: [draconis_dep]
)
Build and run
meson setup build
meson compile -C build
./build/demo
Expected output: OS: Ubuntu 24.04.2 LTS
Kernel: 6.8.0-51-generic
CPU: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Memory: 8.42 GiB / 15.52 GiB
Disk: 145.23 GiB / 512.00 GiB
Understanding Result types
Draconis++ uses Result<T> for error handling instead of exceptions. This provides compile-time safety and explicit error handling.
Checking for success
Using has_value()
Pattern matching (C++26)
Result < String > cpu = GetCPUModel (cache);
if (cpu) {
// Success - dereference with *
std :: println ( "CPU: {}" , * cpu);
} else {
// Error - access error details
std :: println ( "Error: {}" , cpu . error (). message );
std :: println ( "Code: {}" , magic_enum :: enum_name ( cpu . error (). code ));
}
Available system queries
The draconis::core::system namespace provides these functions:
Function Return Type Description GetOperatingSystem(cache)Result<OSInfo>OS name and version GetKernelVersion(cache)Result<String>Kernel/NT version GetHost(cache)Result<String>Hostname/computer model GetShell(cache)Result<String>Current shell GetDesktopEnvironment(cache)Result<String>Desktop environment (KDE, GNOME, etc.) GetWindowManager(cache)Result<String>Window manager/compositor GetCPUModel(cache)Result<String>CPU model name GetCPUCores(cache)Result<CPUCores>Physical and logical core counts GetGPUModel(cache)Result<String>Primary GPU model GetMemInfo(cache)Result<ResourceUsage>Memory usage (used/total bytes) GetDiskUsage(cache)Result<ResourceUsage>Disk usage (used/total bytes) GetNetworkInterfaces(cache)Result<Vec<NetworkInterface>>All network interfaces GetPrimaryNetworkInterface(cache)Result<NetworkInterface>Primary network interface GetOutputs(cache)Result<Vec<DisplayInfo>>All displays GetPrimaryOutput(cache)Result<DisplayInfo>Primary display GetUptime()Result<std::chrono::seconds>System uptime
See the API Reference for complete details.
Using the cache manager
The CacheManager caches system query results to improve performance when repeatedly accessing the same information.
// Create once, reuse for multiple queries
CacheManager cache;
// First call queries the system
Result < String > cpu1 = GetCPUModel (cache);
// Second call returns cached result (no system query)
Result < String > cpu2 = GetCPUModel (cache);
// Invalidate cache for a specific key
cache . invalidate ( "cpu_model" );
// Clear all cached data
cache . invalidateAll ();
Running the example servers
Draconis++ includes two example applications in the source tree:
HTTP server example
Serves system information via HTTP using the Glaze HTTP library.
cd draconis++
meson setup build -Dbuild_examples=true
meson compile -C build
./build/examples/glaze_http/glaze_http
Open http://localhost:3722 in your browser to see a formatted system info page.
Key features:
Mustache templating with glz::stencil
JSON serialization via Glaze
Async HTTP server with ASIO
Custom CSS styling
MCP server example
The MCP (Model Context Protocol) server exposes Draconis++ as stdio-based tools for AI assistants.
./build/examples/mcp_server/mcp_server
Available MCP tools:
system_info - Get OS, kernel, shell, desktop environment
hardware_info - Get CPU, GPU, memory, disk info
network_info - Get network interface details
display_info - Get display/monitor information
package_count - Count installed packages by manager
uptime - Get system uptime
comprehensive_info - Get all info in one call
cache_clear - Clear the cache
Integrate with MCP clients (Claude Desktop, etc.) by configuring the stdio transport.
Next steps
API reference Explore all available functions and data types
Configuration Learn how to configure build options and precompiled settings
Plugin development Extend Draconis++ with custom plugins
Examples See complete example applications
Common patterns
Handling multiple queries efficiently
#include <Drac++/Core/System.hpp>
#include <Drac++/Utils/CacheManager.hpp>
using namespace draconis :: core :: system ;
using namespace draconis :: utils :: cache ;
void displaySystemInfo () {
CacheManager cache;
// Query multiple items with one cache instance
auto os = GetOperatingSystem (cache);
auto kernel = GetKernelVersion (cache);
auto cpu = GetCPUModel (cache);
auto mem = GetMemInfo (cache);
// Handle each result
if (os) std :: println ( "OS: {} {}" , os -> name , os -> version );
if (kernel) std :: println ( "Kernel: {}" , * kernel);
if (cpu) std :: println ( "CPU: {}" , * cpu);
if (mem) {
std :: println ( "Memory: {:.2f} GiB / {:.2f} GiB" ,
BytesToGiB ( mem -> usedBytes ),
BytesToGiB ( mem -> totalBytes )
);
}
}
Checking package counts (Linux/macOS)
#include <Drac++/Services/Packages.hpp>
using namespace draconis :: services :: packages ;
#if DRAC_ENABLE_PACKAGECOUNT
void showPackages () {
CacheManager cache;
// Query specific package managers
Manager enabled = Manager ::Pacman | Manager ::Cargo | Manager ::Nix;
Result < Map < String, u64 >> counts = GetIndividualCounts (cache, enabled);
if (counts) {
for ( const auto & [manager, count] : * counts) {
std :: println ( "{}: {} packages" , manager, count);
}
}
}
#endif
void showNetworkInfo () {
CacheManager cache;
// Get all interfaces
Result < Vec < NetworkInterface >> interfaces = GetNetworkInterfaces (cache);
if (interfaces) {
for ( const auto & iface : * interfaces) {
std :: println ( "Interface: {}" , iface . name );
std :: println ( " IP: {}" , iface . ipAddress );
std :: println ( " MAC: {}" , iface . macAddress );
}
}
// Get primary interface only
Result < NetworkInterface > primary = GetPrimaryNetworkInterface (cache);
if (primary) {
std :: println ( "Primary: {} ({})" , primary -> name , primary -> ipAddress );
}
}
View full example code Check out the complete HTTP and MCP server examples on GitHub