# chatctx documentation

> chatctx serves concise, owner-reviewed engineering guidance to coding agents over the Model Context Protocol. Read-only retrieval, source provenance, explicit no-match. No generative model runs in the retrieval path.

- Endpoint: `https://chatctx-mcp.brackket.workers.dev/mcp`
- Site: `https://chatctx.pages.dev/`
- Transport: MCP Streamable HTTP, stateless
- Tools: `search_knowledge`, `get_guidance`, `submit_feedback`
- Machine-readable index: `https://chatctx.pages.dev/llms.txt`
- Full documentation: `https://chatctx.pages.dev/llms-full.txt`

## Connection

- Endpoint: `https://chatctx-mcp.brackket.workers.dev/mcp`
- `POST` for JSON-RPC requests and notifications; `GET` opens a keep-alive SSE stream.
- No `Mcp-Session-Id` is issued or required.
- Requests use `Content-Type: application/json` and must send `Accept: application/json, text/event-stream`.
- Responses are SSE-framed: parse the `data:` line, not the whole body.
- Server name: `chatctx-knowledge`. Capabilities: tools only.
- Handshake: `initialize` → `notifications/initialized` → `tools/list` or `tools/call`.

## Authentication

Send `Authorization: Bearer <key>`, where keys look like `kb_live_<prefix>_<secret>`. Keys are stored as HMAC-SHA256 hashes with a server-side pepper and can be revoked or quota-limited by the owner.

Anonymous guest access is enabled on production: 250 tool calls per client IP per UTC day. An invalid or revoked bearer token returns `401` and never falls through to guest access.

## Tools

### search_knowledge

Hybrid retrieval over approved guidance: PostgreSQL full-text plus pgvector cosine search, fused ranking, applicability bonuses, token-budget shaping.

| Argument | Type | Rules | Default |
| --- | --- | --- | --- |
| `query` | string | required, 2–2,000 chars | — |
| `technologies` | string[] | max 10, each 1–80 chars | `[]` |
| `versions` | object | max 20 keys, short string values | `{}` |
| `topic` | enum \| enum[] | max 3 in an array | none |
| `task_type` | enum | see below | none |
| `max_results` | integer | 1–10 | `5` |
| `detail` | enum | `brief` \| `standard` | `brief` |
| `token_budget` | integer | 200–5,000 | `2500` |

Topics: `architecture`, `implementation`, `security`, `accessibility`, `ux`, `reliability`, `testing`, `performance`, `data`, `observability`, `tooling`.

Task types: `build`, `architecture`, `debug`, `security`, `accessibility`, `performance`, `testing`, `review`, `other`.

Unknown arguments are rejected. Phrase the query as the decision being made.

### get_guidance

Fetch the full record behind a search hit: exceptions, pitfalls, verification checks, version constraints, examples, provenance.

| Argument | Type | Rules | Default |
| --- | --- | --- | --- |
| `ids` | string[] | required, 1–10 slugs or ids | — |
| `detail` | enum | `brief` \| `full` | `full` |

Unknown, deprecated, or non-public identifiers are returned in `missing` instead of failing the call.

### submit_feedback

Anonymous signal about retrieval quality. Never used automatically as ranking input.

| Argument | Type | Rules | Default |
| --- | --- | --- | --- |
| `category` | enum | `helpful`, `not_helpful`, `incorrect`, `outdated`, `missing`, `other` | — |
| `record` | string | optional approved slug or id, 1–120 chars | none |
| `source` | enum | `search_knowledge`, `get_guidance`, `other` | `other` |
| `comment` | string | optional, 1–1,000 chars | none |

Do not send source code, secrets, credentials, customer data, or personal information. Feedback stores no API key, IP address, user agent, or client identifier.

## Response shape

```json
{
  "query_summary": "implementation · React",
  "results": [
    {
      "id": "…",
      "slug": "use-stable-keys-for-dynamic-react-lists",
      "title": "…",
      "topic": "implementation",
      "summary": "…",
      "recommendation": "…",
      "rationale": "…",
      "applies_to": [{ "kind": "framework", "name": "React", "version_constraint": "≥16.0" }],
      "conditions": ["…"],
      "exceptions": ["…"],
      "pitfalls": ["…"],
      "verification_checks": ["…"],
      "confidence": "high",
      "updated_at": "2026-10-18T…",
      "sources": [
        {
          "title": "…",
          "url": "https://…",
          "publisher": "…",
          "evidence_excerpt": "…",
          "relation": "supports"
        }
      ]
    }
  ],
  "retrieval": {
    "mode": "hybrid",
    "degraded": false,
    "embedding_provider": "cloudflare-workers-ai",
    "embedding_cache": "hit",
    "total_candidates": 20
  },
  "suggestions": ["…"]
}
```

`get_guidance` returns `{ "results": [...], "missing": [...] }`. Each record adds `status`, `content_version`, `approved_at`, and optionally `version_constraints` and `examples`.

## Retrieval modes

- `hybrid` — text and vector results fused. Normal operation.
- `keyword_fallback` — no query embedding available; full-text only. Inspect `degraded_reason`; recall is lower, the returned text is unchanged.
- `no_match` — nothing cleared the relevance threshold. `results` is empty and `suggestions` explains how to broaden the query. This means “not in the knowledge base”, not “error”.

`degraded: true` means part of the retrieval path failed. `technology_filter_fallback: true` means technology filters were too narrow and the server retried without them.

## Errors and limits

| Status | Meaning | Action |
| --- | --- | --- |
| `401` | Missing, malformed, or revoked key | Fix the bearer token or use guest access |
| `403` | Host or origin not allowed | Use the documented endpoint host |
| `406` | Missing SSE `Accept` value | Send `Accept: application/json, text/event-stream` |
| `429` | Daily quota exhausted | Back off until `Retry-After`; request a higher quota |

Invalid tool arguments return a successful JSON-RPC response with `result.isError: true` and a validation message. Domain failures use the same envelope with a stable `error.code`. Internal failures never include stack traces or query text.

## Privacy

- Raw search queries are not written to logs.
- Retrieval analytics store a salted hash plus topic, technology filters, mode, result count, and degraded state.
- Query embeddings are cached by hash, model, and dimension; raw query text is never stored.
- Feedback excludes API key ids, IP addresses, user agents, and client identifiers.
- Guest quota accounting stores an HMAC-SHA256 hash of the client IP.

## Trust model

- Only owner-reviewed, approved records are served. Unreviewed candidates never reach the public endpoint.
- Every result carries source links, the evidence relation, and record timestamps.
- Embeddings only find candidate records; the guidance text is human-authored and reviewed.
- Weak matches return `no_match` instead of a plausible-sounding record.

## Machine-readable files

| Path | Content type | Use |
| --- | --- | --- |
| `/llms.txt` | text/plain | Compact index for models |
| `/llms-full.txt` | text/plain | Full documentation in one file |
| `/docs.md` | text/markdown | This reference |
| `/api.json` | application/json | JSON Schemas, limits, errors |
| `/agent-instructions.md` | text/markdown | Copy-paste agent policy |
| `/mcp.json` | application/json | Client configuration snippet |
