con un clic
con un clic
Build MCP (Model Context Protocol) servers - expose tools, resources, and prompts to LLMs. TypeScript/Python SDKs for Claude Desktop integration. NOTE: Do NOT invoke for the built-in /mcp Claude Code command — that lists configured MCP servers and is unrelated to building MCP server code.
MCP (Model Context Protocol) server build and evaluation guide, including local conventions for tool surfaces, config, and testing
Guide for creating effective skills
Re-authenticate Google Workspace MCP in-flight - refresh tokens, setup OAuth, check status
Bug reporting protocol for PM and agents to file GitHub issues
Protocol for tracking files immediately after agent creation
| name | mpm-message |
| description | Send cross-project messages to other Claude MPM instances |
| user-invocable | true |
| version | 3.0.0 |
| category | mpm-command |
| tags | ["mpm-command","communication","pm-required"] |
Send asynchronous messages to other Claude MPM instances running in different projects.
Important: Always use
claude-mpm messageCLI commands or theMessageServicePython API. Never querymessaging.dbdirectly — the database location is an implementation detail.
msg.type NOT msg.message_typeWhen reading a returned Message object, the field is msg.type.
When sending, the parameter is message_type= (matches DB column).
Confusing these causes AttributeError: 'Message' object has no attribute 'message_type'.
# WRONG — causes AttributeError
print(msg.message_type)
# CORRECT
print(msg.type)
The PM must NEVER access messaging.db directly with sqlite3 or raw Python one-liners.
Always use:
claude-mpm message list / read / send / replyMessageService(Path.cwd()) — see API reference belowclaude-mpm message list # all messages
claude-mpm message list --status unread # unread only
claude-mpm message read <message-id> # read + mark as read
claude-mpm message send /path/to/project \
--subject "Subject" --body "Body" \
--type task --priority high --to-agent pm
claude-mpm message reply <message-id> --body "Response"
claude-mpm message archive <message-id>
~/.claude-mpm/messaging.db)All messages flow through a single shared database at ~/.claude-mpm/messaging.db. No per-project databases.
/mpm-message <project-path> <message>
# Send a message
claude-mpm message send <project-path> \
--body "message content" \
--subject "message subject" \
--type [task|request|notification|reply] \
--priority [low|normal|high|urgent] \
--to-agent [pm|engineer|qa|ops|etc]
# For complex bodies with quotes, use --body-file
claude-mpm message send <project-path> --body-file message.txt --subject "subject"
echo "body text" | claude-mpm message send <project-path> --body-file - --subject "subject"
# Inbox operations
claude-mpm message check # Quick unread count
claude-mpm message list # List all messages
claude-mpm message list --status unread # List unread only
claude-mpm message read <message-id> # Read a message
claude-mpm message reply <message-id> --body "response"
claude-mpm message reply <message-id> --body-file reply.txt # From file
claude-mpm message archive <message-id>
claude-mpm message sessions # List active sessions
from pathlib import Path
from claude_mpm.services.communication.message_service import MessageService
service = MessageService(Path.cwd())
msg = service.send_message(
to_project='/path/to/target/project',
to_agent='pm',
message_type='notification', # task | request | notification | reply
subject='Subject here',
body='Body content here',
priority='high', # urgent | high | normal | low
from_agent='pm',
)
print(f"Sent: {msg.id}")
# List unread
unread = service.list_messages(status="unread")
for m in unread:
print(f"[{m.priority}] {m.subject}")
# Read and reply
message = service.read_message("msg-id-here")
reply = service.reply_to_message("msg-id-here", subject="Re: ...", body="Done!")
Note:
send_message()takesmessage_type=(nottype=) — this matches the DB schema column name.
Do NOT use raw SQLite INSERT statements to send messages. This bypasses the abstraction layer and will break when the Huey message bus migration lands (#311).
Wrong:
# ❌ NEVER DO THIS
conn.execute("INSERT INTO messages (type, ...) VALUES ...")
Right:
# ✅ ALWAYS USE MessageService
service = MessageService(Path.cwd())
service.send_message(to_project=..., message_type=..., ...)
The DB column is message_type, not type — direct writes get this wrong and create schema-mismatched records.
| Type | Use Case |
|---|---|
| task | Delegate work to another project |
| request | Ask for information or assistance |
| notification | Share status updates |
| reply | Respond to received messages |
Always use the CLI to check messages — never query the database directly:
# Quick unread count
claude-mpm message check
# List unread messages
claude-mpm message list --status unread
# Read a specific message
claude-mpm message read <message-id>
Single shared database: ~/.claude-mpm/messaging.db
All projects read from and write to the same database. Messages are filtered by to_project on read.
messaging:
enabled: true
check_on_startup: true
command_threshold: 10
time_threshold: 30
auto_create_tasks: true
task_priority_filter: ["urgent", "high"]
Messages are just messages — peer-to-peer communication. Tasks are local decisions. When PM reads a message, the local PM decides what tasks to create based on its own context.
The sending project should NOT inject tasks — it doesn't have the recipient's context.
The current implementation uses SQLite directly. A Huey-based message bus migration is planned (#311). Always use MessageService to ensure your code works after the migration. Do not write to messaging.db directly.
Version: 5.9.27+ Status: Stable Issues: #305, #310, #311, #312