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 documentationpath— Relative path to the implementing JavaScript filecallable— Name of the exported function to invokeargs— JSON schema for parameter validationreturns— 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 generationpath— Relative path to a script injected into the pagereturns— 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
queryparameter and returns user objects
Browser tool post_from_active_element:
- Points to
browser-tools/extract-post.js - Extracts tweet data from the currently focused timeline element
- Returns
{ text, author, timestamp }
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 throughnodeToolsandbrowserToolsobjects - 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) andpost_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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →