Server data from the Official MCP Registry
Agent Workflow Engine — multi-step MCP workflows with per-step directives and validation.
Agent Workflow Engine — multi-step MCP workflows with per-step directives and validation.
MCP Moira is a well-architected workflow engine with comprehensive authentication (Better Auth, OAuth 2.1) and reasonable permissions for its category. However, there are moderate security concerns: environment variable exposure via HTTP headers, potential session fixation via HTTP transport without HTTPS enforcement, and insufficient input validation on template variable resolution. The codebase demonstrates good security practices in rate limiting and data size controls, but lacks explicit security hardening documentation for self-hosted deployments. Supply chain analysis found 14 known vulnerabilities in dependencies (1 critical, 10 high severity).
4 files analyzed · 22 issues found
Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.
This plugin requests these system permissions. Most are normal for its category.
Add this to your MCP configuration file:
{
"mcpServers": {
"io-github-moira-mcp-moira": {
"args": [
"-y",
"mcp-moira"
],
"command": "npx"
}
}
}From the project's GitHub README.
Agent Workflow Engine for AI agents.
Primary users: AI agents via MCP protocol. Web UI is supplementary for workflow management.
See docs/VISION.md for product vision and design principles.
Both run the same engine and MCP tools. Cloud adds managed hosting, multi-user
accounts, and SaaS-only conveniences (e.g. social login); self-host runs single-tenant
with those gates off by default (DEPLOYMENT_MODE=self-host).
Monorepo: Clean separation of concerns with npm workspaces Workflow Engine: Node-graph execution over a set of node types (@mcp-moira/workflow-engine) MCP Server: HTTP protocol server exposing the MCP tools (@mcp-moira/mcp-server) Web Backend: Express API server (@mcp-moira/web-backend) Web Frontend: React UI with webpack (@mcp-moira/web-frontend) Docs: Astro 5 + Starlight documentation site, EN+RU (@mcp-moira/docs) Shared: Database layer + Better Auth + logging (@mcp-moira/shared) Database: Modular repository pattern with Drizzle ORM Settings System: Universal settings with encryption and dynamic UI generation Docker Deployment: Multi-stage container with TypeScript validation Validation: JSON Schema with AJV
/docsdatabase/ - Modular repositories (Workflow, Execution, Settings)auth/ - Better Auth configurationlogging/ - Structured loggingconfig/) - Unified container deployment configurationRun a complete Moira instance locally with Docker — no source build required:
cp .env.example .env # then set BETTER_AUTH_SECRET (and review MOIRA_HOST/MOIRA_PORT)
docker compose up -d
Then open:
The image is pulled from the public registry by default. Data (SQLite + execution
storage) persists in ./data. See Self-Hosting or the in-app docs
at /docs/ for the full reference.
For contributors who want to build and run from the source tree, switch
docker-compose.yml to Option B first — comment out the image: line and
uncomment the build: block (the file documents both options inline). Then:
npm install
docker compose up -d --build # builds the image locally from config/Dockerfile
# Web UI: http://localhost:8080 | MCP: http://localhost:8080/mcp
(The default docker-compose.yml uses the prebuilt public image — docker compose up -d without --build — which is the recommended self-host path.)
The integration/API/E2E suites run against a local Docker container, configured by
.env.local. Copy the template once before running them (or before
npm run docker:restart):
cp .env.local.example .env.local # then set BETTER_AUTH_SECRET
npm test # All tests
npm run test:unit # Unit tests only (no container needed)
npm run test:e2e # E2E tests
npm run fix # ESLint + Prettier fix all files
Configuration in .env (copy from .env.example):
./data/moira.db (bind-mounted, persists across restarts)MCP Moira uses Better Auth with OAuth 2.1 for centralized authentication.
Browser Access:
MCP Clients:
Protected:
Testing:
docker compose up -d
# Access: http://localhost:8080/login
# MCP Inspector: http://localhost:8080/mcp
See docs/AUTHENTICATION.md for complete setup and OAuth flow details.
Point your MCP client (e.g. Claude Code) at your running instance:
| Server | URL | Purpose |
|---|---|---|
moira-local | http://localhost:8080/mcp | Your local self-host instance |
{
"mcpServers": {
"moira-local": { "url": "http://localhost:8080/mcp" }
}
}
Replace
localhost:8080with your own host/port (MOIRA_HOST) if you serve Moira on a different address.
{
"type": "start",
"id": "start",
"connections": { "default": "next-node-id" }
}
{
"type": "agent-directive",
"id": "task",
"directive": "Task instruction",
"completionCondition": "Success criteria",
"inputSchema": {
/* JSON Schema */
},
"connections": { "success": "next-node-id" }
}
{
"type": "condition",
"id": "check",
"condition": {
"operator": "gte",
"left": { "contextPath": "score" },
"right": 8
},
"connections": {
"true": "success-path",
"false": "failure-path"
}
}
{
"type": "telegram-notification",
"id": "notify",
"message": "Task completed: {{result}}",
"chatId": "{{user_chat_id}}",
"connections": { "default": "next-node-id" }
}
{
"type": "end",
"id": "end",
"finalOutput": ["result", "score"]
}
{
"type": "expression",
"id": "increment-counter",
"expressions": ["counter = counter + 1"],
"connections": { "default": "next-step" }
}
{
"type": "teleport",
"id": "teleport-replan",
"directive": "Rewrite the development plan",
"completionCondition": "New plan created",
"hint": "Use when plan needs restructuring",
"connections": { "success": "plan-node" }
}
{
"type": "subgraph",
"id": "run-subtask",
"graphId": "subtask-workflow",
"inputMapping": { "parentVar": "subVar" },
"outputMapping": { "subResult": "parentResult" },
"connections": { "success": "next-step" }
}
{
"type": "lock",
"id": "approval-gate",
"reason": "Waiting for user approval before deployment",
"connections": { "unlocked": "next-step" }
}
Pauses execution until explicitly unlocked. Sends PIN via Telegram with inline approve button. Unlockable via MCP tool, web UI, or Telegram callback.
{
"id": "workflow-id",
"metadata": {
"name": "Workflow Name",
"version": "1.0.0",
"description": "What this workflow does"
},
"nodes": [
/* Node definitions */
]
}
Variables processed in directive, completionCondition, and message fields:
{{variable}} - Context variable{{nested.path}} - Object property access{{executionId}} - System: current process ID{{workflowId}} - System: current workflow ID# Workflow Management
list
start {"workflowId": "workflow-id"}
step {"processId": "process-id", "input": "data"}
manage {"action": "create", "workflow": {...}}
manage {"action": "edit", "workflowId": "workflow-id", "changes": {...}}
manage {"action": "get", "workflowId": "workflow-id"}
# Session Information
session {"action": "user"}
session {"action": "executions"}
session {"action": "execution_context", "executionId": "execution-id"}
session {"action": "current_step", "executionId": "execution-id"}
# Execution Locking
lock {"action": "lock", "executionId": "execution-id", "reason": "Awaiting approval"}
lock {"action": "unlock", "executionId": "execution-id", "pin": "123456"}
lock {"action": "status", "executionId": "execution-id"}
lock {"action": "list"}
# User Settings
settings {"action": "get"}
settings {"action": "get", "category": "ui"}
settings {"action": "set", "key": "ui.theme", "value": "dark"}
settings {"action": "list"}
# Workflow Tokens
token {"action": "upload", "ttlMinutes": 60}
token {"action": "download", "workflowId": "workflow-id", "ttlMinutes": 60}
# Documentation
help
help {"topic": "tools"}
help {"topic": "step"}
packages/workflow-engine/ # Core execution engine
packages/mcp-server/ # MCP HTTP server (internal port, behind nginx)
packages/web-backend/ # Express API (internal port, behind nginx)
packages/web-frontend/ # React UI (static build served by nginx)
data/ # SQLite database (moira.db)
workflows/ # System workflow definitions (backup)
docs/ # Technical documentation
All development happens through Docker containers.
docker compose up -d --build # Build and run the container
npm test # Run all tests
npm run fix # ESLint + Prettier fix
Database: SQLite at DB_PATH (default: ./data/moira.db)
Migrations: Drizzle ORM (npx tsx scripts/run-migrations.ts)
Storage: Workflows and executions in database with user isolation
User Documentation: Served by your running instance at /docs/ (EN) and /ru/docs/ (RU), built from packages/docs (Starlight).
Technical Documentation: /docs directory - system reference, API specs, development guides.
Project Checklist - mandatory pre-commit checks executed by development workflows.
Custom slash commands in /commands directory. See commands/README.md for installation and usage.
POST /mcp # JSON-RPC requests (tools calls)
GET /health # Server health check
# Required for Telegram integration
TELEGRAM_BOT_TOKEN=your_bot_token
TELEGRAM_DEFAULT_CHAT_ID=your_chat_id
# Optional
MCP_PORT=4202 # Internal MCP server port (accessed via nginx proxy)
LOG_LEVEL=info
DEBUG_CONSOLE=true # Console logging for development
WORKFLOWS_DIR=./packages/web-backend/workflows/production
MCP server configuration (see MCP Configuration for details):
{
"mcpServers": {
"moira-local": {
"url": "http://localhost:8080/mcp",
"type": "http"
}
}
}
Environment variables passed via HTTP headers (recommended for HTTP transport).
Alternative: Set environment variables in your .env file.
Project uses ESLint with TypeScript support and Prettier for code formatting.
npm run fix # Auto-fix lint errors and format code
Pre-commit Hook: Husky pre-commit hook automatically runs ESLint and Prettier on staged files.
Configuration:
.eslintrc.json - ESLint rules (strict for production code, relaxed for tests).prettierrc - Prettier formatting rulesany types are errors, must be properly typedany types allowed for flexibilityProtection against spam and DoS attacks with tiered limits:
/api/*): 100 requests/minute/api/auth/*): 100 requests/minute/mcp): 30 requests/minuteExceeded limits return HTTP 429 Too Many Requests.
Protection against oversized payloads:
Exceeded limits return HTTP 413 Payload Too Large.
Request logging includes country detection via geoip-lite:
{
"method": "POST",
"path": "/api/workflows",
"ip": "203.0.113.1",
"country": "US",
"duration": 45,
"status": 200
}
Admin panel at /admin/users provides:
Admin panel at /admin/executions:
Track all sent emails:
/forgot-passwordConfigured via environment variables:
EMAIL_PROVIDER=brevo # Currently: brevo
BREVO_API_KEY=xkeysib-xxx # Brevo API key
EMAIL_FROM=noreply@domain # Sender email
EMAIL_FROM_NAME="App Name" # Sender name
Abstracted provider interface supports Brevo, Resend, SendGrid.
Where things are documented. After changing code, find the area below and update the matching file in the same change.
packages/docs/src/content/docs/docs/ (EN) + …/ru/docs/ (RU)Rendered to the docs site (/docs) and read by users. Each EN page has an RU mirror.
| Area | Covers | Path |
|---|---|---|
| Getting started | Introduction, quickstart, self-hosting | getting-started/ |
| Concepts | Workflows, nodes, templates, notes, artifacts | concepts/ |
| Guides | Writing directives, creating & editing workflows | guides/ |
| Reference | Tools, input schema, magic variables, condition operators, validation, workflow catalog | reference/ |
| Integration | MCP clients, Claude Code, agent guide, Telegram setup, troubleshooting | integration/ |
| Patterns | Branching, validation loop, escalation, subagent review, workspace, and more | patterns/ |
docs/For contributors working on the codebase (implementation detail, not end-user docs).
| File | Covers | Path |
|---|---|---|
| Development setup | Build, Docker, local dev, project structure | docs/DEVELOPMENT.md |
| Testing | Test types, runner, fixtures, antipatterns | docs/TESTING.md + docs/testing/ |
| API | Backend & admin HTTP API reference | docs/API.md |
| System architecture | Engine, storage, MCP transport, handlers, validation | docs/SYSTEM.md |
| Authentication | Better Auth, OAuth 2.1, API tokens | docs/AUTHENTICATION.md |
| Web UI | Frontend architecture, components | docs/WEB-UI.md |
| Audit system | Audit logging design | docs/AUDIT-SYSTEM.md |
| Workflows | Workflow authoring, tools, catalog | docs/WORKFLOW.md, docs/WORKFLOWS.md, docs/WORKFLOW-TOOLS.md |
| Design system | UI design tokens and components | docs/DESIGN-SYSTEM.md |
| Documentation style | How to write internal and public docs | docs/DOCUMENTATION-STYLE-GUIDE.md |
| Logging | Structured logging conventions | docs/LOGGING.md |
| Issue management | GitHub issue conventions | docs/ISSUE-MANAGEMENT.md |
| Architecture decisions | ADRs (licensing, OSS model, …) | docs/adr/ |
| Deployment | Environment variables, restart procedures | docs/deployment/ |
| Legal | License/legal notes | docs/legal/ |
Be the first to review this server!
by Modelcontextprotocol · Developer Tools
Web content fetching and conversion for efficient LLM usage
by Toleno · Developer Tools
Toleno Network MCP Server — Manage your Toleno mining account with Claude AI using natural language.
by mcp-marketplace · Developer Tools
Create, build, and publish Python MCP servers to PyPI — conversationally.