IPC API
TwiLite exposes a local Windows named-pipe IPC API for external tools that need to inspect or control running clients.
Each client instance owns a separate named pipe. This avoids a shared discovery file being overwritten when many clients are running.
Discovery
Enumerate Windows named pipes under:
\\.\pipe\
TwiLite IPC pipe names start with:
twilite-ipc-
The full pipe path looks like:
\\.\pipe\twilite-ipc-12345-550e8400-e29b-41d4-a716-446655440000
The number after twilite-ipc- is the process id. The suffix is the client instance id.
Authentication
The IPC token is stored in:
%USERPROFILE%\twilite\secrets\ipc-token.properties
Every request must include the token in the JSON body:
{
"token": "<token>",
"command": "health"
}
Request Format
The pipe protocol is one JSON request and one JSON response per connection.
Open the named pipe, write a UTF-8 JSON object, read the UTF-8 JSON response, then close the pipe.
All requests use:
{
"token": "<token>",
"command": "<command>"
}
All successful responses include:
{
"ok": true,
"sentAt": "2026-05-27T21:00:00Z"
}
Errors use:
{
"ok": false,
"code": "unauthorized",
"message": "Missing or invalid IPC token.",
"sentAt": "2026-05-27T21:00:00Z"
}
Health
Command:
{
"token": "<token>",
"command": "health"
}
Returns:
{
"ok": true,
"version": 1,
"instanceId": "550e8400-e29b-41d4-a716-446655440000",
"pid": 12345,
"pipe": "\\\\.\\pipe\\twilite-ipc-12345-550e8400-e29b-41d4-a716-446655440000"
}
List Plugins
Command:
{
"token": "<token>",
"command": "plugins"
}
Returns all loaded plugins with source and active state.
{
"ok": true,
"plugins": [
{
"id": "marketplace:auto-gauntlet",
"name": "Auto Gauntlet",
"source": "Marketplace",
"active": true,
"configName": "marketplace:auto-gauntlet:autoGauntlet"
}
]
}
Use id for unambiguous plugin control.
Active Sessions
Command:
{
"token": "<token>",
"command": "sessions"
}
Returns active/running plugins only.
{
"ok": true,
"sessions": [
{
"id": "local:com.example.ExamplePlugin",
"name": "Example",
"source": "Local",
"active": true
}
]
}
Start Plugin
Command:
{
"token": "<token>",
"command": "startPlugin",
"id": "marketplace:auto-gauntlet"
}
You can also use a display name and optional source:
{
"token": "<token>",
"command": "startPlugin",
"plugin": "Auto Gauntlet",
"source": "marketplace"
}
Starting a plugin reloads local and marketplace plugin jars first. This supports replacing plugin code and then restarting it through IPC.
Returns:
{
"ok": true,
"changed": true,
"action": "start",
"plugin": "marketplace:auto-gauntlet",
"source": ""
}
Stop Plugin
Command:
{
"token": "<token>",
"command": "stopPlugin",
"id": "marketplace:auto-gauntlet"
}
Returns the same shape as start, with "action": "stop".
Player State
Command:
{
"token": "<token>",
"command": "player"
}
Returns the current local player snapshot.
{
"ok": true,
"loggedIn": true,
"world": 301,
"name": "player",
"coord": {
"x": 3200,
"y": 3200,
"floor": 0
},
"stats": [
{
"name": "ATTACK",
"base": 99,
"experience": 13034431
}
]
}
PowerShell Example
$tokenProps = Get-Content "$env:USERPROFILE\twilite\secrets\ipc-token.properties"
$token = ($tokenProps | Where-Object { $_ -like 'token=*' }) -replace '^token=', ''
$pipe = [System.IO.Directory]::GetFiles('\\.\pipe\') |
Where-Object { [System.IO.Path]::GetFileName($_).StartsWith('twilite-ipc-') } |
Select-Object -First 1
$client = [System.IO.Pipes.NamedPipeClientStream]::new(
'.',
[System.IO.Path]::GetFileName($pipe),
[System.IO.Pipes.PipeDirection]::InOut
)
$client.Connect(2000)
$request = @{ token = $token; command = 'sessions' } | ConvertTo-Json -Compress
$bytes = [System.Text.Encoding]::UTF8.GetBytes($request)
$client.Write($bytes, 0, $bytes.Length)
$client.Flush()
$buffer = New-Object byte[] 1048576
$read = $client.Read($buffer, 0, $buffer.Length)
$response = [System.Text.Encoding]::UTF8.GetString($buffer, 0, $read)
$client.Dispose()
$response | ConvertFrom-Json