Skip to content

Commit 4bf45e1

Browse files
committed
Add mailbox and todo MCPs
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
1 parent 3adbaed commit 4bf45e1

6 files changed

Lines changed: 1209 additions & 5 deletions

File tree

.github/workflows/image.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
runs-on: ubuntu-latest
1818
strategy:
1919
matrix:
20-
mcp: [duckduckgo, weather, memory, homeassistant, scripts, localrecall, twitter]
20+
mcp: [duckduckgo, weather, memory, homeassistant, scripts, localrecall, twitter, todo, mailbox]
2121
permissions:
2222
packages: write
2323
contents: read

README.md

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,211 @@ mcp:
765765
}
766766
```
767767

768+
### ✅ TODO Server
769+
770+
A shared TODO list management server that allows multiple agents to coordinate tasks with states and assignees. Perfect for agent team coordination.
771+
772+
**Features:**
773+
- Shared TODO list accessible by multiple agents/processes
774+
- File-based persistence with atomic writes
775+
- File locking for concurrent access safety
776+
- Task states: pending, in_progress, done
777+
- Assignee tracking for task ownership
778+
- Full CRUD operations (add, update, remove, list)
779+
- Status summary with counts by state and assignee
780+
781+
**Tools:**
782+
- `add_todo` - Add a new TODO item to the shared list
783+
- `update_todo_status` - Update the status of a TODO item (pending, in_progress, or done)
784+
- `update_todo_assignee` - Update the assignee of a TODO item
785+
- `remove_todo` - Remove a TODO item by ID
786+
- `list_todos` - List all TODO items
787+
- `get_todo_status` - Get a summary of the TODO list with counts by status and assignee
788+
789+
**Configuration:**
790+
- `TODO_FILE_PATH` - Environment variable to set the TODO file path (default: `/data/todos.json`)
791+
792+
**TODO Item Format:**
793+
```json
794+
{
795+
"id": "1703123456789000000",
796+
"title": "Implement feature X",
797+
"status": "in_progress",
798+
"assignee": "agent1"
799+
}
800+
```
801+
802+
**Add TODO Input Format:**
803+
```json
804+
{
805+
"title": "Implement feature X",
806+
"assignee": "agent1"
807+
}
808+
```
809+
810+
**Update Status Input Format:**
811+
```json
812+
{
813+
"id": "1703123456789000000",
814+
"status": "done"
815+
}
816+
```
817+
818+
**List TODOs Output Format:**
819+
```json
820+
{
821+
"items": [
822+
{
823+
"id": "1703123456789000000",
824+
"title": "Implement feature X",
825+
"status": "in_progress",
826+
"assignee": "agent1"
827+
}
828+
],
829+
"count": 1
830+
}
831+
```
832+
833+
**Status Summary Output Format:**
834+
```json
835+
{
836+
"total": 10,
837+
"pending": 3,
838+
"in_progress": 5,
839+
"done": 2,
840+
"by_assignee": {
841+
"agent1": 4,
842+
"agent2": 6
843+
}
844+
}
845+
```
846+
847+
**Docker Image:**
848+
```bash
849+
docker run -e TODO_FILE_PATH=/custom/path/todos.json -v /host/data:/data ghcr.io/mudler/mcps/todo:latest
850+
```
851+
852+
**LocalAI configuration (to add to the model config):**
853+
```yaml
854+
mcp:
855+
stdio: |
856+
{
857+
"mcpServers": {
858+
"todo": {
859+
"command": "docker",
860+
"env": {
861+
"TODO_FILE_PATH": "/data/todos.json"
862+
},
863+
"args": [
864+
"run", "-i", "--rm", "-v", "/host/data:/data",
865+
"ghcr.io/mudler/mcps/todo:master"
866+
]
867+
}
868+
}
869+
}
870+
```
871+
872+
### 📬 Mailbox Server
873+
874+
A shared mailbox server that enables message exchange between different agents in a team. Each agent instance reads only its own messages while being able to send messages to any agent.
875+
876+
**Features:**
877+
- Shared mailbox accessible by multiple agents/processes
878+
- File-based persistence with atomic writes
879+
- File locking for concurrent access safety
880+
- Agent-specific message filtering
881+
- Read/unread status tracking
882+
- Message deletion (only by recipient)
883+
- Timestamp tracking for all messages
884+
885+
**Tools:**
886+
- `send_message` - Send a message to a recipient agent
887+
- `read_messages` - Read all messages for this agent
888+
- `mark_message_read` - Mark a message as read by ID
889+
- `mark_message_unread` - Mark a message as unread by ID
890+
- `delete_message` - Delete a message by ID (only if recipient matches this agent)
891+
892+
**Configuration:**
893+
- `MAILBOX_FILE_PATH` - Environment variable to set the mailbox file path (default: `/data/mailbox.json`)
894+
- `MAILBOX_AGENT_NAME` - Environment variable for this agent's name (required)
895+
896+
**Message Format:**
897+
```json
898+
{
899+
"id": "1703123456789000000",
900+
"sender": "agent1",
901+
"recipient": "agent2",
902+
"content": "Please review the changes",
903+
"timestamp": "2023-12-21T10:30:56.789Z",
904+
"read": false
905+
}
906+
```
907+
908+
**Send Message Input Format:**
909+
```json
910+
{
911+
"recipient": "agent2",
912+
"content": "Please review the changes"
913+
}
914+
```
915+
916+
**Send Message Output Format:**
917+
```json
918+
{
919+
"id": "1703123456789000000",
920+
"sender": "agent1",
921+
"recipient": "agent2",
922+
"content": "Please review the changes",
923+
"timestamp": "2023-12-21T10:30:56.789Z"
924+
}
925+
```
926+
927+
**Read Messages Output Format:**
928+
```json
929+
{
930+
"messages": [
931+
{
932+
"id": "1703123456789000000",
933+
"sender": "agent1",
934+
"recipient": "agent2",
935+
"content": "Please review the changes",
936+
"timestamp": "2023-12-21T10:30:56.789Z",
937+
"read": false
938+
}
939+
],
940+
"count": 1,
941+
"unread": 1
942+
}
943+
```
944+
945+
**Docker Image:**
946+
```bash
947+
docker run -e MAILBOX_FILE_PATH=/custom/path/mailbox.json -e MAILBOX_AGENT_NAME=agent1 -v /host/data:/data ghcr.io/mudler/mcps/mailbox:latest
948+
```
949+
950+
**LocalAI configuration (to add to the model config):**
951+
```yaml
952+
mcp:
953+
stdio: |
954+
{
955+
"mcpServers": {
956+
"mailbox": {
957+
"command": "docker",
958+
"env": {
959+
"MAILBOX_FILE_PATH": "/data/mailbox.json",
960+
"MAILBOX_AGENT_NAME": "agent1"
961+
},
962+
"args": [
963+
"run", "-i", "--rm", "-v", "/host/data:/data",
964+
"ghcr.io/mudler/mcps/mailbox:master"
965+
]
966+
}
967+
}
968+
}
969+
```
970+
971+
**Note:** Each agent instance must have a unique `MAILBOX_AGENT_NAME` to properly filter and manage its own messages. The mailbox file is shared across all agents, but each agent only sees messages where it is the recipient.
972+
768973
## Development
769974

770975
### Prerequisites
@@ -792,6 +997,8 @@ make MCP_SERVER=shell build
792997
make MCP_SERVER=ssh build
793998
make MCP_SERVER=scripts build
794999
make MCP_SERVER=localrecall build
1000+
make MCP_SERVER=todo build
1001+
make MCP_SERVER=mailbox build
7951002
7961003
# Run tests and checks
7971004
make ci-local
@@ -865,6 +1072,12 @@ Docker images are automatically built and pushed to GitHub Container Registry:
8651072
- `ghcr.io/mudler/mcps/localrecall:latest` - Latest LocalRecall server
8661073
- `ghcr.io/mudler/mcps/localrecall:v1.0.0` - Tagged versions
8671074
- `ghcr.io/mudler/mcps/localrecall:master` - Development versions
1075+
- `ghcr.io/mudler/mcps/todo:latest` - Latest TODO server
1076+
- `ghcr.io/mudler/mcps/todo:v1.0.0` - Tagged versions
1077+
- `ghcr.io/mudler/mcps/todo:master` - Development versions
1078+
- `ghcr.io/mudler/mcps/mailbox:latest` - Latest Mailbox server
1079+
- `ghcr.io/mudler/mcps/mailbox:v1.0.0` - Tagged versions
1080+
- `ghcr.io/mudler/mcps/mailbox:master` - Development versions
8681081

8691082
## Contributing
8701083

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ require (
66
github.com/blevesearch/bleve/v2 v2.5.7
77
github.com/dghubble/oauth1 v0.7.3
88
github.com/g8rswimmer/go-twitter/v2 v2.1.5
9+
github.com/gofrs/flock v0.13.0
910
github.com/mkelcik/go-ha-client v1.0.0
1011
github.com/modelcontextprotocol/go-sdk v1.0.0
1112
github.com/onsi/ginkgo/v2 v2.28.1

go.sum

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v
7676
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
7777
github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
7878
github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
79+
github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw=
80+
github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0=
7981
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
8082
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
8183
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -140,8 +142,8 @@ github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWN
140142
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
141143
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
142144
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
143-
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
144-
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
145+
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
146+
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
145147
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
146148
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
147149
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
@@ -253,8 +255,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
253255
google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A=
254256
google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
255257
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
256-
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
257-
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
258+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
259+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
258260
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
259261
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
260262
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

0 commit comments

Comments
 (0)