Skip to main content
Glama

productive-mcp

M4 work starts with native HTTPS and readiness checks. The complete internet deployment and recovery path remains unfinished.

A shared coordination hub for MCP agents. Agents connect to one running server over the network (streamable HTTP) and share state through a real Postgres database, so a registration, a ticket, a memory entry, or a discussion post made by one agent is visible to every other agent immediately.

M3 adds tickets, atomic claims, dependencies, and human approval gates. M2 adds agent profiles, capability lookup, and profile ownership rules. M1 provides accounts, scoped credentials, password sessions, and audit events. Every MCP call needs an active bearer token. See PROJECT_STATUS.md for the current milestone and MILESTONES.md for later work.

Documentation

The architecture plans define the testing, deployment, authentication, authorization, and auditing strategies. The agent registry guide explains registration, capability lookup, profile administration, and the M1 upgrade.

The ticket guide explains the state machine, human approval, and how to file work for agents.

Related MCP server: LLM Bus

Install

Use Python 3.14 or later. From the repository root, install into an active virtual environment:

python -m pip install .

The release workflow publishes wheels and source archives to GitHub releases. For an artifact installation, download a wheel from a successful release and run python -m pip install /path/to/downloaded.whl with its actual path. The project does not currently publish to PyPI. A checkout provides the configuration templates and Alembic migrations used in this guide.

Configure

cp .env.example .env

Set different values for POSTGRES_PASSWORD and PRODUCTIVE_MCP_RUNTIME_PASSWORD. Both passwords must stay outside source control. The runtime password must contain at least 20 characters.

The migration account owns schema changes. The server uses the separate, restricted runtime role. This role can read and update identity data. It can only read and insert audit events.

Run

Fully containerized

docker compose up -d postgres
alembic upgrade head
productive-mcp database
docker compose up -d --build app

Compose binds PostgreSQL and the hub to 127.0.0.1. The data volume survives docker compose down. docker compose down -v removes it.

Locally, against a containerized database

Start Postgres only, then run the hub as a normal Python process - the faster loop for active development, since code changes don't need an image rebuild:

docker compose up -d postgres
alembic upgrade head
productive-mcp database
productive-mcp serve

productive-mcp database creates the restricted runtime role. It uses the runtime password from .env when present. Run it once after migration. Use --if-exists for an idempotent provision step.

The hub listens on 127.0.0.1:8765 and exposes whoami and ping over streamable HTTP. Do not expose this endpoint to an untrusted network. M4 adds native TLS.

Create accounts and credentials

Run these commands on the database host. The first command creates the first human administrator and shows an API key once. Store the key in a password manager.

productive-mcp account bootstrap cliff
productive-mcp account create build-agent --kind agent
productive-mcp credential issue ACCOUNT_ID --name claude-code --scope read

The second command prints the agent account ID. Replace ACCOUNT_ID with this value. credential issue prints the API key once. The scopes are read, write, and admin. A higher scope includes the lower scopes.

Use productive-mcp credential revoke CREDENTIAL_ID to stop one credential. Use productive-mcp account disable ACCOUNT_ID to stop every credential and session for an account. Use productive-mcp account recover USERNAME only on the database host to restore an existing human administrator.

Configure an MCP client

Create a local-only MCP configuration. Do not commit the API key.

{
  "mcpServers": {
    "productive-mcp": {
      "type": "http",
      "url": "http://127.0.0.1:8765/mcp",
      "headers": { "Authorization": "Bearer pmk_replace_this_value" }
    }
  }
}

For a password credential, run productive-mcp login USERNAME. The command prints a short-lived session token. Use this token in the same header. It refuses non-loopback HTTP URLs. Run whoami when the client starts.

To reach a VM from the host, first run this command in a separate terminal:

vagrant ssh -- -N -L 8765:127.0.0.1:8765

Check the client with a one-off Claude Code session. --strict-mcp-config ignores other configured servers:

claude --strict-mcp-config --mcp-config .mcp.config \
  -p "Call whoami, then ping." \
  --allowedTools "mcp__productive-mcp__whoami,mcp__productive-mcp__ping"

The migration commands use PRODUCTIVE_MCP_DATABASE_URL when set. The server uses PRODUCTIVE_MCP_RUNTIME_DATABASE_URL or the runtime username and password. See config.py for the configuration names.

Data

State lives in Postgres. Schema changes go through Alembic migrations in alembic/versions/ - never a hand edit to a live schema.

Develop

cp .env.example .env  # then set both database passwords
python -m venv .venv
.venv/Scripts/activate  # or source .venv/bin/activate on Linux/macOS
pip install -e ".[dev]"
docker compose up -d postgres
alembic upgrade head
productive-mcp database
pytest

Local runs skip database tests if PostgreSQL is unavailable. To require all database tests, run pytest --require-database. CI uses this option, and a true CI environment variable also makes database failures fatal. Empty, 0, and false values disable the environment-based requirement.

Develop in a VM

vagrant up builds a Fedora 44 VM, starts PostgreSQL, applies migrations, provisions the runtime role, and starts the app container. Set both passwords in .env before you run it.

When it finishes, tunnel the app to the host before you use an MCP client. The tunnel command appears in Configure an MCP client.

The venv it also set up inside the VM (~/venv) is there for the faster native dev loop, not required for the above:

vagrant ssh
source ~/venv/bin/activate
cd /vagrant
productive-mcp serve

vagrant halt followed by vagrant up won't bring the container back on its own - provisioning (and starting the app) only runs once unless you pass --provision or run vagrant provision again.

Security

See SECURITY.md for the reporting path and current threat model notes.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Framework-agnostic MCP server for agent memory with Postgres + pgvector, enabling persistent memory, recall, and task management across sessions.
    MIT
  • A
    license
    B
    quality
    C
    maintenance
    MCP server that provides a live coordination layer for AI agents, including attributable handoffs, a shared event ledger, atomic work-claiming, and advisory file leases to prevent collisions.
    27
    9
    AGPL 3.0
  • F
    license
    Not graded
    quality
    B
    maintenance
    A production-grade MCP server over Postgres, providing secure data operations with tenant isolation, exact-once mutations, loop-aware rate limiting, and a tamper-evident audit trail.
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides persistent, scoped shared memory for collaborating AI agents, with tools for storing observations, semantic recall, and handoff workflows. Backed by PostgreSQL and exposed through MCP.
    1
    Apache 2.0