How the Site Skill Manifest Defines Reusable Tools and Browser Tools in Ego‑Lite

The site skill manifest declares reusable Node.js utilities and browser‑side helpers through two top‑level JSON objects: nodeTools for server‑side execution and browserTools for in‑page Chromium automation.

In the citrolabs/ego-lite framework, site skills bundle domain‑specific logic for automating websites like X (Twitter). The manifest file serves as the single source of truth that registers these capabilities with the Ego Browser runtime. This article breaks down how nodeTools and browserTools work, using the actual X‑com skill implementation as a reference.


Understanding the Site Skill Manifest Structure

Each site skill lives in a directory like skills/ego-browser/learnings/x-com/ and contains a manifest.json file. This manifest declares two distinct categories of reusable tools.

Node Tools: Server‑Side Utilities

The nodeTools object maps tool names to Node.js functions that execute inside the skill's server context. According to the source code in skills/ego-browser/learnings/x-com/manifest.json, each entry requires:

  • description — Human‑readable purpose for documentation
  • path — Relative path to the implementing JavaScript file
  • callable — Name of the exported function to invoke
  • args — JSON schema for parameter validation
  • returns — JSON schema for the result type

When an agent script calls runSiteTool(siteId, toolName, args), the runtime loads the file at path, imports the callable function, validates arguments against the args schema, executes the function, and returns the typed result.

Browser Tools: In‑Page Automation

The browserTools object declares utilities that run inside the active Chromium page. As implemented in the same manifest structure, each entry contains:

  • description — Purpose statement for help generation
  • path — Relative path to a script injected into the page
  • returns — Schema for the extracted data

The helper runSiteBrowserTool(siteId, toolName) injects the script into the browser context, runs the exported function, and returns the result. Arguments are optional unless explicitly defined.


Real‑World Example: The X (Twitter) Site Skill

The X‑com skill demonstrates both tool types in practice. Here are excerpts from [skills/ego-browser/learnings/x-com/manifest.json](https://github.com/citrolabs/ego-lite/blob/main/skills/ego-browser/learnings/x-com/manifest.json):

Node tool search_users:

  • Points to tools/search-users.js
  • Exposes callable searchUsers
  • Accepts a query parameter and returns user objects

Browser tool post_from_active_element:

At build time, the runtime scans this manifest, registers both tool types, and makes them available to agent scripts without additional wiring.


Calling Tools from Agent Scripts

The [src/helpers.ts](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts) file exposes two functions for tool invocation.

Using a Node‑Side Tool

// Manifest entry for "search_users":
// {
//   "search_users": {
//     "description": "Search for users on X.",
//     "path": "tools/search-users.js",
//     "callable": "searchUsers",
//     "args": { "type": "object", "properties": { "query": { "type": "string" } } },
//     "returns": { "type": "array", "items": { "type": "object" } }
//   }
// }

const users = await runSiteTool(
  'x-com',               // site‑skill id
  'search_users',        // tool name from manifest
  { query: 'openai' }    // validated against args schema
);

console.log(users);      // typed array per returns schema

The implementation in [tools/search-users.js](https://github.com/citrolabs/ego-lite/blob/main/skills/ego-browser/learnings/x-com/tools/search-users.js) handles the actual API interaction.

Using a Browser‑Side Tool

// Manifest entry for "post_from_active_element":
// {
//   "post_from_active_element": {
//     "description": "Extract tweet data from the currently focused element",
//     "path": "browser-tools/extract-post.js",
//     "returns": { "type": "object" }
//   }
// }

const tweet = await runSiteBrowserTool(
  'x-com',                     // site‑skill id
  'post_from_active_element'   // browser‑tool name
);

console.log(tweet);            // { text, author, timestamp }

The [browser-tools/extract-post.js](https://github.com/citrolabs/ego-lite/blob/main/skills/ego-browser/learnings/x-com/browser-tools/extract-post.js) implementation runs directly in the page's JavaScript context.

Combining Both Tool Types

// Fetch timeline server‑side, then extract details from active element
const timeline = await runSiteTool('x-com', 'get_timeline_posts', { maxPosts: 5 });
const firstTweet = await runSiteBrowserTool('x-com', 'post_from_active_element');

console.log({ serverData: timeline, browserData: firstTweet });

Internal Runtime Mechanics

Behind the helper functions, two internal modules handle tool execution:

Module Responsibility
src/learning/run-site-tool.ts Loads Node tool files, validates arguments against schemas, executes callables
src/learning/run-browser-tool.ts Injects browser tool scripts into Chromium pages, captures return values

Both modules read the site skill manifest to resolve tool paths and enforce type safety. The manifest's JSDoc‑compatible descriptions enable automatic help() generation at runtime.


Summary

  • The site skill manifest (manifest.json) centrally declares reusable tools through nodeTools and browserTools objects
  • Node tools run server‑side via runSiteTool(), with full argument validation and typed returns
  • Browser tools execute in‑page via runSiteBrowserTool(), enabling DOM interaction without exposing selectors to agent code
  • Both tool types follow identical JSON schema patterns, making manifests self‑documenting
  • The X‑com skill demonstrates production usage with search_users (Node) and post_from_active_element (browser)

Frequently Asked Questions

What file format does the site skill manifest use?

The manifest is a JSON file located at the root of each site skill directory, typically named manifest.json. It declares nodeTools and browserTools as top‑level objects mapping tool names to their specifications.

Can browser tools accept arguments like Node tools?

Yes, but optionally. The browserTools schema supports an args property identical to nodeTools, though many browser tools rely on page state rather than explicit parameters. The runSiteBrowserTool() function accepts an optional third argument when the manifest defines an input schema.

How does the runtime validate tool arguments?

Arguments are validated against the JSON schema defined in each tool's args property before execution. The run-site-tool.ts module performs this validation for Node tools; browser tools receive the same treatment in run-browser-tool.ts when arguments are provided.

Where are tool implementations stored relative to the manifest?

Tool implementations reside in subdirectories referenced by relative path values. In the X‑com skill, Node tools live in tools/ and browser tools in browser-tools/, both sibling directories to manifest.json.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →