mess-mcp
MCP server tools for creating and managing MESS physical-world task requests. Provides mess, mess_status, mess_capabilities, mess_request, mess_answer, mess_cancel, and mess_fetch tools.
Packaged view
This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.
Install command
npx @skill-hub/cli install teaguesterling-git-messe-af-mcp
Repository
Skill path: mcp
MCP server tools for creating and managing MESS physical-world task requests. Provides mess, mess_status, mess_capabilities, mess_request, mess_answer, mess_cancel, and mess_fetch tools.
Open repositoryBest for
Primary workflow: Ship Full Stack.
Technical facets: Full Stack, Backend, Integration.
Target audience: everyone.
License: Unknown.
Original source
Catalog source: SkillHub Club.
Repository owner: teaguesterling.
This is still a mirrored public skill entry. Review the repository before installing into production workflows.
What it helps with
- Install mess-mcp into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/teaguesterling/git-messe-af before adding mess-mcp to shared team environments
- Use mess-mcp for development workflows
Works across
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
---
name: mess-mcp
description: MCP server tools for creating and managing MESS physical-world task requests. Provides mess, mess_status, mess_capabilities, mess_request, mess_answer, mess_cancel, and mess_fetch tools.
---
# MESS MCP Server
## Overview
The MESS MCP Server provides Claude Desktop with tools to create and manage physical-world task requests. It syncs with GitHub (or local files) to store request threads.
## Tools
### `mess` - Send MESS Protocol Messages
Create new requests or update existing ones using free-form YAML.
**Input:** YAML-formatted MESS message
**Why YAML?** The `mess` tool accepts raw MESS protocol messages, allowing you to:
- Include any valid MESS protocol fields, not just common ones
- Add custom context, metadata, or instructions
- Construct complex multi-part messages
- Use the full expressiveness of the MESS protocol
The examples below show common patterns, but you can include any fields defined in the MESS protocol specification.
#### Creating a Request
```yaml
- v: 1.0.0
- request:
intent: Check if the garage door is closed
context:
- Getting ready for bed
- Want to make sure house is secure
priority: normal
response_hint:
- image
- text
```
**Response:**
```yaml
ref: "2026-02-01-001"
status: pending
message: "Request created: 2026-02-01-001"
```
#### Updating a Request
Send a status update:
```yaml
- status:
re: "2026-02-01-001"
code: claimed
```
Cancel a request:
```yaml
- cancel:
re: "2026-02-01-001"
reason: "No longer needed"
```
### `mess_status` - Check Request Status
Query pending requests or get details on a specific thread.
#### List All Active Requests
```yaml
ref: null
```
**Response:**
```yaml
- ref: "2026-02-01-001"
status: pending
intent: Check if the garage door is closed
requestor: claude-desktop
executor: null
priority: normal
created: "2026-02-01T22:00:00Z"
hasUpdates: true # changed since last mess_status call
- ref: "2026-02-01-002"
status: claimed
intent: What's in the fridge?
requestor: claude-desktop
executor: teague-phone
priority: normal
hasUpdates: false # no changes since last check
```
**Note:** The `hasUpdates` flag indicates whether the thread changed since your last `mess_status` call. New threads always have `hasUpdates: true`. Use `mess_wait` instead of polling if you want to wait for changes efficiently.
#### Get Specific Thread
```yaml
ref: "2026-02-01-001"
```
**Response (v2.1.0 format):**
```yaml
ref: "2026-02-01-001-garage-check"
status: completed
intent: Check if the garage door is closed
requestor: claude-desktop
executor: teague-phone
messages:
- from: claude-desktop
received: "2026-02-01T22:00:00Z"
MESS:
- v: "1.0.0"
- request:
id: garage-check
intent: Check if the garage door is closed
- from: teague-phone
received: "2026-02-01T22:05:00Z"
re: "2026-02-01-001-garage-check" # message-level reference
MESS:
- status:
code: completed
- response:
content:
- image:
resource: "content://2026-02-01-001-garage-check/att-002-image-door.jpg"
mime: "image/jpeg"
size: 245891
- "All clear - garage door is closed and locked"
attachments:
- name: att-002-image-door.jpg
resource: "content://2026-02-01-001-garage-check/att-002-image-door.jpg"
```
**Note:** Images are returned as `content://` resource URIs instead of inline base64 to keep responses lightweight. Use `mess_fetch` to fetch attachment content when needed.
## Configuration
### GitHub Mode (Recommended)
```json
{
"mcpServers": {
"mess": {
"command": "node",
"args": ["/path/to/mcp/index.js"],
"env": {
"MESS_GITHUB_REPO": "username/mess-exchange",
"MESS_GITHUB_TOKEN": "github_pat_xxxxx",
"MESS_GITHUB_ONLY": "true",
"MESS_AGENT_ID": "claude-desktop"
}
}
}
}
```
### Local Mode
```json
{
"mcpServers": {
"mess": {
"command": "node",
"args": ["/path/to/mcp/index.js"],
"env": {
"MESS_DIR": "~/.mess",
"MESS_AGENT_ID": "claude-desktop"
}
}
}
}
```
### Hybrid Mode (Local + GitHub Sync)
```json
{
"mcpServers": {
"mess": {
"command": "node",
"args": ["/path/to/mcp/index.js"],
"env": {
"MESS_DIR": "~/.mess",
"MESS_GITHUB_REPO": "username/mess-exchange",
"MESS_GITHUB_TOKEN": "github_pat_xxxxx",
"MESS_AGENT_ID": "claude-desktop"
}
}
}
}
```
### `mess_capabilities` - Discover Available Capabilities
List physical-world capabilities that executors in this exchange can perform.
**Input:** Optional `tag` filter
#### List All Capabilities
```yaml
# No input needed
```
**Response:**
```yaml
- id: camera
description: Take and attach photos
tags: [attachments]
- id: check-door
description: Check if doors are locked or closed
tags: [security, physical-access]
- id: hands
description: Has human hands for physical manipulation
tags: [physical-access]
```
#### Filter by Tag
```yaml
tag: security
```
**Response:**
```yaml
- id: check-door
description: Check if doors are locked or closed
tags: [security, physical-access]
- id: check-stove
description: Verify stove/oven is turned off
tags: [security, safety]
```
Use this to understand what kinds of tasks you can request. Capabilities are defined in `capabilities/*.yaml` in the exchange.
### `mess_request` - Create Request (Simple)
A simpler alternative to the raw `mess` tool for creating requests.
**Input:**
```yaml
intent: "Check if the garage door is closed"
context:
- "Getting ready for bed"
priority: elevated
response_hints:
- image
```
**Response:**
```yaml
ref: "2026-02-01-001"
status: pending
message: "Request created"
```
### `mess_answer` - Answer Question
Respond to an executor's question when status is `needs_input`.
**Input:**
```yaml
ref: "2026-02-01-001"
answer: "The living room ceiling light, not the lamp"
```
### `mess_cancel` - Cancel Request
Cancel a pending or in-progress request.
**Input:**
```yaml
ref: "2026-02-01-001"
reason: "No longer needed" # optional
```
### `mess_wait` - Wait for Changes
Wait for changes to threads instead of polling `mess_status` repeatedly.
**Input:**
```yaml
ref: "2026-02-01-001" # optional: wait for specific thread
timeout: 60 # optional: seconds (default: 60, max: 43200 / 12 hours)
```
**Response:**
```yaml
updated:
- ref: "2026-02-01-001"
status: claimed
hasUpdates: true
waited: 5
timedOut: false
```
**Adaptive polling:** Poll frequency scales with timeout (~30 polls total):
- 60s timeout → polls every 2s
- 5 min → every 10s
- 1 hour → every 2 min
- 12 hours → every 24 min
**When to use:**
- After creating a request, call `mess_wait` to be notified when claimed/completed
- Returns immediately if thread changed since wait started
- Use for efficient long-running waits instead of polling
**Example workflow:**
```yaml
# 1. Create a request
mess_request:
intent: "Check if the garage door is closed"
# 2. Wait for it to be completed (up to 1 hour)
mess_wait:
ref: "2026-02-01-001"
timeout: 3600
# 3. Response returns when status changes or timeout
```
### `mess_fetch` - Fetch Resource Content
**This is how you retrieve images and attachments.** When `mess_status` returns `content://` URIs, use this tool to fetch the actual content.
**Input:**
```yaml
uri: "content://2026-02-01-001/photo.jpg"
```
**Supported URI schemes:**
- `content://{ref}/{filename}` - Attachments (images, files)
- `thread://{ref}` - Full thread data (envelope + messages)
- `thread://{ref}/envelope` - Thread metadata only
- `thread://{ref}/latest` - Most recent message
- `mess://help` - This documentation
**Response for images:**
```yaml
uri: "content://2026-02-01-001/photo.jpg"
mimeType: "image/jpeg"
encoding: "base64"
data: "/9j/4AAQSkZJRg..."
```
**Response for thread data:**
Returns the thread content as YAML.
**Example workflow:**
```yaml
# 1. Check status, see there's an image
mess_status:
ref: "2026-02-01-001"
# Response includes: resource: "content://2026-02-01-001/photo.jpg"
# 2. Fetch the image
mess_fetch:
uri: "content://2026-02-01-001/photo.jpg"
# Response includes base64 image data
```
## Request Fields
| Field | Required | Description |
|-------|----------|-------------|
| `intent` | Yes | What you need done (be specific) |
| `id` | No | Your local identifier for tracking (exchange assigns canonical `ref`) |
| `context` | No | List of relevant context strings |
| `priority` | No | `background`, `normal`, `elevated`, `urgent` |
| `response_hint` | No | Expected response types: `text`, `image`, `video`, `audio` |
### Free-Form Extensions
The MESS protocol is extensible. Beyond the standard fields above, you can include:
```yaml
- v: 1.0.0
- request:
intent: Check the garden irrigation system
context:
- Haven't watered in 3 days
priority: normal
# Standard fields above, custom fields below:
location: backyard
equipment_needed:
- hose access
- manual valve knowledge
safety_notes:
- Watch for wasps near the shed
deadline: before 6pm today
```
Custom fields are preserved in the thread and visible to executors. Use them for domain-specific context that doesn't fit the standard fields.
## Status Codes
| Status | Meaning |
|--------|---------|
| `pending` | Waiting for executor to claim |
| `claimed` | Executor is working on it |
| `in_progress` | Executor actively working |
| `needs_input` | Executor needs clarification |
| `completed` | Task finished successfully |
| `failed` | Could not complete |
| `declined` | Executor declined the request |
| `cancelled` | Request was cancelled |
## Common Patterns
### Create and Wait
```python
# 1. Create request
mess:
- v: 1.0.0
- request:
intent: Is anyone home?
# 2. Periodically check status
mess_status:
ref: "2026-02-01-001"
# 3. When completed, read the response
```
### Urgent Request
```yaml
- v: 1.0.0
- request:
intent: Did I leave the stove on?
context:
- Just left the house
- Can't remember if I turned it off
priority: urgent
response_hint:
- image
- text
```
### Follow-up After needs_input
```yaml
# Original request got needs_input status
# Executor asked: "Which light?"
# Send clarification (v2.1.0: answer block, message-level re: handled automatically)
- answer:
id: light-clarification
value: "The living room ceiling light, not the lamp"
```
## Resources
The MCP server uses `content://` and `thread://` URIs for attachments and thread data.
### Fetching Attachments
When `mess_status` returns a thread, images and files are referenced as resource URIs:
```yaml
image:
resource: "content://2026-02-01-001/att-002-image-door.jpg"
mime: "image/jpeg"
size: 245891
```
**To fetch the actual image, use `mess_fetch`:**
```yaml
mess_fetch:
uri: "content://2026-02-01-001/att-002-image-door.jpg"
```
This keeps status responses lightweight and avoids blowing up context with large base64 payloads.
### Resource URI Format
```
content://{thread-ref}/{attachment-filename}
```
Examples:
- `content://2026-02-01-001-garage-check/att-002-image-door.jpg`
- `content://2026-02-01-003-fridge/att-005-image-contents.jpg`
### Thread Resources
Read thread data with attachments automatically rewritten to `content://` URIs:
```
thread://{ref} # Full thread (envelope + messages)
thread://{ref}/envelope # Just metadata (status, executor, history)
thread://{ref}/latest # Most recent message only
```
**Example - Read full thread:**
```yaml
# Request: thread://2026-02-01-001
# Response:
envelope:
ref: "2026-02-01-001"
status: completed
intent: Check the garage door
messages:
- from: claude-desktop
MESS:
- request:
intent: Check the garage door
- from: teague-phone
MESS:
- response:
content:
- image:
resource: "content://2026-02-01-001/att-001-door.jpg"
- "Door is closed"
```
**Example - Read just envelope:**
```yaml
# Request: thread://2026-02-01-001/envelope
# Response:
ref: "2026-02-01-001"
status: completed
executor: teague-phone
updated: "2026-02-01T22:05:00Z"
```
## Error Handling
**Thread not found:**
```yaml
error: "Thread 2026-02-01-999 not found"
```
**Missing required field:**
```yaml
error: "Missing re: field"
```
**GitHub API error:**
```yaml
error: "GitHub API error: 401"
```
## File Locations
### macOS
- Config: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Local MESS dir: `~/.mess/`
### Linux
- Config: `~/.config/claude/claude_desktop_config.json`
- Local MESS dir: `~/.mess/`
### Windows
- Config: `%APPDATA%\Claude\claude_desktop_config.json`
- Local MESS dir: `%USERPROFILE%\.mess\`
---
## Skill Companion Files
> Additional files collected from the skill directory layout.
### README.md
```markdown
# MESS MCP Server
An MCP (Model Context Protocol) server that enables AI agents like Claude to dispatch physical-world tasks to human executors.
## Features
- **GitHub sync**: Tasks sync to/from your GitHub repository
- **Local mode**: Store tasks locally without GitHub
- **Hybrid mode**: Local storage with GitHub backup
- Eight tools: `mess`, `mess_status`, `mess_capabilities`, `mess_request`, `mess_answer`, `mess_cancel`, `mess_fetch`, `mess_wait`
- Resources: `content://` for attachments, `thread://` for thread data
## Installation
```bash
cd mcp
npm install
```
## Configuration
The server supports three modes via environment variables:
### Mode 1: GitHub Only (Recommended for sharing)
All tasks stored in GitHub. Best when multiple executors/agents share the same exchange.
```bash
MESS_GITHUB_REPO=your-username/mess-exchange
MESS_GITHUB_TOKEN=github_pat_xxxxx
MESS_GITHUB_ONLY=true
MESS_AGENT_ID=claude-desktop
```
### Mode 2: GitHub Sync (Hybrid)
Tasks stored locally AND synced to GitHub. Good for offline capability with cloud backup.
```bash
MESS_GITHUB_REPO=your-username/mess-exchange
MESS_GITHUB_TOKEN=github_pat_xxxxx
MESS_DIR=~/.mess
MESS_AGENT_ID=claude-desktop
```
### Mode 3: Local Only
Tasks stored only on local filesystem. Good for single-machine use or testing.
```bash
MESS_DIR=~/.mess
MESS_AGENT_ID=claude-desktop
```
## Environment Variables
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `MESS_GITHUB_REPO` | No | - | GitHub repo in `owner/name` format |
| `MESS_GITHUB_TOKEN` | If using GitHub | - | GitHub Personal Access Token |
| `MESS_GITHUB_ONLY` | No | `false` | Set `true` to disable local storage |
| `MESS_DIR` | No | `~/.mess` | Local directory for task files |
| `MESS_AGENT_ID` | No | `claude-agent` | Identifier for this agent |
| `MESS_CAPABILITIES_DIR` | No | `../capabilities` | Directory containing capability definitions |
| `MESS_SYNC_ENABLED` | No | `true` | Enable background sync for change notifications |
| `MESS_SYNC_INTERVAL` | No | `30000` | Sync interval in milliseconds |
## Setting up with Claude Desktop
### macOS
Edit `~/Library/Application Support/Claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"mess": {
"command": "node",
"args": ["/absolute/path/to/mcp/index.js"],
"env": {
"MESS_GITHUB_REPO": "your-username/mess-exchange",
"MESS_GITHUB_TOKEN": "github_pat_xxxxx",
"MESS_GITHUB_ONLY": "true",
"MESS_AGENT_ID": "claude-desktop"
}
}
}
}
```
### Linux
Edit `~/.config/claude/claude_desktop_config.json` with the same structure.
### Windows
Edit `%APPDATA%\Claude\claude_desktop_config.json` with the same structure.
After editing, restart Claude Desktop.
## Setting up with Claude Code
Add to your Claude Code MCP settings or use the command line:
```bash
export MESS_GITHUB_REPO=your-username/mess-exchange
export MESS_GITHUB_TOKEN=github_pat_xxxxx
export MESS_GITHUB_ONLY=true
export MESS_AGENT_ID=claude-code
node /path/to/mcp/index.js
```
## Self-Hosting Locally (No Cloud)
For a completely local setup without GitHub:
### 1. Create the local exchange directory
```bash
mkdir -p ~/.mess/{received,executing,finished,canceled}
```
### 2. Configure Claude Desktop for local mode
```json
{
"mcpServers": {
"mess": {
"command": "node",
"args": ["/absolute/path/to/mcp/index.js"],
"env": {
"MESS_DIR": "~/.mess",
"MESS_AGENT_ID": "claude-desktop"
}
}
}
}
```
### 3. Run the client locally
Open `client/index.html` directly in your browser. When configuring:
1. Skip the GitHub token step (click "I have my token")
2. For repository, you'll need to set up a local adapter (see below)
**Note:** The web client currently requires GitHub. For fully local operation, you can:
- View task files directly in `~/.mess/received/`
- Use any text editor to respond to tasks
- Create a simple local web server (future enhancement)
### Local File Format
Tasks are stored as YAML files in `~/.mess/<status>/<ref>.messe-af.yaml`:
```yaml
ref: 2026-02-01-001
requestor: claude-desktop
executor: null
status: pending
created: 2026-02-01T10:00:00Z
updated: 2026-02-01T10:00:00Z
intent: Check if the garage door is closed
priority: normal
history:
- action: created
at: 2026-02-01T10:00:00Z
by: claude-desktop
---
from: claude-desktop
received: 2026-02-01T10:00:00Z
channel: mcp
MESS:
- v: 1.0.0
- request:
intent: Check if the garage door is closed
context:
- Getting ready for bed
response_hint:
- image
```
## Tools Available
### `mess`
Send a MESS protocol message to create or update requests.
**Create a request:**
```yaml
- v: 1.0.0
- request:
intent: Check if the garage door is closed
context:
- Getting ready for bed
priority: normal
response_hint:
- image
```
**Cancel a request:**
```yaml
- cancel:
re: 2026-02-01-001
reason: No longer needed
```
### `mess_status`
Check status of requests.
- Without `ref`: Lists all pending/in-progress requests
- With `ref`: Returns full details including message history
### `mess_capabilities`
List available physical-world capabilities for this exchange.
- Without `tag`: Lists all capabilities
- With `tag`: Filters by tag (e.g., "security", "attachments")
**Response format:**
```yaml
- id: camera
description: Take and attach photos
tags: [attachments]
- id: check-door
description: Check if doors are locked or closed
tags: [security, physical-access]
```
Capabilities are defined in `capabilities/*.yaml` files. See [docs/capabilities.md](../docs/capabilities.md) for the format.
### `mess_request`
Create a new physical-world task request (simpler than raw `mess` tool).
**Parameters:**
- `intent` (required): What you need done
- `context`: Array of relevant context strings
- `priority`: `background`, `normal`, `elevated`, or `urgent`
- `response_hints`: Expected response types (`text`, `image`, `video`, `audio`)
**Example:**
```json
{
"intent": "Check if the garage door is closed",
"context": ["Getting ready for bed"],
"priority": "elevated",
"response_hints": ["image"]
}
```
### `mess_answer`
Answer an executor's question (when status is `needs_input`).
**Parameters:**
- `ref` (required): Thread ref
- `answer` (required): Your answer
### `mess_cancel`
Cancel a pending or in-progress request.
**Parameters:**
- `ref` (required): Thread ref to cancel
- `reason`: Why you're cancelling (optional)
### `mess_fetch`
Fetch content from MESS resource URIs. Use this to retrieve images, files, or thread data referenced in responses.
**Parameters:**
- `uri` (required): Resource URI
**Supported URIs:**
- `content://{ref}/{filename}` - Attachments (images, files)
- `thread://{ref}` - Full thread data
- `thread://{ref}/envelope` - Thread metadata only
- `thread://{ref}/latest` - Most recent message
- `mess://help` - Protocol documentation
**Example:**
```json
{ "uri": "content://2026-02-01-001/photo.jpg" }
```
For images, returns base64-encoded data with mime type.
### `mess_wait`
Wait for changes to threads instead of polling `mess_status` repeatedly.
**Parameters:**
- `ref`: Optional thread ref to watch specifically
- `timeout`: Max seconds to wait (default: 60, max: 43200 / 12 hours)
**Example:**
```json
{ "ref": "2026-02-01-001", "timeout": 3600 }
```
**Returns:**
```yaml
updated:
- ref: "2026-02-01-001"
status: claimed
hasUpdates: true
waited: 5
timedOut: false
```
Poll frequency scales with timeout (~30 polls): 60s→2s, 1h→2min, 12h→24min. Returns empty `updated` array if timeout expires with no changes.
## Resources
### `content://` - Attachments
Fetch attachment content from threads:
```
content://{thread-ref}/{filename}
```
### `thread://` - Thread Data
Read thread data with attachments rewritten to `content://` URIs:
```
thread://{ref} # Full thread (envelope + messages)
thread://{ref}/envelope # Just metadata (status, executor, history)
thread://{ref}/latest # Most recent message only
```
## Troubleshooting
### "MESS MCP Server started" but no tools appear
- Restart Claude Desktop after config changes
- Check the config file path is correct for your OS
- Verify JSON syntax is valid
### GitHub API errors
- Ensure your token has `Contents: Read and write` permission
- Token must have access to the specific repository
- Check repo name format is `owner/repo` not a URL
### Permission errors on local files
```bash
# Fix permissions
chmod -R 755 ~/.mess
```
## Background Sync
The MCP server automatically polls for changes to tracked threads and sends MCP notifications when state changes (claimed, completed, needs_input, etc.).
- **Enabled by default**: Set `MESS_SYNC_ENABLED=false` to disable
- **30-second interval**: Adjust with `MESS_SYNC_INTERVAL=60000` (in ms)
- **Tracks agent-created threads**: Only threads you create are monitored
- **MCP notifications**: Sends `resources/updated` for `thread://{ref}` URIs
This allows Claude Desktop to be notified when:
- A human claims your request
- A task is completed with a response
- The executor needs clarification (needs_input)
## Development
Run the server directly for testing:
```bash
# GitHub mode
MESS_GITHUB_REPO=user/repo MESS_GITHUB_TOKEN=ghp_xxx node index.js
# Local mode
MESS_DIR=~/.mess node index.js
```
The server communicates via stdio, so you'll see startup logs on stderr.
```