projectstate

online.projectstatePublished by projectstate.onlineOfficial publisherv0.3.0Updated Oct 28, 2026

Per-project memory for AI agents: decisions, attempts, tasks, ranked recall. Paid per call via x402.

VerifiedStreamable HTTPWeb executableProductivity & WorkflowKnowledge & Memory

Overview

AI-generated overview

Per-project memory for AI agents: stores decisions, attempts and tasks, and returns ranked, budgeted recall — paid per call in USDC over x402.

What you can do
  • Open or create a project and get a compact brief of status, open tasks, active decisions and failed attempts
  • Read or overwrite the one-line project status as a hand-off note between sessions
  • Store decisions, attempts, tasks and notes with tags and file references
  • Search project memory by keyword with filters on kind, status, tags and files, trimmed to a character budget
  • Check a planned intent against prior failures, binding decisions and overlapping tasks before starting work
  • Update or delete existing entries: close tasks, mark attempts, supersede decisions
When to use it
Useful when several agents or sessions (coding assistants, CI agents, scripts) work on the same repository and need one shared, compact record of what was decided, what failed and what is still open. The plan_check tool is aimed at avoiding repeated dead ends before non-trivial work.
Requirements
Remote Streamable HTTP endpoint; no account or API key. An x402-capable client and a crypto wallet able to sign USDC payments on Base mainnet, since each call is paid; a credit token can be reused as a bearer credential after the first payment.
Before you install
Every tool call costs money in USDC (roughly $0.002 to $0.010 per call), so an agent can spend funds on its own; a wallet signing key is needed client-side. Payments go to a third-party service on Base mainnet, and stored project facts are sent to that service. Entries can be overwritten or deleted by the update tool.

Installation

In SourceWeft

  1. Open projectstate in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.

Use with an agent

Paste this prompt into Claude Code, Codex, Cursor or another agent — or into SourceWeft chat. The agent reads this server's install guide, shows you its publisher, endpoint and sign-in, and adds it to your client once you agree. Keys never go into a command.

Read https://sourceweft.com/mcp/online.projectstate%2Fprojectstate/install.md and connect the MCP server it describes to my client. Before changing any config, show me its publisher, endpoint and sign-in method and wait for my OK. Never put an API key in a command or in a file I would commit; ask me where it should come from.

Read the install guide the agent follows

Other MCP clients

Add this to your client's mcpServers config.

{
  "mcpServers": {
    "projectstate": {
      "type": "http",
      "url": "https://projectstate.online/mcp"
    }
  }
}

README

projectstate

Persistent project memory for AI agents, paid per call in USDC over x402. No account, no API key.

https://projectstate.online/mcp — an MCP server (Streamable HTTP) that remembers, per project, what was decided, what was tried and failed, and what is still open, and hands an agent back the three facts it needs instead of the whole history.

Why

Every agent already has "memory". What it does not have is project state that survives across tools and sessions: Claude Code, Cursor, a CI agent and a script all working on the same repo, sharing one ranked, compact record of decisions and dead ends. That is what this is. Retrieval is the point: recall returns at most a few lines inside a character budget, ranked so superseded decisions sink and active ones float.

Tools

ToolDoesPrice
project_open(project, name?, description?)open/create a project; returns a brief: status, open tasks, latest decisions, failed attempts$0.002
project_status(project, set_status?)read or set the one-line status (hand-off note between sessions)$0.002
remember(project, kind, title, body?, tags?, files?, status?, supersedes?, idempotency_key?)store a decision, attempt, task or note$0.002
recall(project, query?, kind?, status?, tags?, files?, limit=5, max_chars=1500)ranked keyword search, trimmed to a budget$0.005
plan_check(project, intent, files?, limit=3, max_chars=1200)say what you are about to do; get back the failed attempts, binding decisions and overlapping tasks that would change the plan$0.010
update(project, id, status?, title?, body?, append?, tags?, files?, delete?)close tasks, mark attempts, supersede decisions$0.002

Failed calls are free. Identical retries (or any call with the same idempotency_key) are never billed twice. Prices are published per tool in tools/list under _meta.priceUsd.

plan_check

The tool to call before starting something non-trivial:

plan_check(project="my-app", intent="switch the session cache to Redis", files=["src/cache.py"])
Plan check for 'my-app': 'switch the session cache to Redis'Prior failures (1):  #8 attempt/failed (2026-09-12): Tried Redis for the session cache — connection pool exhausted under loadActive decisions that constrain this (1):  #9 decision/active (2026-09-12): Cache with SQLite instead of Redis — one less service to runOpen tasks that overlap (1):  #10 task/open (2026-09-12): Benchmark the cache options

Three targeted searches in one call, returning only what would change the plan. A clean plan answers "Nothing on record matches this plan" so the agent can proceed without a second lookup.

