fix(ci): pin openclaw patch workflow upstream
molecules-ai-openclaw
Patched fork of OpenClaw with MCP hybrid push+poll notification delivery for real-time agent messaging.
Overview
This repository contains a patched version of OpenClaw that enables real-time message delivery from MCP servers (e.g., molecule-mcp) to OpenClaw agents via a dual-path system:
- Push notifications — Instant delivery via
notifications/claude/channel - Poll fallback — Automatic polling via instructions injected into the system prompt
Why This Patch?
Standard MCP implementations rely on polling, which introduces latency. This patch adds push notification support while maintaining backward compatibility through an automatic poll fallback.
Architecture
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ MCP Server │────▶│ Push Handler │────▶│ OpenClaw Agent │
│ (molecule-mcp) │ │ (notifications/ │ │ (real-time) │
└─────────────────┘ │ claude/channel) │ └─────────────────┘
│ └──────────────────┘ ▲
│ │
│ ┌──────────────────┐ │
└─────────────▶│ Poll Fallback │──────────────┘
│ (instructions in │
│ system prompt) │
└──────────────────┘
Key Features
| Feature | Description | Status |
|---|---|---|
| Push Notifications | Real-time delivery via MCP channel notifications | ✅ Implemented |
| Poll Fallback | Automatic polling via system prompt instructions | ✅ Implemented |
| Instructions Deduplication | Removes duplicate instructions from multiple servers | ✅ Implemented |
| Retry Logic | Exponential backoff for failed push handlers | ✅ Implemented |
| Backward Compatible | No breaking changes to existing MCP usage | ✅ Verified |
| Zero Configuration | Works out of the box for all users | ✅ Verified |
Files Changed
Core Implementation
| File | Change |
|---|---|
src/agents/pi-bundle-mcp-types.ts |
Added McpPushNotificationHandler type and instructions field |
src/agents/pi-bundle-mcp-runtime.ts |
Push handler registration, retry logic, instructions collection |
src/agents/pi-bundle-mcp-materialize.ts |
Propagate instructions through materialization |
src/agents/pi-embedded-runner/run/params.ts |
Added pushNotificationHandler parameter |
src/agents/pi-embedded-runner/run/attempt.ts |
System prompt injection with deduplication |
Tests
| File | Coverage |
|---|---|
src/agents/pi-bundle-mcp-runtime.test.ts |
Instructions propagation |
src/agents/pi-bundle-mcp-push-notification.test.ts |
Push handler types |
src/agents/pi-bundle-mcp-optimizations.test.ts |
Deduplication and retry logic |
Infrastructure
| File | Purpose |
|---|---|
.gitea/workflows/build-and-publish.yml |
Gitea Actions CICD pipeline |
Dockerfile |
Multi-stage container build |
CICD_INTEGRATION.md |
Platform integration guide |
ORG_SETUP.md |
Organization setup instructions |
PATCHED_VERSION.md |
Local usage documentation |
Quick Start
For Platform Developers
# Configure registry
npm config set @molecule-ai:registry https://git.moleculesai.app/api/packages/npm
# Install patched OpenClaw
npm install -g @molecule-ai/openclaw
# Verify installation
openclaw --version
For Container Deployment
# Pull from Gitea Container Registry
docker pull git.moleculesai.app/molecule-ai/molecules-ai-openclaw:latest
# Run
docker run -p 3000:3000 git.moleculesai.app/molecule-ai/molecules-ai-openclaw:latest
For Development
# Clone
git clone https://git.moleculesai.app/molecule-ai/molecules-ai-openclaw.git
cd molecules-ai-openclaw
# Install dependencies
npm install
# Run tests
npx vitest run src/agents/pi-bundle-mcp-runtime.test.ts
npx vitest run src/agents/pi-bundle-mcp-push-notification.test.ts
npx vitest run src/agents/pi-bundle-mcp-optimizations.test.ts
Configuration
Push Notification Handler
import type { McpPushNotificationHandler } from "@molecule-ai/openclaw";
const pushHandler: McpPushNotificationHandler = async ({ serverName, notification }) => {
const { content, meta } = notification.params as any;
// Inject as synthetic user turn
conversation.addMessage({
role: "user",
content,
metadata: {
source: "molecule_push",
activity_id: meta.activity_id,
kind: meta.kind,
}
});
// Trigger agent turn if idle
if (agentState === "idle") {
agent.runTurn();
}
};
// Pass to runEmbeddedAttempt
await runEmbeddedAttempt({
...params,
pushNotificationHandler: pushHandler,
});
Poll Fallback (Automatic)
No configuration needed. The agent receives instructions like:
At the start of every turn, before producing your final response, call
wait_for_message(timeout_secs=2)to check for inbound messages.
CICD Pipeline
push to main
│
▼
┌─────────┐ ┌─────────────┐ ┌─────────────────┐
│ Test │───▶│ Build │───▶│ Publish npm │
│ │ │ (artifact) │ │ @molecule-ai │
└─────────┘ └─────────────┘ └─────────────────┘
│ ┌─────────────────┐
└──────────▶│ Publish Docker │
│ + Trivy scan │
└─────────────────┘
daily cron: sync-upstream → re-apply patch → push → trigger build
See CICD_INTEGRATION.md for detailed setup.
Upstream Sync
This fork is automatically synced with upstream OpenClaw daily at 9 AM UTC.
| Aspect | Details |
|---|---|
| Upstream | https://github.com/openclaw/openclaw |
| Sync Schedule | Daily at 9 AM UTC |
| Sync Method | Gitea Actions workflow |
| Conflict Handling | Automatic patch re-application with failure alerts |
Testing
Unit Tests
# Run all MCP tests
npx vitest run src/agents/pi-bundle-mcp-*.test.ts
# Run specific test
npx vitest run src/agents/pi-bundle-mcp-optimizations.test.ts
Integration Testing
# Start OpenClaw with molecule-mcp
openclaw gateway start
# Verify MCP connection
openclaw mcp list
# Check push notifications in logs
openclaw logs --follow | grep "push notification"
Troubleshooting
"Package not found"
# Verify registry configuration
npm config get @molecule-ai:registry
# Should return: https://git.moleculesai.app/api/packages/npm
# Check authentication
npm config get //git.moleculesai.app/api/packages/npm/:_authToken
"Push notifications not working"
- Verify MCP server supports
notifications/claude/channel - Check
pushNotificationHandleris passed torunEmbeddedAttempt - Review logs for handler errors:
openclaw logs | grep "push notification handler failed"
"Duplicate instructions in prompt"
This is fixed by deduplication logic. If still seeing duplicates:
- Check multiple MCP servers aren't returning identical instructions
- Verify
pi-bundle-mcp-optimizations.test.tspasses
Contributing
Before Submitting
- Run tests:
npx vitest run src/agents/pi-bundle-mcp-*.test.ts - Type check:
npx tsc --noEmit --skipLibCheck - Follow SOP guidelines
Branch Naming
feature/mcp-*— New MCP featuresfix/mcp-*— MCP bug fixessync/upstream-*— Upstream syncs
Commit Messages
Follow conventional commits:
feat(mcp): add push notification retry logic
fix(mcp): deduplicate instructions from multiple servers
docs: update CICD integration guide
Security
- Private registry — Packages published to private Gitea registry
- Vulnerability scanning — Trivy scans on every Docker build
- Non-root containers — Docker images run as unprivileged user
- Token rotation — Gitea tokens should be rotated every 90 days
License
Same as upstream OpenClaw. See LICENSE for details.
Support
- Issues: https://git.moleculesai.app/molecule-ai/molecules-ai-openclaw/issues
- Upstream: https://github.com/openclaw/openclaw/issues
- Documentation: See
docs/directory in upstream repository
Acknowledgments
This patch builds on the excellent work of the OpenClaw team. Special thanks to the MCP community for the notification protocol specification.