Skip to main content
Glama

shed-mcp

A small self-hosted MCP gateway between ChatGPT and private shed-* applications. Phase 1 exposes Shed Life Todos through seven narrowly scoped tools. Shed Life remains the source of truth; this gateway calls its HTTP API and has no database or copied task store.

ChatGPT → OpenAI Secure MCP Tunnel → tunnel-client → shed-mcp /mcp → Shed Life API

Operators are responsible for securing the downstream applications they expose. Run this single-account gateway on a trusted private host. It is not a remote administration interface. No shell, file, SQL, code-execution or arbitrary HTTP tools exist. MIT licensed; version 0.1.0 is pre-release.

Tools

Tool

Behavior

Annotations

create_task

Persist a requested actionable todo; title required, optional description/date/categories

Write, non-destructive, non-idempotent

list_tasks

Open tasks by default; status, today/overdue/upcoming, category and substring query filters

Read-only, idempotent

get_task

One task by stable UUID

Read-only, idempotent

update_task

Only supplied title/description/due_date/categories; omitted fields unchanged

Write, destructive, idempotent

complete_task

Mark a known task completed

Write, non-destructive, idempotent

reopen_task

Reopen a completed task

Write, non-destructive, idempotent

delete_task

Permanent deletion, no undo; explicit request and confirm=true required

Write, destructive, idempotent

All tools set openWorldHint=false because they address one bounded private account. Annotations are hints, not permissions. IDs come from task results; clients should search and clarify ambiguous matches before writes. Categories are existing names resolved to backend IDs; they are never implicitly created.

due_date is a real date-only YYYY-MM-DD. TIMEZONE determines the reference date for list filters, not a timestamp conversion; explicit today overrides it. Today equals that date, overdue is before it, upcoming after it. Undated tasks match none. Filters combine with AND. Set status=all to include completed tasks. PATCH null clears due date; empty description clears notes; empty categories clears membership.

“Add buy milk for tomorrow” should create a task after resolving the date. “How should I organize my todo list?” should stay conversational. See evaluation prompts.

Related MCP server: TODO MCP Server

Local development

Install stable Rust (edition 2024) and Node.js 24+ for development tools, then:

npm ci
cp .env.example .env
# Edit the backend origin and timezone for your deployment.
npm run check
set -a
. ./.env
set +a
cargo run --locked

The gateway reads its environment; the example shell loads your trusted local .env. Systemd reads its private EnvironmentFile directly. Required backend configuration is validated at startup. Basic tests use a mock downstream and require no credentials. The production server uses the official Rust MCP SDK; architecture and SDK choice records maturity and current protocol support. Node.js is needed only for tests and Inspector, not to run the gateway. Build a production executable with cargo build --release --locked.

Configuration

Environment variable

Default / requirement

SHED_LIFE_BASE_URL

Required HTTP(S) origin, e.g. http://127.0.0.1:8080; no path/query/credentials

MCP_BIND_ADDRESS

127.0.0.1; explicit IPv4/IPv6 address

MCP_PORT

4317

REQUEST_TIMEOUT_MS

5000; 1–120000

TIMEZONE

UTC; IANA timezone, e.g. Europe/London

LOG_LEVEL

info; error or silent also supported

MCP_ALLOWED_HOSTS

localhost/loopback by default; comma-separated URL hostnames, required for non-loopback binds

The stable Streamable HTTP endpoint is /mcp. /healthz reports gateway process health, not backend readiness. Success/failure tool logs include name, safe error code and latency without task payloads. Backend outages are reported on tool invocation.

Compatible Shed Life API

Run your own compatible Shed Life service and configure its origin. Its v0.1.0 API must provide task GET/POST/PATCH/DELETE routes, completion/reopening, and category GET as described in architecture. Its documented default port is 8092; the generic .env.example origin is a placeholder. Never point this gateway at a database file.

Run the optional live lifecycle test only against a trusted gateway backed by a deployment you are authorized to modify:

MCP_TEST_URL=http://127.0.0.1:4317/mcp npm run verify:live

It creates one uniquely named temporary task, exercises all seven tools, deletes it, and verifies absence. It prints no personal task list. See verification.

MCP Inspector

With the gateway running:

npx @modelcontextprotocol/inspector --web
# Select Streamable HTTP and http://127.0.0.1:4317/mcp through the Inspector proxy.
npx @modelcontextprotocol/inspector --cli http://127.0.0.1:4317/mcp --transport http --method tools/list
npm run verify:inspector

The automated Inspector verification creates a mock backend and temporary loopback gateway, discovers schemas/descriptions/annotations, invokes every tool and checks malformed input. The browser UI must use Inspector's local proxy because gateway Origin requests are rejected. Initialization and both modern discovery and legacy protocol behavior are SDK responsibilities; transport tests exercise them.

Private deployment and ChatGPT

For a dedicated system service, adapt the generic unit, create a dedicated service user, install the release executable as /opt/shed-mcp/shed-mcp, and keep a mode-0600 environment file under /etc/shed-mcp/environment. Keep the listener private, preferably loopback beside the tunnel client.

For a user service, run cargo build --release --locked first and create a private environment file outside tracked content:

chmod 600 /path/to/private/environment
python3 scripts/install-user-service.py --environment /path/to/private/environment
systemctl --user status shed-mcp.service

This installer writes the actual paths into the user's systemd configuration outside Git. It enables boot startup and restart-on-failure. User services need lingering to start without login; check loginctl show-user "$USER" -p Linger and arrange it with your administrator if necessary. No firewall or networking changes are required. See deployment and Secure MCP Tunnel for current OpenAI UI steps, runtime credentials, doctor checks and persistent supervision.

OpenAI's Secure MCP Tunnel guide documents outbound-only connectivity. Provision a tunnel associated with your intended ChatGPT workspace, run the official tunnel client beside this gateway, then add a custom MCP server in ChatGPT with Connection → Tunnel. NEEDS_USER.md lists steps requiring account access. A public source repository does not require a public MCP endpoint or public plugin submission.

Security and limitations

Read SECURITY.md before deployment. This version has no OAuth, per-user account isolation, or internet-facing abuse protection. Loopback trusts local processes; tunnel access must be tightly scoped. Shared deployment requires MCP-compatible authentication and authorization at a private proxy. Do not expose the listener publicly.

Creation is not idempotent in the compatible backend. Writes are never automatically retried; after an uncertain outcome inspect state before retrying. Concurrent writes are last-write-wins. Lists are bounded by a 2 MB response limit and have no pagination until supported by the backend. Future inbox/habit/reminder/calendar/note or other app domains are intentionally unimplemented.

Keep real environment files, keys, tunnel identities, personal URLs, logs and task data outside Git. CONTRIBUTING.md describes checks; PROJECT_STATUS.md records validation and release readiness. Do not publish until history and staged content have been audited.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers