How to Customize holaOS: A Complete Guide to Desktop, Workspace, and Agent Extensions
You can customize holaOS at every layer—from workspace storage locations and UI icons to custom agent tools and MCP servers—without forking the codebase.
holaOS is a modular, local-first platform designed for extensibility. Its architecture cleanly separates frontend apps, runtime services, and shared memory, letting you override or extend individual components while the core system remains unchanged. Whether you need to relocate your workspace, add proprietary tools for agents, or swap visual elements, holaOS provides well-defined extension points backed by specific source files in the holaboss-ai/holaOS repository.
Workspace Location and Persistence
The most fundamental customization is changing where holaOS stores its data. By default, the platform maintains a workspace folder containing shared memory, skills, and installed apps. You can redirect this to any directory or maintain multiple workspaces and switch between them.
The WorkspaceInfo type in runtime/state-store/src/store.ts defines the structure:
interface WorkspaceInfo {
workspaceId: string;
workspacePath: string;
}
The assertWorkspaceFolderHealthy helper (~line 1670) resolves the last-known on-disk path for each workspace, validating that the directory exists and contains expected holaOS metadata.
To create a workspace at a custom location:
import { Store } from '@/runtime/state-store/src/store';
await Store.createWorkspace({
workspaceId: 'my-ws-custom',
workspacePath: '/Users/me/hola-custom-ws',
});
This pattern enables scenarios like:
- Symlinking workspaces to cloud-synced directories
- Isolating client projects in separate workspaces
- Running holaOS from portable storage
Custom Tools and Agent Commands
Agents in holaOS invoke capabilities through a discovered toolset that merges built-in functions with your custom additions. You can register new tools that call internal APIs, proprietary services, or local CLIs.
The registration flow in runtime/harness-host/src/pi.ts handles this:
buildPiMcpCustomToolsFromDiscovered(~lines 2630-2670) assembles thecustomToolsarray from discovered schemassanitizeToolSchemas(~line 3148) validates tool definitions before exposing them to agents
Add a custom tool by defining its MCP-compatible schema and execution handler:
const myTool = {
name: 'my_search',
description: 'Search internal docs',
parameters: {
type: 'object',
properties: {
query: { type: 'string', description: 'Search query' },
},
required: ['query'],
},
execute: async ({ query }) => {
const results = await myInternalSearch(query);
return { result: results };
},
};
import { registerCustomTool } from '@/runtime/harness-host/src/pi';
registerCustomTool(myTool);
The tool becomes immediately available to agents without restarting the entire platform. Tool execution runs in the host process, giving full access to local resources and network capabilities.
Icon Palette Customization
All UI icons in holaOS are routed through a single wrapper component, allowing you to replace visuals without modifying dozens of component files.
The icon system lives in apps/desktop/src/components/ui/icons.tsx. It maps IconType values to actual HugeIcons SVG components:
// apps/desktop/src/components/ui/icons.tsx
export const MyNewIcon = makeIcon(HugeIconHome);
After creating the wrapper, import it throughout your components:
import { MyNewIcon } from '@/components/ui/icons';
This approach means:
- You can swap the underlying HugeIcons entry without changing import sites
- Custom icon sets can be integrated by wrapping them with
makeIcon() - The icon library remains tree-shakeable
HolaApps: In-Workspace Applications
HolaApps are marketplace applications that run alongside the agent—Notion instances, browsers, custom web UIs, or internal dashboards. Each app is described by a manifest and can target any MCP server.
The app loader in apps/desktop/src/components/app/ reads manifests from the workspace's apps/ folder. A minimal manifest specifies:
- Entry point URL or file
- Required permissions
- Associated MCP server (if any)
- UI presentation hints
You can develop private HolaApps for internal tools and distribute them through your workspace without publishing to any marketplace.
Model Context Protocol (MCP) Servers
MCP servers extend agent capabilities by exposing external tools, embedding providers, or alternative LLM backends. holaOS maintains a registry of these servers in the mcpToolMetadata map within runtime/harness-host/src/pi.ts.
Register a new MCP server at runtime:
import { addMcpServer } from '@/runtime/harness-host/src/pi';
addMcpServer({
serverId: 'my-mcp',
url: 'http://localhost:8000',
tools: ['my_search', 'my_analyze'],
});
The server immediately becomes available for tool discovery. This enables:
- Connecting to internal MCP-compliant services
- A/B testing different LLM providers
- Implementing organization-specific tool governance
Configuration and Environment Overrides
Default settings—memory retention policies, built-in tool toggles, model defaults—can be overridden through configuration files.
The migration script at runtime/state-store/src/migrations/001-workspace-plugins.ts applies stored plugin configurations on startup, ensuring customizations persist across sessions.
For environment-specific values, reference apps/desktop/.env.example and create a local .env file:
# apps/desktop/.env
HOLA_WORKSPACE_ROOT=/custom/workspace/path
HOLA_DEFAULT_MODEL=claude-sonnet-4
HOLA_ENABLE_TELEMETRY=false
The installation script at scripts/install.sh can be modified before first run to initialize holaOS with custom defaults.
Key Source Files Reference
| File | Responsibility |
|---|---|
runtime/state-store/src/store.ts |
Workspace lifecycle, path resolution, WorkspaceInfo type |
runtime/harness-host/src/pi.ts |
Agent dispatch, custom tool registration, MCP server metadata |
apps/desktop/src/components/ui/icons.tsx |
Icon wrapper layer, makeIcon() factory |
runtime/state-store/src/migrations/001-workspace-plugins.ts |
Plugin configuration persistence |
apps/desktop/.env.example |
Environment variable template |
scripts/install.sh |
Initial workspace setup (editable) |
Summary
- Workspace location: Redirect via
Store.createWorkspace()with customworkspacePath - Custom tools: Register through
registerCustomTool()inruntime/harness-host/src/pi.ts - UI icons: Wrap with
makeIcon()inapps/desktop/src/components/ui/icons.tsx - HolaApps: Add manifests to workspace
apps/folder - MCP servers: Register via
addMcpServer()for external tool integration - Configuration: Use migration scripts and
.envfiles for persistent overrides
Frequently Asked Questions
Can I run multiple holaOS workspaces simultaneously?
Yes. Each workspace has a unique workspaceId and independent workspacePath. Launch separate holaOS instances pointing to different workspace IDs, or switch contexts within a single instance using Store.loadWorkspace().
Do custom tools require restarting holaOS?
No. The registerCustomTool() function updates the customTools array at runtime. Agents discover new tools on their next planning cycle without platform restart.
What icon library does holaOS use?
holaOS ships with HugeIcons, a free MIT-licensed icon set. The makeIcon() wrapper in apps/desktop/src/components/ui/icons.tsx lets you substitute any HugeIcons entry or wrap custom SVGs to match the platform's icon interface.
Can I disable built-in tools that agents shouldn't access?
Yes. Configuration migrations in runtime/state-store/src/migrations/001-workspace-plugins.ts can modify the enabled toolset. Filter the customTools array or adjust mcpToolMetadata entries to restrict agent capabilities per workspace.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →