Modifying Soulshack Code
March 9, 2026 ยท View on GitHub
This guide provides an overview of the codebase and instructions for common modification tasks.
Project Structure
cmd/soulshack/: Application entry point (main.go).internal/behaviors/: Event-driven behaviors (URL watcher, op watcher, addressed/non-addressed chat).internal/bot/: Core bot runtime, system initialization, and behavior registration.internal/commands/: Implementation of IRC commands (e.g.,/help,/tools).internal/config/: Configuration loading and validation.internal/core/: Core interfaces (ChatContextInterface,System,LLM) and types.internal/irc/: IRC connection handling, context management, and message parsing.internal/llm/: Integration with thepollytoollibrary for LLM capabilities.
Common Tasks
Adding a New Command
- Create a new file in
internal/commands/(e.g.,mycommand.go). - Implement the
Commandinterface:type MyCommand struct{} func (c *MyCommand) Name() string { return "/mycommand" } func (c *MyCommand) AdminOnly() bool { return false } func (c *MyCommand) Execute(ctx irc.ChatContextInterface) { ctx.Reply("Hello from MyCommand!") } - Register the command in
internal/bot/run.go:cmdRegistry.Register(&commands.MyCommand{})
Adding a Tool
Soulshack supports a unified tool system that includes native Go tools, Shell scripts, and MCP servers.
1. Shell Tools
Shell tools are executable scripts that implement a simple protocol:
--schema: Output JSON schema for the tool.--execute <json_args>: Execute the tool with the given arguments.
Example (get_date.sh):
#!/bin/bash
if [[ "\$1" == "--schema" ]]; then
cat <<EOF
{
"title": "get_date",
"description": "get current date",
"type": "object",
"properties": {
"format": { "type": "string", "description": "date format" }
},
"required": ["format"]
}
EOF
exit 0
fi
if [[ "\$1" == "--execute" ]]; then
format=$(jq -r '.format' <<< "\$2")
date -- "$format"
fi
To use: Add the script path to your config or use /tools add ./get_date.sh.
2. MCP Servers
Soulshack supports the Model Context Protocol. You can load MCP servers by providing a JSON configuration file using the Claude Desktop format.
Local Server Example (filesystem.json):
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["@modelcontextprotocol/server-filesystem", "/tmp"],
"env": {}
}
}
}
Remote Server Example (SSE transport):
{
"mcpServers": {
"remote-api": {
"url": "https://api.example.com/mcp",
"transport": "sse",
"headers": {
"Authorization": "Bearer your-api-key"
},
"timeout": "30s"
}
}
}
Multi-server configs: If a config file contains multiple servers, use #servername to select one:
--tool mcp.json#filesystem
/tools add mcp.json#git
To use: Add the JSON file path to your config or use /tools add ./filesystem.json.
3. Native Go Tools
- Implement the tool using the
pollytool/toolsinterface. - Register it in
internal/bot/system.goor viainternal/irc/tools.go.
Modifying LLM Logic
internal/llm/polly.go: Handles the interaction with the LLM agent.internal/llm/completion.go: Constructs the completion request.
To change how the bot prompts the LLM or handles the stream, modify ChatCompletionStream in polly.go.
Testing
Run unit tests using standard Go tooling:
go test ./...
For integration testing, you may need to mock the IRC connection or LLM responses. See internal/testing/ for mock implementations.