--- layout: default title: Discovery Agents nav_order: 5 --- # Discovery Agents Theta Directory supports a robust agent architecture for auto-discovering devices, hosts, and services across your home lab or data center. Agents run on a scheduled cron and feed their data into a central **Reconciliation Engine** that smartly merges information based on MAC addresses and IPs. ## Writing a Custom Agent Agents are simple JavaScript files placed in `nodejs/agents/discovery/`. A agent must export a single `discover` async function that returns a standardized graph of `resources` and `edges`. ### Agent Skeleton ```javascript // nodejs/agents/discovery/my_custom_agent.js module.exports = { discover: async (config) => { const { url, apiKey } = config; // Provided by your configuration const resources = []; const edges = []; // 1. Fetch your data from an API // const data = await fetch(...); // 2. Map data to Resources resources.push({ kind: 'network_device', // 'host', 'service', 'network_device', 'unmanaged_device' name: 'My Switch', slug: 'my-switch-01', metadata: { make: 'Vendor', model: 'Model X', interfaces: [ { mac: '00:1A:2B:3C:4D:5E', ip: '10.0.0.5' } ] } }); // 3. Map relations to Edges (optional) edges.push({ parentSlug: 'my-switch-01', childSlug: 'some-connected-client-slug', relation: 'connected_to' // 'hosts', 'exposes', 'connected_to' }); return { resources, edges }; } }; ``` ## Configuration Agents are automatically loaded and executed by the internal BullMQ job scheduler. You configure them in your `config/sso-secrets.js`: ```javascript module.exports = { // ... existing config ... discovery: { agents: { my_custom_agent: { enabled: true, cron: '*/30 * * * *', // Run every 30 minutes url: 'https://api.example.com', apiKey: 'secret-key' }, nmap: { enabled: true, cron: '0 * * * *', targetRange: '192.168.1.0/24' } } } }; ``` ## The Reconciliation Engine When your agent returns its graph, the Reconciliation Engine takes over: 1. **Matching:** It tries to find an existing device in the database matching any MAC address provided in the `interfaces` array. If no MAC matches, it falls back to IP address, and then to `slug`. 2. **Merging:** If it finds a match, it gracefully merges the metadata (so your agent can add CPU info to a host that NMAP previously found). 3. **Source Tracking:** It records your agent's filename in the `discovery_sources` array on the resource, and updates the `last_seen` timestamp. 4. **LDAP Spam Prevention:** Brand new devices are marked as `managed: false`. They will not pollute your LDAP directory until an admin explicitly promotes them.