How paying works

  1. Call a tool. Without credit the result is isError: true with an x402 v2 PaymentRequired in structuredContent (scheme exact, USDC on Base, the amount, the pay-to address).
  2. Sign the USDC payment and retry the same call with the payload in _meta["x402/payment"].
  3. The result carries the settlement receipt in _meta["x402/payment-response"] and a credit token in _meta["projectstate/x402-credit"].
  4. One payment buys credit ($0.10 on a session-based connection, $0.01 minimum per call without one). Later calls draw from it automatically on a session, or by sending the credit token as Authorization: Bearer xc_…. Unused credit stays on your wallet address.

Works with any x402-capable client: x402-mcp (withPayment()) for the Vercel AI SDK, the x402 Python package, or the 30-line handshake in scripts/x402_agent_demo.py.

python
from eth_account import Accountfrom mcp import Clientfrom x402 import x402Clientfrom x402.mechanisms.evm.exact import register_exact_evm_clientfrom x402.mechanisms.evm.signers import EthAccountSignerfrom x402.schemas import PaymentRequired
x = x402Client(); register_exact_evm_client(x, EthAccountSigner(Account.from_key(KEY)))async with Client("https://projectstate.online/mcp") as mcp:    r = await mcp.call_tool("project_open", {"project": "my-app"})       # -> PaymentRequired    pay = (await x.create_payment_payload(PaymentRequired(**r.structured_content))).model_dump(by_alias=True, exclude_none=True)    r = await mcp.call_tool("project_open", {"project": "my-app"}, meta={"x402/payment": pay})    token = r.meta["projectstate/x402-credit"]                          # reuse on later calls

What is under the hood

Python 3.12, the official MCP Python SDK (v2), SQLite + FTS5 (bm25, no vectors), the official x402 package against the Coinbase facilitator on Base mainnet. One process, one SQLite file, an admin dashboard with per-tool latency, error messages, a full audit ledger and a retrieval-quality meter (zero-hit and re-query rates) that says when keyword search stops being enough.

Docs: https://projectstate.online/docs · Registry: online.projectstate/projectstate · License: MIT

Run your own

deploy/install.sh sets up systemd, nginx, fail2ban, hourly SQLite backups and unattended upgrades on a small Ubuntu VPS; deploy/env.example lists every setting; deploy/x402_live_setup.sh switches the x402 rail to Base mainnet with Coinbase CDP keys. pytest tests/ runs 33 tests including a mock x402 facilitator that verifies real EIP-712 signatures.

Source: README.md at commit a8db121

Tools

6

project_open

Open project

Open (or create) a project and get a compact brief: status line, open tasks, latest active decisions and failed attempts. Call this first in a session. Omit `project` to list your projects. `project` is a slug like 'my-app' (lowercase, digits, '-', '_' or '.').

Parametersnameprojectdescription

project_status

Project status

Get the project's one-line status, open tasks and last change. Pass `set_status` to overwrite the status line (e.g. 'v0.3 shipped; next: migrate auth to OAuth'). Cheap; use it for handoff notes between sessions.

Parametersprojectrequiredset_status

remember

Remember

Store one fact about the project. `kind` is one of: decision (what was chosen and why), attempt (something tried; status 'worked'|'failed'|'partial'), task (status 'open'|'done'|'dropped'), note (anything else). `title` is one line; put details, reasons and error messages in `body`. `files` lists related paths. `supersedes` marks an older decision/task as replaced by this one. Identical content is stored once, so retries are safe; `idempotency_key` additionally guarantees a retry is not billed twice.

Parametersbodykindrequiredtagsfilestitlerequiredstatusprojectrequiredsupersedesidempotency_key

recall

Recall

Search the project's memory with keywords and get the few most relevant entries (ranked, active entries first, superseded ones last), trimmed to `max_chars`. Use 2-5 specific keywords (e.g. 'auth token expiry'). Filters: kind (decision|attempt|task|note), status, tags, files. Omit `query` for the most recent entries. Follow up with update(project, id, ...) or remember(...).

Parameterskindtagsfileslimitquerystatusprojectrequiredmax_chars

plan_check

Plan check

Before you start something non-trivial, say what you are about to do and get back only what would change your mind: attempts that already failed at this, decisions that are still in force and constrain it, and open tasks that overlap. `intent` is one line in plain words, e.g. 'switch the cache to Redis' or 'rewrite the auth middleware to use refresh tokens'. Pass `files` if you know which paths you will touch; entries about those files are included even when the wording differs. Cheaper than repeating work that already failed once.

Parametersfileslimitintentrequiredprojectrequiredmax_chars

update

Update entry

Change an existing entry by id: set `status` (task open|done|dropped, attempt worked|failed|partial, decision active|superseded|reverted, note active|archived), replace `title`/`body`, `append` a line to the body (e.g. an outcome), replace `tags`/`files`, or `delete` it.

Parametersidrequiredbodytagsfilestitleappenddeletestatusprojectrequired

Version history

1
  1. v0.3.0LatestSep 16, 2026

Score

100% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 daysRequired25 pts
  • Auth declaredRequired10 pts
  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts