# projectstate

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

- name: online.projectstate/projectstate
- version: 0.3.0
- connection class: R0 (autonomous)
- trust: 93/100
- quality: 83/100 (good)
- owner: not claimed
- descriptor: https://api.protogrid.dev/v1/servers/online.projectstate%2Fprojectstate
- tools: https://api.protogrid.dev/v1/servers/online.projectstate%2Fprojectstate/tools

**An agent can connect right now, no human step.** Remote endpoint, no authentication, reachable on the last probe.

## Connection (mcpServers)

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


## Trust

- hygiene: 100
- liveness: 100
- freshness: 85
- provenance: 85
- drivers: +repository +dns-namespace +website +reachable +uptime-99% ~updated-38d-ago
- Derived from observable signals (official registry feed and our own credential-free probes); no code audit performed.

## Quality 83/100 (good)

### protocol: 88 (weight 25)

- pass `protocol.modern`: supports 2026-07-28 (server/discover)
- pass `protocol.stateless`: answers without a session
- pass `protocol.transport`: streamable HTTP
- warn `protocol.list_ttl`: tools/list declares ttlMs 0, so clients re-fetch it on every use

### authorization: n/a (weight 15)

- n/a `auth.prm`, `auth.as_metadata`, `auth.cimd`: no remote uses OAuth
- n/a `auth.secret_in_url`: no templated URL

### tool hygiene: 71 (weight 30)

- pass `tools.descriptions`: every tool has a description
- pass `tools.description_length`: descriptions are concise
- pass `tools.schemas`: every tool has an object input schema
- fail `tools.annotations`: no tool declares readOnlyHint or destructiveHint, so clients cannot tell safe calls from risky ones
- fail `tools.directory_hints`: no tool declares all four of readOnlyHint, destructiveHint, idempotentHint and openWorldHint; missing: project_status (readOnlyHint, destructiveHint, idempotentHint, openWorldHint); remember (readOnlyHint, destructiveHint, idempotentHint, openWorldHint); recall (readOnlyHint, destructiveHint, idempotentHint, openWorldHint); …
- pass `tools.token_cost`: about 1,406 tokens to load every tool
- pass `tools.api_dump`: tools are not a one-to-one API dump

### stability: 100 (weight 15)

- pass `stability.changes`: no tool changes in 30 days
- pass `stability.rug_pull`: no tool changed its meaning under the same name

### dependencies: n/a (weight 15)

- n/a `deps.known_vulns`, `deps.mcp_sdk_version`, `deps.resolvable`: no npm or PyPI package

- tools: 6, about 1,406 tokens to load them all
- tool set hash: b316081db34ab017e4083622e9dfd0bb
- badge: [![protogrid quality](https://protogrid.dev/badge/online.projectstate/projectstate.svg)](https://protogrid.dev/servers/online.projectstate/projectstate)
- Checks run on what our credential-free, read-only probes observe; tools are never called and no code audit is performed.

### Tool changes

_No tool definition changes recorded._

## Remotes

- https://projectstate.online/mcp (streamable-http, auth none, reachable true, uptime30d 0.9915254)

## Packages

_none_

## Tools (6)

- `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.
- `project_open`: 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 '.').
- `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.
- `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(...).
- `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.
- `update`: 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.
