OpenMolt.dev
OpenMolt lets you build programmatic AI agents in Node.js that think, plan, and act using tools, integrations, and memory — directly from your codebase.
Install / Use
/learn @ybouane/OpenMolt.devREADME
OpenMolt
Programmatic AI Agent System for Node.js / TypeScript
OpenMolt lets your code create autonomous AI agents that plan, reason, and act — calling real APIs, reading files, generating images, sending messages, and more. Agents run a self-directed reasoning loop (the Maestro loop) powered by any LLM until the task is complete.
npm install openmolt
→ openmolt.dev — full documentation, API reference, and examples
Why OpenMolt?
| | |
|---|---|
| Secure by design | Agents access only the scopes you grant. The LLM sees tool names — never raw credentials |
| Multi-provider | OpenAI, Anthropic Claude, and Google Gemini with a unified provider:model string |
| 30+ built-in integrations | Gmail, Slack, GitHub, Notion, Stripe, Discord, S3, and more — ready out of the box |
| Declarative HTTP tools | Define integrations as data (endpoint, auth, Liquid templates) — no boilerplate |
| Typed output | Pass a Zod schema; agent.run() returns a validated, typed object |
| Scheduling | Interval and cron-style daily schedules with timezone support |
| Events | Observable reasoning loop — hook into every tool call, plan update, and LLM output |
| Memory | Long-term and short-term memory stores with onUpdate persistence callbacks |
| CLI | npx openmolt agent.json to run agents from a config file |
Secure by Design
OpenMolt was built with security as a first-class constraint, not an afterthought.
Scope-gated tools. Every integration is granted an explicit list of scopes when you attach it to an agent. If a tool requires the write scope and you only granted read, the agent cannot call it — regardless of what the LLM decides.
integrations: [
{
integration: 'gmail',
credential: { type: 'oauth2', config: { ... } },
scopes: ['read'], // agent can read emails, but cannot send or delete
},
],
Credentials never reach the LLM. The model only sees tool names and their input/output schemas. Your API keys, tokens, and OAuth secrets are resolved server-side at execution time — the LLM prompt contains none of them.
Directory-restricted filesystem. The FileSystem integration is a factory that you instantiate with an explicit allowlist of directories. The agent cannot read or write outside those paths.
om.registerIntegration('fileSystem', OpenMolt.FileSystemIntegration('./output'));
// agent cannot access /etc, ~/, or any path outside ./output
No implicit network access. Agents can only call APIs that are registered as integrations. There is no general-purpose outbound HTTP unless you explicitly add the httpRequest integration.
Quick Start
import OpenMolt from 'openmolt';
const om = new OpenMolt({
llmProviders: {
openai: { apiKey: process.env.OPENMOLT_OPENAI_API_KEY },
},
});
const agent = om.createAgent({
name: 'Comedian',
model: 'openai:gpt-4o-mini',
instructions: 'You are a witty stand-up comedian.',
});
const result = await agent.run('Tell me a joke!');
console.log(result);
Environment variables (no config needed):
| Variable | Provider |
|---|---|
| OPENMOLT_OPENAI_API_KEY | OpenAI |
| OPENMOLT_ANTHROPIC_API_KEY | Anthropic |
| OPENMOLT_GOOGLE_API_KEY | Google Gemini |
Model Strings
Choose any LLM with provider:model-name:
model: 'openai:gpt-4o'
model: 'openai:o3-mini'
model: 'anthropic:claude-opus-4-6'
model: 'anthropic:claude-sonnet-4-6'
model: 'google:gemini-2.0-flash'
model: 'google:gemini-2.5-pro'
Optional per-model config:
modelConfig: {
thinking: true, // Extended thinking (Anthropic / Gemini)
search: true, // Grounded web search (Gemini)
temperature: 0.7,
}
Examples
Structured output with a Zod schema
import { z } from 'zod';
import OpenMolt from 'openmolt';
const om = new OpenMolt({ llmProviders: { openai: {} } });
const LogoSchema = z.object({
logoUrl: z.string().url(),
altText: z.string().optional(),
confidence: z.enum(['high', 'medium', 'low']),
});
const agent = om.createAgent({
name: 'LogoExtractor',
model: 'openai:gpt-4o',
instructions: 'Fetch the page with httpRequest and extract the logo URL.',
integrations: [
{ integration: 'httpRequest', credential: { type: 'custom', config: {} }, scopes: 'all' },
],
outputSchema: LogoSchema,
});
const result = await agent.run('https://example.com') as z.infer<typeof LogoSchema>;
console.log(result.logoUrl, result.confidence);
Gmail draft generator that runs on a schedule
import OpenMolt from 'openmolt';
const om = new OpenMolt({ llmProviders: { openai: {} }, maxSteps: 30 });
const agent = om.createAgent({
name: 'GmailDraftBot',
model: 'openai:gpt-4o',
instructions: `
Fetch the 10 most recent unread emails.
For each one, draft a professional reply using gmail → createDraft.
Finish with a summary of how many drafts were created.
`,
integrations: [
{
integration: 'gmail',
credential: {
type: 'oauth2',
config: {
clientId: process.env.GOOGLE_CLIENT_ID ?? '',
clientSecret: process.env.GOOGLE_CLIENT_SECRET ?? '',
refreshToken: process.env.GOOGLE_REFRESH_TOKEN ?? '',
},
onTokenRefresh: async (newConfig) => { /* persist tokens */ },
},
scopes: 'all',
},
],
});
agent.on('tool:call', ({ tool }) =>
console.log(`[tool] ${tool.integration}.${tool.handle}`)
);
// Run once now, then every 20 minutes
await agent.run('Process unread emails.');
const id = agent.schedule({ type: 'interval', value: 20 * 60 });
process.on('SIGINT', () => { agent.cancelSchedule(id); process.exit(0); });
Blog post writer with AI-generated images
import OpenMolt from 'openmolt';
const om = new OpenMolt({ llmProviders: { openai: {} }, maxSteps: 40 });
// Restrict filesystem access to ./blog only
om.registerIntegration('fileSystem', OpenMolt.FileSystemIntegration('./blog'));
const agent = om.createAgent({
name: 'BlogWriter',
model: 'openai:gpt-4o',
instructions: `
1. Write a full Markdown blog post with front-matter.
2. Generate 2-3 images with fal → generate (fal-ai/flux/schnell).
3. Save the .md file to fileSystem with the fal CDN image URLs inline.
4. Finish with the output path and image URLs.
`,
integrations: [
{ integration: 'fal', credential: { type: 'bearer', config: { apiKey: process.env.FAL_API_KEY ?? '' } }, scopes: 'all' },
{ integration: 'fileSystem', credential: { type: 'custom', config: {} }, scopes: ['read', 'write'] },
],
});
const result = await agent.run('Write a blog post about the future of AI agents.');
console.log(result);
Custom integration (declarative HTTP)
import OpenMolt, { IntegrationDefinition } from 'openmolt';
import { z } from 'zod';
const weatherDefinition: IntegrationDefinition = {
name: 'Weather',
apiSetup: {
baseUrl: 'https://api.openweathermap.org/data/2.5',
headers: { 'Content-Type': 'application/json' },
responseFormat: 'json',
},
credentialSetup: [{ type: 'custom', queryParams: { appid: '{{ config.apiKey }}' } }],
tools: [
{
handle: 'getCurrentWeather',
description: 'Get current weather for a city.',
method: 'GET',
endpoint: '/weather',
queryParams: { q: '{{ input.city }}', units: 'metric' },
inputSchema: z.object({ city: z.string() }),
outputSchema: z.object({ temp: z.number(), description: z.string() }),
},
],
};
const om = new OpenMolt({ llmProviders: { anthropic: {} } });
om.registerIntegration('weather', weatherDefinition);
const agent = om.createAgent({
name: 'WeatherBot',
model: 'anthropic:claude-sonnet-4-6',
instructions: 'Answer questions about the current weather.',
integrations: [
{ integration: 'weather', credential: { type: 'custom', config: { apiKey: process.env.WEATHER_API_KEY ?? '' } }, scopes: 'all' },
],
});
console.log(await agent.run('What is the weather in Tokyo?'));
Daily scheduling with memory
const agent = om.createAgent({
name: 'ReportBot',
model: 'google:gemini-2.0-flash',
instructions: 'Pull metrics from Stripe and post a daily summary to Slack.',
memory: {
longTerm: {
data: '',
onUpdate: async (data) => await fs.writeFile('memory.txt', data),
},
},
integrations: [
{ integration: 'stripe', credential: { type: 'bearer', config: { apiKey: process.env.STRIPE_SECRET_KEY ?? '' } }, scopes: 'all' },
{ integration: 'slack', credential: { type: 'bearer', config: { apiKey: process.env.SLACK_BOT_TOKEN ?? '' } }, scopes: 'all' },
],
});
// Every weekday at 9 AM New York time
agent.schedule({
type: 'daily',
dayOfWeek: [1, 2, 3, 4, 5],
hour: 9, minute: 0,
timeZone: 'America/New_York',
});
Built-in Integrations
| Category | Integrations | |---|---| | Productivity | Notion, Airtable, Google Calendar, Google Drive, Google Sheets, Microsoft Outlook | | Communication | Gmail, Slack, Discord, Telegram, WhatsApp, Twilio | | Social / Content | X (Twitter), Instagram, TikTok, YouTube | | AI / Media | fal.ai, Google Imagen + Veo (Gemini Media Models), OpenAI Media Models (DALL-E / gpt-image-1) | | Commerce | Stripe, Shopify, Etsy | | Dev & Cloud | GitHub, AWS S3, Dropbox | | Ads | Google Ads, Meta Ads | | Web | browser-use.com (cloud browsing), Generic HTTP Request | | Local | FileSystem (directory-restricted) |
Events
Observe every step of the agent's reasoning:
agent.on('llmOutput', ({ output }) => console.log('LLM tokens used:', output.usage));
agent.on('commandsQueued', ({ commands }) => console.log('Next commands:', commands.length));
agent.on('tool:call', ({ tool })
Related Skills
node-connect
344.1kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
96.8kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
344.1kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
344.1kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
