mcp-context-card 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.well-known/ai-catalog.json +2 -2
- package/.well-known/fafa +7 -6
- package/AGENTS.md +11 -9
- package/CHANGELOG.md +59 -2
- package/README.md +43 -28
- package/dist/author.d.ts +11 -2
- package/dist/author.js +73 -14
- package/dist/bin.d.ts +9 -5
- package/dist/bin.js +46 -6
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/faf/parse-fafm.js +22 -1
- package/dist/identity.d.ts +1 -1
- package/dist/identity.js +1 -1
- package/dist/render-card.js +2 -2
- package/dist/server.d.ts +4 -4
- package/dist/server.js +10 -9
- package/dist/transport/http.js +4 -4
- package/docs/MECHANISMS.md +5 -5
- package/docs/TRANSPORT.md +4 -4
- package/docs/WIRING.md +13 -3
- package/docs/card.html +6 -6
- package/docs/img/card.png +0 -0
- package/package.json +4 -3
- package/project.faf +6 -6
- package/project.fafm +13 -4
- package/server.json +5 -5
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"displayName": "mcp-context-card — persistent memory (.fafm)",
|
|
19
19
|
"type": "application/vnd.fafm+yaml",
|
|
20
20
|
"mediaType": "application/vnd.fafm+yaml",
|
|
21
|
-
"description": "Cross-session memory —
|
|
21
|
+
"description": "Cross-session memory — 4 fact(s), profile \"knowledge\". Recall survives a process restart. No de-facto standard for this concern yet.",
|
|
22
22
|
"url": "./project.fafm",
|
|
23
23
|
"_meta": {
|
|
24
24
|
"io.github.wolfe-jam.mcp-context-card/iana": "https://www.iana.org/assignments/media-types/application/vnd.fafm+yaml"
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"displayName": "mcp-context-card — agent identity (.fafa)",
|
|
30
30
|
"type": "application/vnd.fafa+yaml",
|
|
31
31
|
"mediaType": "application/vnd.fafa+yaml",
|
|
32
|
-
"description": "
|
|
32
|
+
"description": "The essential MCP components for a project's context (AGENTS.md), cross-session memory, and identity — a base MCP on its own, or a drop-in extension for any existing MCP server, discoverable through the Server Card _meta block and a self-published ai-catalog.json.",
|
|
33
33
|
"url": "./.well-known/fafa",
|
|
34
34
|
"_meta": {
|
|
35
35
|
"io.github.wolfe-jam.mcp-context-card/iana": "https://www.iana.org/assignments/media-types/application/vnd.fafa+yaml"
|
package/.well-known/fafa
CHANGED
|
@@ -8,11 +8,12 @@ version: "1.0"
|
|
|
8
8
|
agent:
|
|
9
9
|
name: "mcp-context-card"
|
|
10
10
|
displayName: "mcp-context-card"
|
|
11
|
-
vendor: "
|
|
12
|
-
version: "0.5.
|
|
11
|
+
vendor: "io.github.wolfe-jam"
|
|
12
|
+
version: "0.5.2"
|
|
13
13
|
description: >-
|
|
14
|
-
|
|
15
|
-
and identity
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
The essential MCP components for a project's context (AGENTS.md),
|
|
15
|
+
cross-session memory, and identity — a base MCP on its own, or a
|
|
16
|
+
drop-in extension for any existing MCP server, discoverable through the
|
|
17
|
+
Server Card _meta block and a self-published ai-catalog.json.
|
|
18
|
+
status: "published"
|
|
18
19
|
license: "MIT"
|
package/AGENTS.md
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# AGENTS.md
|
|
2
2
|
|
|
3
|
-
`mcp-context-card` is
|
|
4
|
-
(this file), **memory**, and **identity**
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
`mcp-context-card` is the essential MCP server for a project's **context**
|
|
4
|
+
(this file), **memory**, and **identity** — usable as your base MCP, or
|
|
5
|
+
dropped into any existing MCP server as an extension. Discoverable to any
|
|
6
|
+
MCP client through the two surfaces already in the ecosystem: the Server
|
|
7
|
+
Card `_meta` block and `ai-catalog.json` sibling entries.
|
|
7
8
|
|
|
8
9
|
`read_agents_md` serves this file, section by section, over the same MCP
|
|
9
10
|
connection.
|
|
@@ -40,14 +41,14 @@ Windows for every push and PR to `main` (`.github/workflows/ci.yml`).
|
|
|
40
41
|
|---|---|
|
|
41
42
|
| `src/server.ts` | the MCP server — the nine tools + the Server Card resource |
|
|
42
43
|
| `src/agents-md.ts` | reads and section-splits this file |
|
|
43
|
-
| `src/author.ts` | `author_agents_md` —
|
|
44
|
+
| `src/author.ts` | `author_agents_md` — BETTER via `agents-md-facts`, BEST when `project.faf` exists |
|
|
44
45
|
| `src/md.ts` | a minimal dependency-free Markdown → HTML renderer |
|
|
45
46
|
| `src/render-card.ts` | the card — identity + this file + memory + discovery, as one HTML page |
|
|
46
47
|
| `src/memory.ts` → `src/faf/parse-fafm.ts` | file-backed `remember` / `recall` / `forget` |
|
|
47
48
|
| `src/identity.ts` | `whoami` (`.fafa` → `package.json` fallback) + the `_meta` context block |
|
|
48
49
|
| `src/catalog-gen.ts` | writes `.well-known/ai-catalog.json` from the same three sources |
|
|
49
50
|
| `src/transport/http.ts` | the stateless Streamable HTTP app (Hono) |
|
|
50
|
-
| `src/bin.ts` | the entry point (`resolveLaunch`) — `stdio` · `--http` · `card` |
|
|
51
|
+
| `src/bin.ts` | the entry point (`resolveLaunch`) — `stdio` · `--http` · `card` · `--help` · `--version` |
|
|
51
52
|
| `src/faf/parse-fafm.ts` · `parse-fafa.ts` | the `.fafm` / `.fafa` parsers |
|
|
52
53
|
|
|
53
54
|
## Conventions
|
|
@@ -80,6 +81,7 @@ plus `npm run catalog:check` and `npm run card:check` clean if you touched
|
|
|
80
81
|
|
|
81
82
|
## Authoring this file
|
|
82
83
|
|
|
83
|
-
`AGENTS.md` here is maintained by hand.
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
`AGENTS.md` here is maintained by hand. The `author_agents_md` tool (or
|
|
85
|
+
`faf export --agents`) would draft a BEST version straight from this repo's
|
|
86
|
+
own `project.faf` plus its detected facts — the server doesn't care how the
|
|
87
|
+
file was authored, only that it's valid Markdown.
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,63 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project. Adheres to [Semantic Versioning](https://semver.org).
|
|
4
4
|
|
|
5
|
+
## 0.5.2
|
|
6
|
+
|
|
7
|
+
The soak, closed out. Two Cursor host checks — a real bug found and fixed, a
|
|
8
|
+
real gap found and fixed, both confirmed against a real independent MCP host
|
|
9
|
+
on the current build.
|
|
10
|
+
|
|
11
|
+
- **`author_agents_md` now authors BEST, not just BETTER, when it can.**
|
|
12
|
+
BETTER is the facts-only draft from `agents-md-facts` (build/test
|
|
13
|
+
commands, entry points, conventions — nothing invented). **BEST** is that
|
|
14
|
+
plus a `## Project` section ahead of it — goal, who it's for, why, and a
|
|
15
|
+
"start here" file list — read straight from `project.faf` when one
|
|
16
|
+
exists. This is the point of the app: give the best AGENTS.md the
|
|
17
|
+
project has the material for, not a fixed floor. The tool's response
|
|
18
|
+
names the tier it produced.
|
|
19
|
+
- **Fix:** `remember` on a project that had never had a `project.fafm`
|
|
20
|
+
threw `ENOENT` instead of starting one — the single most common
|
|
21
|
+
first-use case. `remember` now creates a fresh `.fafm` on first write;
|
|
22
|
+
`forget` / `parseFafm` were already safe and are unchanged. A real
|
|
23
|
+
child-process e2e test (a cold root, two separate OS processes) makes
|
|
24
|
+
this a permanent regression guard, not just a fix.
|
|
25
|
+
- `docs/WIRING.md`: a note on hosts whose spawn `PATH` lacks `npx`
|
|
26
|
+
(`spawn npx ENOENT`, observed in Cursor) — point `command` at `node` +
|
|
27
|
+
the installed `dist/bin.js` instead.
|
|
28
|
+
- **The README / AGENTS.md / `project.faf` / manifest reframe** — dropped
|
|
29
|
+
"Small, MIT…" / "a piece, not the toolbox" for the real positioning:
|
|
30
|
+
essential context, memory, and identity components, usable as a base MCP
|
|
31
|
+
on their own, or a drop-in extension for any existing MCP server.
|
|
32
|
+
- An accuracy pass across every shipped surface, caught by re-reading
|
|
33
|
+
rather than by any check: stale test/tool counts (README, CHANGELOG,
|
|
34
|
+
and `project.faf`'s own `human_context.what` — it undercounted its own
|
|
35
|
+
tools), 3-release-old version strings sitting in two hand-shown examples
|
|
36
|
+
(`examples/README.md`, `docs/MECHANISMS.md`), a pre-rename
|
|
37
|
+
docker-compose service name (`trinity` → `context-card`), an internal
|
|
38
|
+
function that still carried the pre-rename product name (`trinityMeta` →
|
|
39
|
+
`serverCardMeta` — not a public export). `project.faf` itself rechecked
|
|
40
|
+
against the current architecture (`tech_stack`, `key_files`, `cicd`).
|
|
41
|
+
- 102 tests, coverage gate held, `card:check` / `catalog:check` green,
|
|
42
|
+
`faf-cli check`: ✪ Trophy 100%, 15/15 slots.
|
|
43
|
+
|
|
44
|
+
## 0.5.1
|
|
45
|
+
|
|
46
|
+
First-hour ergonomics and wording, from the 0.5.0 soak.
|
|
47
|
+
|
|
48
|
+
- `--help` / `-h` and `--version` / `-V` (and the `help` / `version` subcommands)
|
|
49
|
+
— a bare `mcp-context-card` is a stdio server that waits on stdin, so at a
|
|
50
|
+
terminal it looked idle with no way to ask what it was.
|
|
51
|
+
- stdio mode now prints one line to **stderr** on start
|
|
52
|
+
(`… · stdio · waiting for an MCP host on stdin`) — mirrors what `--http`
|
|
53
|
+
already did. stdout stays clean for the JSON-RPC wire.
|
|
54
|
+
- The npm and `server.json` descriptions no longer open with "Reference MCP
|
|
55
|
+
server" — they now match the README ("An MCP server that makes a project's
|
|
56
|
+
context, memory, and identity discoverable…"). Same in `.well-known/fafa`;
|
|
57
|
+
the three `project.fafm` facts are `type: fact`. `package.json` `author` set
|
|
58
|
+
to the LICENSE holder.
|
|
59
|
+
- `.well-known/fafa` — `vendor: io.github.wolfe-jam`, `status: published`
|
|
60
|
+
(were both `reference`). Shows in `whoami` and as the card's pills.
|
|
61
|
+
|
|
5
62
|
## 0.5.0
|
|
6
63
|
|
|
7
64
|
The first public release — installable, and settling in the open before a
|
|
@@ -47,7 +104,7 @@ tested server.
|
|
|
47
104
|
|
|
48
105
|
### Engineering
|
|
49
106
|
|
|
50
|
-
-
|
|
107
|
+
- 90 tests across Linux / macOS / Windows, coverage-gated
|
|
51
108
|
(lines 90 / funcs 85 / branches 80, `src/` only). A real `child_process`
|
|
52
109
|
spawn proves memory across a genuine process boundary; stdio/HTTP
|
|
53
110
|
tool-surface parity is asserted.
|
|
@@ -70,6 +127,6 @@ tested server.
|
|
|
70
127
|
|
|
71
128
|
## v0.1.0 (2026-08-12)
|
|
72
129
|
|
|
73
|
-
- Initial private
|
|
130
|
+
- Initial private implementation (as `faf-trinity`): project context,
|
|
74
131
|
persistent memory, and agent identity in one MCP server, through two
|
|
75
132
|
mechanisms already live in production. `demo.ts` proved all three.
|
package/README.md
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
[](https://github.com/Wolfe-Jam/mcp-context-card/actions/workflows/ci.yml)
|
|
4
4
|
[](./LICENSE)
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
to any MCP client
|
|
6
|
+
The essential MCP server for a project's context, memory, and identity —
|
|
7
|
+
discoverable to any MCP client, and rendered as one card you can read.
|
|
8
8
|
|
|
9
9
|
- **context** — the project's `AGENTS.md`, served whole or one section at a time
|
|
10
10
|
- **memory** — facts that persist across sessions, in a file
|
|
@@ -13,26 +13,34 @@ to any MCP client — and renders them as one card you can read.
|
|
|
13
13
|
Discovery goes through two surfaces already in the ecosystem: the Server Card
|
|
14
14
|
`_meta` block and `ai-catalog.json` sibling entries.
|
|
15
15
|
|
|
16
|
-
##
|
|
16
|
+
## A base MCP — or an extension for any other
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
Context, memory, and identity are essential — every MCP host needs an agent
|
|
19
|
+
that knows a project's instructions, remembers facts across sessions, and can
|
|
20
|
+
say what it is. `mcp-context-card` is those three, done once:
|
|
21
21
|
|
|
22
|
-
**
|
|
22
|
+
- **Stand it up as your base MCP.** Point a host at it and an agent already
|
|
23
|
+
has `AGENTS.md` served section‑by‑section, `remember` / `recall` / `forget`
|
|
24
|
+
memory that survives a restart, and a `whoami` identity — before a single
|
|
25
|
+
tool of your own is written.
|
|
26
|
+
- **Or extend any existing MCP with it.** Run it alongside a server you
|
|
27
|
+
already have — filesystem, git, a database, your own — and that agent
|
|
28
|
+
gains context, memory, and identity discovery it didn't have. Nothing to
|
|
29
|
+
migrate; it composes.
|
|
23
30
|
|
|
24
|
-
|
|
25
|
-
-
|
|
26
|
-
- tied to FAF — context is plain Markdown (`AGENTS.md`); the memory and identity
|
|
27
|
-
formats are swappable examples
|
|
31
|
+
Nine tools, two discovery surfaces already in the ecosystem (Server Card
|
|
32
|
+
`_meta`, `ai-catalog.json`), and a rendered [card](#the-card). MIT, on npm.
|
|
28
33
|
|
|
29
34
|
It composes:
|
|
30
35
|
|
|
31
36
|
- **serve · discover · render** — this server
|
|
32
|
-
- **author
|
|
37
|
+
- **author BETTER, keep true** — [`agents-md-facts`](https://github.com/Wolfe-Jam/agents-md-facts) (`author_agents_md` wraps it for the facts layer; adds a BEST layer of its own from `project.faf` when one exists)
|
|
33
38
|
- **files · shell · git** — [`server-filesystem`](https://github.com/modelcontextprotocol/servers), [`server-git`](https://github.com/modelcontextprotocol/servers) / github‑mcp‑server, your test runner's MCP
|
|
34
39
|
|
|
35
|
-
|
|
40
|
+
Not a framework or a platform — three concerns, nothing more. Not a file,
|
|
41
|
+
shell, or search tool — it never touches your files or runs commands. Not
|
|
42
|
+
tied to FAF — context is plain Markdown (`AGENTS.md`); the memory and identity
|
|
43
|
+
formats are swappable examples.
|
|
36
44
|
|
|
37
45
|
## The card
|
|
38
46
|
|
|
@@ -55,7 +63,7 @@ Light, dark, or auto; the accent defaults to the AAIF palette and takes any hex.
|
|
|
55
63
|
|
|
56
64
|
| You want… | Reach for |
|
|
57
65
|
|---|---|
|
|
58
|
-
| an `AGENTS.md` and you don't have one | `author_agents_md` —
|
|
66
|
+
| an `AGENTS.md` and you don't have one | `author_agents_md` — BEST with a `project.faf`, BETTER without |
|
|
59
67
|
| your agent to pull *one* `AGENTS.md` section on demand, not the whole file | `read_agents_md` · `list_agents_md_sections` |
|
|
60
68
|
| a persistent notepad for your agent — survives restarts, no setup | `remember` · `recall` · `forget` |
|
|
61
69
|
| a shareable view of what your MCP server exposes to agents | `GET /card` · `npx mcp-context-card card` |
|
|
@@ -65,20 +73,21 @@ Light, dark, or auto; the accent defaults to the AAIF palette and takes any hex.
|
|
|
65
73
|
|
|
66
74
|
### No `AGENTS.md` yet?
|
|
67
75
|
|
|
68
|
-
The `author_agents_md` tool authors one from your repo's
|
|
69
|
-
build/test commands, entry points, toolchain conventions
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
76
|
+
The `author_agents_md` tool authors one — **BETTER** from your repo's real
|
|
77
|
+
facts (build/test commands, entry points, toolchain conventions, via
|
|
78
|
+
[`agents-md-facts`](https://github.com/Wolfe-Jam/agents-md-facts)), or
|
|
79
|
+
**BEST** when a `project.faf` exists: the same facts, plus its structured
|
|
80
|
+
goal, who it's for, and why, as a section ahead of them. Nothing to
|
|
81
|
+
configure — the tier follows what's actually there.
|
|
82
|
+
([The ladder this follows.](https://github.com/Wolfe-Jam/agents-md-facts/blob/main/docs/BETTER-BEST.md))
|
|
83
|
+
|
|
84
|
+
To author or keep the facts layer true outside a session:
|
|
73
85
|
|
|
74
86
|
```bash
|
|
75
87
|
npx agents-md-facts # author / refresh AGENTS.md
|
|
76
88
|
npx agents-md-facts --check # fail if missing or stale (CI, pre-commit)
|
|
77
89
|
```
|
|
78
90
|
|
|
79
|
-
A `project.faf` is the next rung — a structured source that refreshes the file.
|
|
80
|
-
Short model: [`agents-md-facts/docs/BETTER-BEST.md`](https://github.com/Wolfe-Jam/agents-md-facts/blob/main/docs/BETTER-BEST.md).
|
|
81
|
-
|
|
82
91
|
### See the card
|
|
83
92
|
|
|
84
93
|
One command, no host, no config:
|
|
@@ -109,6 +118,11 @@ memory tools work with or without it; identity is optional. Over HTTP instead:
|
|
|
109
118
|
[docs/WIRING.md](./docs/WIRING.md); transport choice in
|
|
110
119
|
[docs/TRANSPORT.md](./docs/TRANSPORT.md).
|
|
111
120
|
|
|
121
|
+
Extending an MCP you already run: most hosts accept more than one
|
|
122
|
+
`mcpServers` entry — add `context-card` alongside `server-filesystem`,
|
|
123
|
+
`server-git`, or your own, and every agent in that host gains context,
|
|
124
|
+
memory, and identity discovery without anything else changing.
|
|
125
|
+
|
|
112
126
|
## Why
|
|
113
127
|
|
|
114
128
|
`AGENTS.md` is the de-facto standard for telling a coding agent how to work in a
|
|
@@ -137,7 +151,7 @@ The wire‑level detail is in [docs/MECHANISMS.md](./docs/MECHANISMS.md).
|
|
|
137
151
|
|
|
138
152
|
| Tool | What it's for |
|
|
139
153
|
|---|---|
|
|
140
|
-
| `author_agents_md` | draft an `AGENTS.md` from the repo's facts (via `agents-md-facts`)
|
|
154
|
+
| `author_agents_md` | draft an `AGENTS.md` — BETTER from the repo's facts (via `agents-md-facts`), BEST when a `project.faf` exists — ready to drop in |
|
|
141
155
|
| `read_agents_md` | return the project's `AGENTS.md` — whole, or one section by heading |
|
|
142
156
|
| `list_agents_md_sections` | the headings, so a client pulls one section instead of the whole file |
|
|
143
157
|
| `remember` | write a fact that will still be there next session |
|
|
@@ -159,9 +173,10 @@ The wire‑level detail is in [docs/MECHANISMS.md](./docs/MECHANISMS.md).
|
|
|
159
173
|
4. **Discovery** — `list_context_sources()`, then the same server over stateless
|
|
160
174
|
HTTP with its `.well-known` routes and `GET /card`.
|
|
161
175
|
|
|
162
|
-
|
|
163
|
-
child process and
|
|
164
|
-
|
|
176
|
+
99 tests on Linux, macOS, and Windows, coverage‑gated in CI. Two spawn a real
|
|
177
|
+
child process and check a remembered fact survives the restart — one against
|
|
178
|
+
an existing `project.fafm`, one starting from a project that has never had
|
|
179
|
+
one; another checks the stdio and HTTP tool surfaces match.
|
|
165
180
|
|
|
166
181
|
## Layout
|
|
167
182
|
|
|
@@ -169,14 +184,14 @@ the stdio and HTTP tool surfaces match.
|
|
|
169
184
|
|---|---|
|
|
170
185
|
| `src/server.ts` | the nine tools + the Server Card resource |
|
|
171
186
|
| `src/agents-md.ts` | reads and section‑splits `AGENTS.md` |
|
|
172
|
-
| `src/author.ts` | `author_agents_md` —
|
|
187
|
+
| `src/author.ts` | `author_agents_md` — BETTER via [`agents-md-facts`](https://github.com/Wolfe-Jam/agents-md-facts), BEST when `project.faf` exists |
|
|
173
188
|
| `src/md.ts` | a minimal dependency‑free Markdown → HTML renderer |
|
|
174
189
|
| `src/render-card.ts` | the card — identity + `AGENTS.md` + memory + discovery, as one HTML page |
|
|
175
190
|
| `src/memory.ts` | file‑backed `remember` / `recall` / `forget` |
|
|
176
191
|
| `src/identity.ts` | `whoami` (`.fafa` → `package.json` fallback) + the `_meta` block |
|
|
177
192
|
| `src/catalog-gen.ts` | writes `ai-catalog.json` from the same three sources |
|
|
178
193
|
| `src/transport/http.ts` | the stateless Streamable HTTP app (Hono) |
|
|
179
|
-
| `src/bin.ts` | the entry point — `stdio` · `--http` · `card` |
|
|
194
|
+
| `src/bin.ts` | the entry point — `stdio` · `--http` · `card` · `--help` · `--version` |
|
|
180
195
|
|
|
181
196
|
## Related
|
|
182
197
|
|
package/dist/author.d.ts
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
/** The markers `agents-md-facts` uses to bound its managed block. */
|
|
2
2
|
export declare const BLOCK_START = "<!-- agents:from-facts:start -->";
|
|
3
3
|
export declare const BLOCK_END = "<!-- agents:from-facts:end -->";
|
|
4
|
+
/** The markers this file uses to bound the project.faf-sourced intent block. */
|
|
5
|
+
export declare const FAF_BLOCK_START = "<!-- context:from-faf:start -->";
|
|
6
|
+
export declare const FAF_BLOCK_END = "<!-- context:from-faf:end -->";
|
|
4
7
|
export interface Authored {
|
|
5
|
-
/** the AGENTS.md text —
|
|
8
|
+
/** the AGENTS.md text — one or two managed blocks, ready to drop in */
|
|
6
9
|
markdown: string;
|
|
7
10
|
/** whether an AGENTS.md already exists at the target */
|
|
8
11
|
exists: boolean;
|
|
12
|
+
/** which tier was authored — BEST only when a readable project.faf was found */
|
|
13
|
+
tier: "better" | "best";
|
|
9
14
|
}
|
|
10
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* Author AGENTS.md for `root`. BETTER from repo facts alone; BEST — facts
|
|
17
|
+
* plus the project.faf intent block, ahead of it — when a project.faf with
|
|
18
|
+
* real content exists.
|
|
19
|
+
*/
|
|
11
20
|
export declare function authorAgentsMd(root: string): Authored;
|
package/dist/author.js
CHANGED
|
@@ -1,27 +1,86 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* author — author an AGENTS.md for a project
|
|
2
|
+
* author — author an AGENTS.md for a project, at the tier the project earns.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* markers so `agents-md-facts --check` (or its Action / pre-commit hook) can
|
|
8
|
-
* keep the result true afterwards.
|
|
4
|
+
* BETTER: the engine is `agents-md-facts` (a published, standalone tool) —
|
|
5
|
+
* it detects real build/test commands, entry points, toolchain conventions
|
|
6
|
+
* and nothing invented. Every project gets at least this.
|
|
9
7
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
8
|
+
* BEST: when `project.faf` exists, its structured intent — goal, who it's
|
|
9
|
+
* for, why it exists, the files that matter most — is real, human-authored
|
|
10
|
+
* truth that no amount of repo-scanning can detect. A project with a
|
|
11
|
+
* `project.faf` gets BOTH: the facts block, unchanged, plus this intent as
|
|
12
|
+
* its own managed block ahead of it. This is the whole point of the app:
|
|
13
|
+
* give the BEST AGENTS.md when the structured source to build it from is
|
|
14
|
+
* sitting right there.
|
|
13
15
|
*/
|
|
14
|
-
import { existsSync } from "node:fs";
|
|
16
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
15
17
|
import { join } from "node:path";
|
|
18
|
+
import { parse } from "yaml";
|
|
16
19
|
import { authorAgentsMd as authorBlock, buildRepoContext } from "agents-md-facts";
|
|
17
20
|
/** The markers `agents-md-facts` uses to bound its managed block. */
|
|
18
21
|
export const BLOCK_START = "<!-- agents:from-facts:start -->";
|
|
19
22
|
export const BLOCK_END = "<!-- agents:from-facts:end -->";
|
|
20
|
-
/**
|
|
23
|
+
/** The markers this file uses to bound the project.faf-sourced intent block. */
|
|
24
|
+
export const FAF_BLOCK_START = "<!-- context:from-faf:start -->";
|
|
25
|
+
export const FAF_BLOCK_END = "<!-- context:from-faf:end -->";
|
|
26
|
+
/** Read the structured intent out of `root`'s project.faf, or null if there isn't one to read. */
|
|
27
|
+
function readFafIntent(root) {
|
|
28
|
+
const path = join(root, "project.faf");
|
|
29
|
+
if (!existsSync(path))
|
|
30
|
+
return null;
|
|
31
|
+
try {
|
|
32
|
+
const doc = (parse(readFileSync(path, "utf8")) ?? {});
|
|
33
|
+
const project = doc.project ?? {};
|
|
34
|
+
const humanContext = doc.human_context ?? {};
|
|
35
|
+
const intent = {
|
|
36
|
+
name: str(project.name),
|
|
37
|
+
goal: str(project.goal),
|
|
38
|
+
who: str(humanContext.who),
|
|
39
|
+
why: str(humanContext.why),
|
|
40
|
+
keyFiles: Array.isArray(doc.key_files) ? doc.key_files.map(String).filter(Boolean) : undefined,
|
|
41
|
+
};
|
|
42
|
+
// A .faf with nothing usable in it isn't a real intent source.
|
|
43
|
+
return intent.goal || intent.who || intent.why ? intent : null;
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function str(v) {
|
|
50
|
+
const s = typeof v === "string" ? v.trim() : "";
|
|
51
|
+
return s || undefined;
|
|
52
|
+
}
|
|
53
|
+
/** Render the project.faf-sourced intent as its own managed block. */
|
|
54
|
+
function fafIntentBlock(intent) {
|
|
55
|
+
const lines = ["## Project", ""];
|
|
56
|
+
if (intent.goal)
|
|
57
|
+
lines.push(intent.goal, "");
|
|
58
|
+
if (intent.who)
|
|
59
|
+
lines.push(`**Who it's for:** ${intent.who}`, "");
|
|
60
|
+
if (intent.why)
|
|
61
|
+
lines.push(`**Why:** ${intent.why}`, "");
|
|
62
|
+
if (intent.keyFiles?.length) {
|
|
63
|
+
lines.push("**Start here:**", "");
|
|
64
|
+
for (const f of intent.keyFiles)
|
|
65
|
+
lines.push(`- \`${f}\``);
|
|
66
|
+
lines.push("");
|
|
67
|
+
}
|
|
68
|
+
return `${FAF_BLOCK_START}\n${lines.join("\n").trimEnd()}\n${FAF_BLOCK_END}\n`;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Author AGENTS.md for `root`. BETTER from repo facts alone; BEST — facts
|
|
72
|
+
* plus the project.faf intent block, ahead of it — when a project.faf with
|
|
73
|
+
* real content exists.
|
|
74
|
+
*/
|
|
21
75
|
export function authorAgentsMd(root) {
|
|
22
|
-
const
|
|
76
|
+
const factsBlock = `${BLOCK_START}\n${authorBlock(buildRepoContext(root)).trim()}\n${BLOCK_END}\n`;
|
|
77
|
+
const exists = existsSync(join(root, "AGENTS.md"));
|
|
78
|
+
const intent = readFafIntent(root);
|
|
79
|
+
if (!intent)
|
|
80
|
+
return { markdown: factsBlock, exists, tier: "better" };
|
|
23
81
|
return {
|
|
24
|
-
markdown: `${
|
|
25
|
-
exists
|
|
82
|
+
markdown: `${fafIntentBlock(intent)}\n${factsBlock}`,
|
|
83
|
+
exists,
|
|
84
|
+
tier: "best",
|
|
26
85
|
};
|
|
27
86
|
}
|
package/dist/bin.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
export type Mode = "stdio" | "http" | "card";
|
|
2
|
+
export type Mode = "stdio" | "http" | "card" | "help" | "version";
|
|
3
3
|
export interface Launch {
|
|
4
4
|
mode: Mode;
|
|
5
5
|
/** port for http mode (ignored otherwise). */
|
|
@@ -7,14 +7,18 @@ export interface Launch {
|
|
|
7
7
|
/** directory to read from — cwd for `card`, else MCP_CONTEXT_CARD_ROOT ?? package root. */
|
|
8
8
|
root: string;
|
|
9
9
|
}
|
|
10
|
+
/** what a bare `--help` / `help` prints. */
|
|
11
|
+
export declare const HELP = "mcp-context-card 0.5.2\nServe a project's context (AGENTS.md), memory, and identity over MCP.\n\nUSAGE\n mcp-context-card stdio MCP server \u2014 what an MCP host spawns (default)\n mcp-context-card --http stateless Streamable HTTP on PORT (default 3000)\n mcp-context-card --stdio force stdio even when PORT is set\n mcp-context-card card [> f.html] render this directory's context card to stdout\n --theme light|dark --accent #hex\n mcp-context-card --help this text\n mcp-context-card --version print version\n\nENV\n MCP_CONTEXT_CARD_ROOT read AGENTS.md / project.fafm / .well-known/ from here\n PORT if set, run HTTP instead of stdio\n\nA bare run is an stdio server: it waits for a host to speak JSON-RPC on stdin,\nso it looks idle at a terminal. Try `card` or `--http` to see output directly.\nhttps://github.com/Wolfe-Jam/mcp-context-card\n";
|
|
10
12
|
/**
|
|
11
13
|
* Decide how to launch, from argv + env. Pure — so the mode matrix is unit
|
|
12
14
|
* tested without spawning a process.
|
|
13
15
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
16
|
+
* --help | -h | help → print usage
|
|
17
|
+
* --version | -V | version → print version
|
|
18
|
+
* card → render the cwd's card to stdout
|
|
19
|
+
* (nothing) → stdio
|
|
20
|
+
* --http | PORT=<n> → http
|
|
21
|
+
* --stdio → stdio, even when PORT is set
|
|
18
22
|
*/
|
|
19
23
|
export declare function resolveLaunch(argv: readonly string[], env?: NodeJS.ProcessEnv): Launch;
|
|
20
24
|
/** value of `--flag <value>` in argv, or undefined. */
|
package/dist/bin.js
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
* mcp-context-card --stdio → force stdio even when PORT is set
|
|
9
9
|
* mcp-context-card card → render THIS directory's context card to stdout
|
|
10
10
|
* ( > card.html · --theme light|dark · --accent #hex )
|
|
11
|
+
* mcp-context-card --help → usage
|
|
12
|
+
* mcp-context-card --version → version
|
|
11
13
|
*
|
|
12
14
|
* MCP_CONTEXT_CARD_ROOT=/path/to/project → read AGENTS.md / project.fafm /
|
|
13
15
|
* .well-known/ from there instead of the package's own bundled copies.
|
|
@@ -15,17 +17,46 @@
|
|
|
15
17
|
import { resolve } from "node:path";
|
|
16
18
|
import { pathToFileURL } from "node:url";
|
|
17
19
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
20
|
+
import { NAME, VERSION } from "./constants.js";
|
|
18
21
|
import { ROOT, serve } from "./server.js";
|
|
22
|
+
/** what a bare `--help` / `help` prints. */
|
|
23
|
+
export const HELP = `${NAME} ${VERSION}
|
|
24
|
+
Serve a project's context (AGENTS.md), memory, and identity over MCP.
|
|
25
|
+
|
|
26
|
+
USAGE
|
|
27
|
+
mcp-context-card stdio MCP server — what an MCP host spawns (default)
|
|
28
|
+
mcp-context-card --http stateless Streamable HTTP on PORT (default 3000)
|
|
29
|
+
mcp-context-card --stdio force stdio even when PORT is set
|
|
30
|
+
mcp-context-card card [> f.html] render this directory's context card to stdout
|
|
31
|
+
--theme light|dark --accent #hex
|
|
32
|
+
mcp-context-card --help this text
|
|
33
|
+
mcp-context-card --version print version
|
|
34
|
+
|
|
35
|
+
ENV
|
|
36
|
+
MCP_CONTEXT_CARD_ROOT read AGENTS.md / project.fafm / .well-known/ from here
|
|
37
|
+
PORT if set, run HTTP instead of stdio
|
|
38
|
+
|
|
39
|
+
A bare run is an stdio server: it waits for a host to speak JSON-RPC on stdin,
|
|
40
|
+
so it looks idle at a terminal. Try \`card\` or \`--http\` to see output directly.
|
|
41
|
+
https://github.com/Wolfe-Jam/mcp-context-card
|
|
42
|
+
`;
|
|
19
43
|
/**
|
|
20
44
|
* Decide how to launch, from argv + env. Pure — so the mode matrix is unit
|
|
21
45
|
* tested without spawning a process.
|
|
22
46
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
47
|
+
* --help | -h | help → print usage
|
|
48
|
+
* --version | -V | version → print version
|
|
49
|
+
* card → render the cwd's card to stdout
|
|
50
|
+
* (nothing) → stdio
|
|
51
|
+
* --http | PORT=<n> → http
|
|
52
|
+
* --stdio → stdio, even when PORT is set
|
|
27
53
|
*/
|
|
28
54
|
export function resolveLaunch(argv, env = process.env) {
|
|
55
|
+
const has = (...flags) => flags.some((f) => argv.includes(f));
|
|
56
|
+
if (argv[0] === "help" || has("--help", "-h"))
|
|
57
|
+
return { mode: "help", port: 0, root: ROOT };
|
|
58
|
+
if (argv[0] === "version" || has("--version", "-V"))
|
|
59
|
+
return { mode: "version", port: 0, root: ROOT };
|
|
29
60
|
if (argv[0] === "card") {
|
|
30
61
|
return {
|
|
31
62
|
mode: "card",
|
|
@@ -49,7 +80,13 @@ export function flagValue(argv, flag) {
|
|
|
49
80
|
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
50
81
|
const argv = process.argv.slice(2);
|
|
51
82
|
const { mode, port, root } = resolveLaunch(argv);
|
|
52
|
-
if (mode === "
|
|
83
|
+
if (mode === "help") {
|
|
84
|
+
process.stdout.write(HELP);
|
|
85
|
+
}
|
|
86
|
+
else if (mode === "version") {
|
|
87
|
+
process.stdout.write(`${VERSION}\n`);
|
|
88
|
+
}
|
|
89
|
+
else if (mode === "card") {
|
|
53
90
|
const { renderCard, safeAccent } = await import("./render-card.js");
|
|
54
91
|
const theme = flagValue(argv, "--theme");
|
|
55
92
|
process.stdout.write(renderCard(root, {
|
|
@@ -62,9 +99,12 @@ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href)
|
|
|
62
99
|
const { serve: serveHttp } = await import("@hono/node-server");
|
|
63
100
|
serveHttp({ fetch: httpApp(root).fetch, port });
|
|
64
101
|
// stderr, not stdout — stdout is the MCP wire in stdio mode.
|
|
65
|
-
console.error(
|
|
102
|
+
console.error(`${NAME} · http · :${port} (POST /mcp · GET /card · GET /.well-known/*)`);
|
|
66
103
|
}
|
|
67
104
|
else {
|
|
105
|
+
// stderr so it never touches the JSON-RPC wire on stdout; a bare run at a
|
|
106
|
+
// terminal otherwise looks hung.
|
|
107
|
+
console.error(`${NAME} · stdio · waiting for an MCP host on stdin (--help for usage · Ctrl-C to exit)`);
|
|
68
108
|
await serve(new StdioServerTransport(), root);
|
|
69
109
|
}
|
|
70
110
|
}
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Server identity constants, in their own module so any file can import
|
|
2
2
|
* them without pulling in the whole server. */
|
|
3
3
|
export declare const NAME = "mcp-context-card";
|
|
4
|
-
export declare const VERSION = "0.5.
|
|
4
|
+
export declare const VERSION = "0.5.2";
|
|
5
5
|
export declare const SERVER_CARD_URI = "mcp-context-card://server-card";
|
package/dist/constants.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Server identity constants, in their own module so any file can import
|
|
2
2
|
* them without pulling in the whole server. */
|
|
3
3
|
export const NAME = "mcp-context-card";
|
|
4
|
-
export const VERSION = "0.5.
|
|
4
|
+
export const VERSION = "0.5.2";
|
|
5
5
|
export const SERVER_CARD_URI = "mcp-context-card://server-card";
|
package/dist/faf/parse-fafm.js
CHANGED
|
@@ -27,8 +27,29 @@ function factMap(entries) {
|
|
|
27
27
|
m.set(k, q(v));
|
|
28
28
|
return m;
|
|
29
29
|
}
|
|
30
|
+
/** A brand-new .fafm — what `remember()` writes the first time a project has none. */
|
|
31
|
+
const FRESH_FAFM = `version: "1.1"
|
|
32
|
+
memory:
|
|
33
|
+
facts: []
|
|
34
|
+
sessions: []
|
|
35
|
+
preferences: {}
|
|
36
|
+
custom: {}
|
|
37
|
+
`;
|
|
38
|
+
/**
|
|
39
|
+
* Load the .fafm at `path`. A missing file is not an error here — it means
|
|
40
|
+
* "no memory yet", and remember()/forget() need a document to edit even
|
|
41
|
+
* before anything has ever been written. Any other read error (permissions,
|
|
42
|
+
* a directory in the way, …) still throws.
|
|
43
|
+
*/
|
|
30
44
|
function load(path) {
|
|
31
|
-
|
|
45
|
+
try {
|
|
46
|
+
return parseDocument(readFileSync(path, "utf8"));
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
if (err.code === "ENOENT")
|
|
50
|
+
return parseDocument(FRESH_FAFM);
|
|
51
|
+
throw err;
|
|
52
|
+
}
|
|
32
53
|
}
|
|
33
54
|
export function parseFafm(path) {
|
|
34
55
|
let doc;
|
package/dist/identity.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export declare function whoami(root: string): string;
|
|
|
16
16
|
* other two point at their worked-example artifacts; `memory` carries a note
|
|
17
17
|
* because there is no de-facto standard for it yet.
|
|
18
18
|
*/
|
|
19
|
-
export declare function
|
|
19
|
+
export declare function serverCardMeta(): {
|
|
20
20
|
readonly "io.github.wolfe-jam.mcp-context-card/context": {
|
|
21
21
|
readonly source: "AGENTS.md";
|
|
22
22
|
readonly mediaType: "text/markdown";
|
package/dist/identity.js
CHANGED
|
@@ -61,7 +61,7 @@ export function whoami(root) {
|
|
|
61
61
|
* other two point at their worked-example artifacts; `memory` carries a note
|
|
62
62
|
* because there is no de-facto standard for it yet.
|
|
63
63
|
*/
|
|
64
|
-
export function
|
|
64
|
+
export function serverCardMeta() {
|
|
65
65
|
return {
|
|
66
66
|
[`${META_NS}/context`]: {
|
|
67
67
|
source: "AGENTS.md",
|
package/dist/render-card.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import { join } from "node:path";
|
|
13
13
|
import { parseAgentsMd } from "./agents-md.js";
|
|
14
14
|
import { parseFafm } from "./memory.js";
|
|
15
|
-
import { resolveIdentity,
|
|
15
|
+
import { resolveIdentity, serverCardMeta, META_NS } from "./identity.js";
|
|
16
16
|
import { NAME, SERVER_CARD_URI } from "./constants.js";
|
|
17
17
|
import { escapeHtml, renderInline, renderMarkdown, slug } from "./md.js";
|
|
18
18
|
/** AAIF brand orange (aaif.io). The default accent. */
|
|
@@ -92,7 +92,7 @@ export function renderCard(root, opts = {}) {
|
|
|
92
92
|
const agents = parseAgentsMd(join(root, "AGENTS.md"));
|
|
93
93
|
const mem = parseFafm(join(root, "project.fafm"));
|
|
94
94
|
const id = resolveIdentity(root);
|
|
95
|
-
const meta =
|
|
95
|
+
const meta = serverCardMeta();
|
|
96
96
|
const name = id?.displayName ?? id?.name ?? NAME;
|
|
97
97
|
const pills = [
|
|
98
98
|
id?.vendor && id.vendor !== id.status && `<span class="pill">${escapeHtml(id.vendor)}</span>`,
|
package/dist/server.d.ts
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* mcp-context-card server — makes a project's context, memory, and identity
|
|
3
3
|
* discoverable to any MCP client.
|
|
4
4
|
*
|
|
5
|
-
* context — read_agents_md · list_agents_md_sections (this project's AGENTS.md)
|
|
6
|
-
* memory — remember · recall · forget
|
|
7
|
-
* identity — whoami
|
|
8
|
-
* discovery — list_context_sources
|
|
5
|
+
* context — read_agents_md · list_agents_md_sections · author_agents_md (this project's AGENTS.md)
|
|
6
|
+
* memory — remember · recall · forget (a .fafm file)
|
|
7
|
+
* identity — whoami (this server's .fafa)
|
|
8
|
+
* discovery — list_context_sources · render_context_card (what's published, and how)
|
|
9
9
|
*
|
|
10
10
|
* ...exposed through the two mechanisms already in the ecosystem:
|
|
11
11
|
*
|
package/dist/server.js
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* mcp-context-card server — makes a project's context, memory, and identity
|
|
3
3
|
* discoverable to any MCP client.
|
|
4
4
|
*
|
|
5
|
-
* context — read_agents_md · list_agents_md_sections (this project's AGENTS.md)
|
|
6
|
-
* memory — remember · recall · forget
|
|
7
|
-
* identity — whoami
|
|
8
|
-
* discovery — list_context_sources
|
|
5
|
+
* context — read_agents_md · list_agents_md_sections · author_agents_md (this project's AGENTS.md)
|
|
6
|
+
* memory — remember · recall · forget (a .fafm file)
|
|
7
|
+
* identity — whoami (this server's .fafa)
|
|
8
|
+
* discovery — list_context_sources · render_context_card (what's published, and how)
|
|
9
9
|
*
|
|
10
10
|
* ...exposed through the two mechanisms already in the ecosystem:
|
|
11
11
|
*
|
|
@@ -22,7 +22,7 @@ import { fileURLToPath, pathToFileURL } from "node:url";
|
|
|
22
22
|
import { findSection, parseAgentsMd } from "./agents-md.js";
|
|
23
23
|
import { authorAgentsMd } from "./author.js";
|
|
24
24
|
import { forget, parseFafm, recall, remember } from "./memory.js";
|
|
25
|
-
import { identity,
|
|
25
|
+
import { identity, serverCardMeta, whoami } from "./identity.js";
|
|
26
26
|
import { renderCard, safeAccent } from "./render-card.js";
|
|
27
27
|
export { NAME, VERSION, SERVER_CARD_URI } from "./constants.js";
|
|
28
28
|
import { NAME, VERSION, SERVER_CARD_URI } from "./constants.js";
|
|
@@ -36,7 +36,7 @@ export const ROOT = join(here, "..");
|
|
|
36
36
|
* `/.well-known/mcp/server-card`.
|
|
37
37
|
*/
|
|
38
38
|
export function serverCard() {
|
|
39
|
-
return { name: NAME, version: VERSION, _meta:
|
|
39
|
+
return { name: NAME, version: VERSION, _meta: serverCardMeta() };
|
|
40
40
|
}
|
|
41
41
|
const text = (s) => ({ content: [{ type: "text", text: s }] });
|
|
42
42
|
/**
|
|
@@ -88,7 +88,7 @@ export function createServer(root = ROOT) {
|
|
|
88
88
|
},
|
|
89
89
|
{
|
|
90
90
|
name: "author_agents_md",
|
|
91
|
-
description: "Author an AGENTS.md for this project from
|
|
91
|
+
description: "Author an AGENTS.md for this project and return the draft — BETTER from repo facts alone (via agents-md-facts: real build/test commands, entry points, toolchain conventions, nothing invented), or BEST when a project.faf exists (facts plus its structured goal/who/why as a second managed block ahead of them). Does not write a file.",
|
|
92
92
|
inputSchema: { type: "object", properties: {} },
|
|
93
93
|
},
|
|
94
94
|
{
|
|
@@ -170,9 +170,10 @@ export function createServer(root = ROOT) {
|
|
|
170
170
|
}
|
|
171
171
|
case "author_agents_md": {
|
|
172
172
|
const a = authorAgentsMd(root);
|
|
173
|
+
const tier = a.tier === "best" ? "BEST (project.faf + facts)" : "BETTER (facts only)";
|
|
173
174
|
const note = a.exists
|
|
174
|
-
?
|
|
175
|
-
:
|
|
175
|
+
? `${tier} — AGENTS.md already exists, diff this in, don't overwrite`
|
|
176
|
+
: `${tier} — no AGENTS.md yet, write this, then \`npx agents-md-facts --check\` keeps the facts block true`;
|
|
176
177
|
return text(`<!-- ${note} -->\n\n${a.markdown}`);
|
|
177
178
|
}
|
|
178
179
|
case "remember": {
|
package/dist/transport/http.js
CHANGED
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
* A Hono app. `POST /mcp` is the MCP endpoint, run **stateless**: a fresh
|
|
5
5
|
* server + transport per request, `sessionIdGenerator: undefined`, and
|
|
6
6
|
* `enableJsonResponse` so every response is a complete JSON body (no SSE
|
|
7
|
-
* stream, nothing to keep open). That's the right default
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* stream, nothing to keep open). That's the right default here — it scales
|
|
8
|
+
* horizontally, needs no sticky sessions, and there's no per-connection
|
|
9
|
+
* state to leak. A server that needs server-streamed
|
|
10
10
|
* notifications or resumability would set a `sessionIdGenerator` and hold
|
|
11
11
|
* transports in a map; this one deliberately does not.
|
|
12
12
|
*
|
|
13
13
|
* Alongside the MCP endpoint it serves the discovery documents:
|
|
14
|
-
* GET /.well-known/mcp/server-card — the Server Card + _meta
|
|
14
|
+
* GET /.well-known/mcp/server-card — the Server Card + _meta block
|
|
15
15
|
* GET /.well-known/ai-catalog.json — the three sibling entries
|
|
16
16
|
* GET /.well-known/fafa — the agent identity card
|
|
17
17
|
*/
|
package/docs/MECHANISMS.md
CHANGED
|
@@ -5,7 +5,7 @@ mechanisms that already exist in the MCP ecosystem. This is the wire‑level
|
|
|
5
5
|
detail.
|
|
6
6
|
|
|
7
7
|
The **context** concern points at `AGENTS.md` (`text/markdown`). Memory and
|
|
8
|
-
identity have no de‑facto standard, so
|
|
8
|
+
identity have no de‑facto standard, so this server points them at `.fafm` and
|
|
9
9
|
`.fafa`. Everything below is about the *shape* — swap the artifacts and the
|
|
10
10
|
mechanism is unchanged.
|
|
11
11
|
|
|
@@ -29,7 +29,7 @@ Both return:
|
|
|
29
29
|
```jsonc
|
|
30
30
|
{
|
|
31
31
|
"name": "mcp-context-card",
|
|
32
|
-
"version": "0.2
|
|
32
|
+
"version": "0.5.2",
|
|
33
33
|
"_meta": {
|
|
34
34
|
"io.github.wolfe-jam.mcp-context-card/context": {
|
|
35
35
|
"source": "AGENTS.md",
|
|
@@ -39,7 +39,7 @@ Both return:
|
|
|
39
39
|
"source": "project.fafm",
|
|
40
40
|
"mediaType": "application/vnd.fafm+yaml",
|
|
41
41
|
"iana": "https://www.iana.org/assignments/media-types/application/vnd.fafm+yaml",
|
|
42
|
-
"note": "no de-facto standard for agent memory yet — one instantiation"
|
|
42
|
+
"note": "no de-facto standard for agent memory yet — this is one instantiation"
|
|
43
43
|
},
|
|
44
44
|
"io.github.wolfe-jam.mcp-context-card/identity": {
|
|
45
45
|
"source": ".well-known/fafa",
|
|
@@ -64,7 +64,7 @@ Both return:
|
|
|
64
64
|
is for instructions; the block says so rather than implying `.fafm` is a
|
|
65
65
|
standard.
|
|
66
66
|
|
|
67
|
-
Built by `
|
|
67
|
+
Built by `serverCardMeta()` in [`src/identity.ts`](../src/identity.ts).
|
|
68
68
|
|
|
69
69
|
---
|
|
70
70
|
|
|
@@ -129,7 +129,7 @@ project.fafm ─┼─→ Server Card _meta (context · memory · identity)
|
|
|
129
129
|
fafa
|
|
130
130
|
```
|
|
131
131
|
|
|
132
|
-
`catalog-gen.ts` reads exactly the files `
|
|
132
|
+
`catalog-gen.ts` reads exactly the files `serverCardMeta()` names. The CI job
|
|
133
133
|
`npm run catalog:check` regenerates `ai-catalog.json` and fails on any drift —
|
|
134
134
|
change a source, both surfaces move together.
|
|
135
135
|
|
package/docs/TRANSPORT.md
CHANGED
|
@@ -41,7 +41,7 @@ the wire, so all logging goes to `stderr`.
|
|
|
41
41
|
```
|
|
42
42
|
GET / → index (endpoints)
|
|
43
43
|
POST /mcp → MCP (initialize, tools/list, tools/call, …)
|
|
44
|
-
GET /.well-known/mcp/server-card → the Server Card + _meta
|
|
44
|
+
GET /.well-known/mcp/server-card → the Server Card + _meta block
|
|
45
45
|
GET /.well-known/ai-catalog.json → the three sibling entries
|
|
46
46
|
GET /.well-known/fafa → the agent identity card
|
|
47
47
|
```
|
|
@@ -81,6 +81,6 @@ streaming tools would flip this. See `src/transport/http.ts`.
|
|
|
81
81
|
|
|
82
82
|
### DNS-rebinding protection
|
|
83
83
|
|
|
84
|
-
Off by default (
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
Off by default (the server should run anywhere with no config). For a real
|
|
85
|
+
deployment, pass `allowedHosts` / `allowedOrigins` to the transport and set
|
|
86
|
+
`enableDnsRebindingProtection: true`.
|
package/docs/WIRING.md
CHANGED
|
@@ -26,6 +26,13 @@
|
|
|
26
26
|
- **`MCP_CONTEXT_CARD_ROOT`** — directory holding `AGENTS.md`, `project.fafm`, and
|
|
27
27
|
`.well-known/fafa`. Omit it and the server uses its own bundled copies.
|
|
28
28
|
- `stdout` is the JSON‑RPC wire; logging is on `stderr`.
|
|
29
|
+
- **`command: "npx"` fails to spawn on some hosts** (`spawn npx ENOENT`) — the
|
|
30
|
+
host's process spawn doesn't inherit a shell `PATH` that has `npx` on it,
|
|
31
|
+
even though a login shell does. Observed with Cursor. Fix: point `command`
|
|
32
|
+
at an absolute path to `node`, with the installed package's `dist/bin.js` as
|
|
33
|
+
the arg — e.g. `command: "node"`, `args: ["/path/to/node_modules/mcp-context-card/dist/bin.js"]`
|
|
34
|
+
(or wherever `npm install -g` / your package manager put it; find it with
|
|
35
|
+
`npm root -g` or `which mcp-context-card` after a global install).
|
|
29
36
|
|
|
30
37
|
### Streamable HTTP (remote)
|
|
31
38
|
|
|
@@ -72,7 +79,10 @@ And to discover what a server offers before committing to it:
|
|
|
72
79
|
await client.callTool({ name: "list_context_sources", arguments: {} });
|
|
73
80
|
// → { context: { source: "AGENTS.md", mediaType: "text/markdown", present: true, sections: 9 },
|
|
74
81
|
// memory: { … }, identity: { … },
|
|
75
|
-
// surfaces: {
|
|
82
|
+
// surfaces: { mcp: { serverCard: "resource mcp-context-card://server-card" },
|
|
83
|
+
// http: { serverCard: "GET /.well-known/mcp/server-card",
|
|
84
|
+
// aiCatalog: "GET /.well-known/ai-catalog.json",
|
|
85
|
+
// card: "GET /card" } } }
|
|
76
86
|
```
|
|
77
87
|
|
|
78
88
|
---
|
|
@@ -84,11 +94,11 @@ To serve *your* artifacts:
|
|
|
84
94
|
1. **Replace the three files** — `AGENTS.md`, `project.fafm`, `.well-known/fafa`
|
|
85
95
|
— with your own, or point `MCP_CONTEXT_CARD_ROOT` at a directory that has them.
|
|
86
96
|
`AGENTS.md` is the one with a real standard; the other two are swappable.
|
|
87
|
-
2. **Rename the namespace.** `
|
|
97
|
+
2. **Rename the namespace.** `serverCardMeta()` in `src/identity.ts` uses
|
|
88
98
|
`io.github.wolfe-jam.mcp-context-card/*` keys, and `buildCatalog()` in
|
|
89
99
|
`src/catalog-gen.ts` uses `urn:air:mcp-context-card:*` identifiers. Change both to
|
|
90
100
|
a domain or GitHub identity you control ([MECHANISMS.md](./MECHANISMS.md)).
|
|
91
|
-
3. **Swap the media types** in `
|
|
101
|
+
3. **Swap the media types** in `serverCardMeta()` if your memory / identity
|
|
92
102
|
artifacts aren't `.fafm` / `.fafa`. Drop the `iana` field for any that isn't
|
|
93
103
|
a registered type.
|
|
94
104
|
4. `npm run catalog` to regenerate, `npm run demo` to confirm all three still
|
package/docs/card.html
CHANGED
|
@@ -73,11 +73,11 @@ section:last-child{border-bottom:0}
|
|
|
73
73
|
<main class="card">
|
|
74
74
|
<div class="top">
|
|
75
75
|
<h1>mcp-context-card</h1>
|
|
76
|
-
<div class="pills"><span class="pill">v0.5.
|
|
76
|
+
<div class="pills"><span class="pill">io.github.wolfe-jam</span><span class="pill">v0.5.2</span><span class="pill accent">published</span><span class="pill">MIT</span></div>
|
|
77
77
|
</div>
|
|
78
78
|
<section>
|
|
79
79
|
<p class="label">Context — AGENTS.md</p>
|
|
80
|
-
<ul class="toc"><li><a href="#setup">Setup</a></li><li><a href="#build">Build</a></li><li><a href="#test">Test</a></li><li><a href="#layout">Layout</a></li><li><a href="#conventions">Conventions</a></li><li><a href="#the-invariant">The invariant</a></li><li><a href="#safety">Safety</a></li><li><a href="#definition-of-done">Definition of done</a></li><li><a href="#authoring-this-file">Authoring this file</a></li></ul><div class="md"><p><code>mcp-context-card</code> is
|
|
80
|
+
<ul class="toc"><li><a href="#setup">Setup</a></li><li><a href="#build">Build</a></li><li><a href="#test">Test</a></li><li><a href="#layout">Layout</a></li><li><a href="#conventions">Conventions</a></li><li><a href="#the-invariant">The invariant</a></li><li><a href="#safety">Safety</a></li><li><a href="#definition-of-done">Definition of done</a></li><li><a href="#authoring-this-file">Authoring this file</a></li></ul><div class="md"><p><code>mcp-context-card</code> is the essential MCP server for a project's <strong>context</strong> (this file), <strong>memory</strong>, and <strong>identity</strong> — usable as your base MCP, or dropped into any existing MCP server as an extension. Discoverable to any MCP client through the two surfaces already in the ecosystem: the Server Card <code>_meta</code> block and <code>ai-catalog.json</code> sibling entries.</p>
|
|
81
81
|
<p><code>read_agents_md</code> serves this file, section by section, over the same MCP connection.</p>
|
|
82
82
|
<h2 id="setup">Setup</h2>
|
|
83
83
|
<pre><code class="language-bash">npm ci</code></pre>
|
|
@@ -91,7 +91,7 @@ npm run test:coverage # + the coverage gate (lines 90 / funcs 85 / branches 80,
|
|
|
91
91
|
npm run demo # end to end: all tools over stdio, then over stateless HTTP</code></pre>
|
|
92
92
|
<p>CI runs <code>typecheck → build → test:coverage → demo</code> on Linux, macOS, and Windows for every push and PR to <code>main</code> (<code>.github/workflows/ci.yml</code>).</p>
|
|
93
93
|
<h2 id="layout">Layout</h2>
|
|
94
|
-
<table><thead><tr><th>Path</th><th>What</th></tr></thead><tbody><tr><td><code>src/server.ts</code></td><td>the MCP server — the nine tools + the Server Card resource</td></tr><tr><td><code>src/agents-md.ts</code></td><td>reads and section-splits this file</td></tr><tr><td><code>src/author.ts</code></td><td><code>author_agents_md</code> —
|
|
94
|
+
<table><thead><tr><th>Path</th><th>What</th></tr></thead><tbody><tr><td><code>src/server.ts</code></td><td>the MCP server — the nine tools + the Server Card resource</td></tr><tr><td><code>src/agents-md.ts</code></td><td>reads and section-splits this file</td></tr><tr><td><code>src/author.ts</code></td><td><code>author_agents_md</code> — BETTER via <code>agents-md-facts</code>, BEST when <code>project.faf</code> exists</td></tr><tr><td><code>src/md.ts</code></td><td>a minimal dependency-free Markdown → HTML renderer</td></tr><tr><td><code>src/render-card.ts</code></td><td>the card — identity + this file + memory + discovery, as one HTML page</td></tr><tr><td><code>src/memory.ts</code> → <code>src/faf/parse-fafm.ts</code></td><td>file-backed <code>remember</code> / <code>recall</code> / <code>forget</code></td></tr><tr><td><code>src/identity.ts</code></td><td><code>whoami</code> (<code>.fafa</code> → <code>package.json</code> fallback) + the <code>_meta</code> context block</td></tr><tr><td><code>src/catalog-gen.ts</code></td><td>writes <code>.well-known/ai-catalog.json</code> from the same three sources</td></tr><tr><td><code>src/transport/http.ts</code></td><td>the stateless Streamable HTTP app (Hono)</td></tr><tr><td><code>src/bin.ts</code></td><td>the entry point (<code>resolveLaunch</code>) — <code>stdio</code> · <code>--http</code> · <code>card</code> · <code>--help</code> · <code>--version</code></td></tr><tr><td><code>src/faf/parse-fafm.ts</code> · <code>parse-fafa.ts</code></td><td>the <code>.fafm</code> / <code>.fafa</code> parsers</td></tr></tbody></table>
|
|
95
95
|
<h2 id="conventions">Conventions</h2>
|
|
96
96
|
<ul><li>TypeScript strict, ESM only (<code>"type": "module"</code>, <code>.js</code> import specifiers).</li><li>Tests use <code>node:test</code> + <code>node:assert/strict</code> — no test framework.</li><li>Every source file opens with a comment stating what it is and why.</li><li>Conventional Commit messages (<code>feat:</code>, <code>fix:</code>, <code>chore:</code>, <code>test:</code>, <code>docs:</code>).</li></ul>
|
|
97
97
|
<h2 id="the-invariant">The invariant</h2>
|
|
@@ -101,11 +101,11 @@ npm run demo # end to end: all tools over stdio, then over stateless HT
|
|
|
101
101
|
<h2 id="definition-of-done">Definition of done</h2>
|
|
102
102
|
<p><code>npm run typecheck && npm run build && npm test && npm run demo</code> all green, plus <code>npm run catalog:check</code> and <code>npm run card:check</code> clean if you touched <code>AGENTS.md</code>, <code>project.fafm</code>, or <code>.well-known/fafa</code>.</p>
|
|
103
103
|
<h2 id="authoring-this-file">Authoring this file</h2>
|
|
104
|
-
<p><code>AGENTS.md</code> here is maintained by hand.
|
|
104
|
+
<p><code>AGENTS.md</code> here is maintained by hand. The <code>author_agents_md</code> tool (or <code>faf export --agents</code>) would draft a BEST version straight from this repo's own <code>project.faf</code> plus its detected facts — the server doesn't care how the file was authored, only that it's valid Markdown.</p></div>
|
|
105
105
|
</section>
|
|
106
106
|
<section>
|
|
107
|
-
<p class="label">Memory —
|
|
108
|
-
<div class="fact"><p>The context concern points at AGENTS.md — the de-facto standard for agent instructions. read_agents_md serves it whole or one section at a time, so a client pulls '## Test' without spending its context window on the whole file. Memory and identity have no de-facto standard, so
|
|
107
|
+
<p class="label">Memory — 4 facts</p>
|
|
108
|
+
<div class="fact"><p>The context concern points at AGENTS.md — the de-facto standard for agent instructions. read_agents_md serves it whole or one section at a time, so a client pulls '## Test' without spending its context window on the whole file. Memory and identity have no de-facto standard, so this server uses .fafm and .fafa as one instantiation each.</p><div class="meta"><span class="tag">scope</span><span class="tag">agents-md</span><span class="dot" title="verified"></span></div></div><div class="fact"><p>Both exposure mechanisms — the Server Card _meta block and a self-published ai-catalog.json — already exist in the MCP ecosystem. This server wires all three concerns through them, from one set of source files, with a CI check (catalog:check) that fails if the two surfaces drift apart.</p><div class="meta"><span class="tag">mcp</span><span class="tag">server-card</span><span class="tag">ai-catalog</span><span class="dot" title="verified"></span></div></div><div class="fact"><p>Distribution: a published npm package (bin <code>mcp-context-card</code>, dual transport). The three source files (AGENTS.md, project.fafm, .well-known/fafa) ship with the package so it is a working discovery target on install. MCP_CONTEXT_CARD_ROOT points it at a real project.</p><div class="meta"><span class="tag">distribution</span><span class="tag">mit</span><span class="tag">npm</span><span class="dot" title="verified"></span></div></div><div class="fact"><p>author_agents_md authors the best AGENTS.md the project has the material for, not a fixed floor. BETTER is the facts-only draft (via agents-md-facts: build/test commands, entry points, conventions — nothing invented). BEST is that plus a '## Project' section ahead of it, read straight from project.faf when one exists — goal, who it's for, why, and a start-here file list. The rule is concrete: project.faf present means BEST, absent means BETTER.</p><div class="meta"><span class="tag">agents-md</span><span class="tag">author_agents_md</span><span class="tag">faf</span><span class="dot" title="verified"></span></div></div>
|
|
109
109
|
</section>
|
|
110
110
|
<section>
|
|
111
111
|
<p class="label">Discovery</p>
|
package/docs/img/card.png
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-context-card",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"mcpName": "io.github.wolfe-jam/mcp-context-card",
|
|
5
|
-
"description": "
|
|
5
|
+
"description": "The essential MCP components for a project's context (AGENTS.md), cross-session memory, and identity — a base MCP on its own, or a drop-in extension for any existing MCP server. Discoverable through the Server Card _meta block and ai-catalog.json sibling entries.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mcp",
|
|
8
8
|
"model-context-protocol",
|
|
9
|
+
"agents-md",
|
|
9
10
|
"server-card",
|
|
10
11
|
"ai-catalog",
|
|
11
12
|
"project-context",
|
|
12
13
|
"agent-memory",
|
|
13
14
|
"agent-identity"
|
|
14
15
|
],
|
|
15
|
-
"author": "
|
|
16
|
+
"author": "James Wolfe",
|
|
16
17
|
"license": "MIT",
|
|
17
18
|
"type": "module",
|
|
18
19
|
"private": false,
|
package/project.faf
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
faf_version: "3.0"
|
|
2
2
|
project:
|
|
3
3
|
name: mcp-context-card
|
|
4
|
-
goal:
|
|
4
|
+
goal: The essential MCP server for a project's context (its AGENTS.md), memory, and identity — usable as a base MCP on its own, or as a drop-in extension for any existing MCP server. Discoverable to any MCP client through the Server Card _meta block and ai-catalog.json sibling entries, the two surfaces already in the ecosystem.
|
|
5
5
|
main_language: TypeScript
|
|
6
6
|
type: mcp
|
|
7
7
|
stack:
|
|
@@ -16,13 +16,13 @@ stack:
|
|
|
16
16
|
database: slotignored # memory is a file, not a DB
|
|
17
17
|
connection: slotignored # no database
|
|
18
18
|
hosting: Docker / any Node host — stdio for local, stateless Streamable HTTP for remote
|
|
19
|
-
cicd: GitHub Actions
|
|
20
|
-
tech_stack: [TypeScript, "@modelcontextprotocol/sdk", hono, yaml]
|
|
19
|
+
cicd: GitHub Actions — typecheck + build + test:coverage + demo on 3 OSes; catalog:check + card:check on Linux
|
|
20
|
+
tech_stack: [TypeScript, "@modelcontextprotocol/sdk", "agents-md-facts", hono, yaml]
|
|
21
21
|
human_context:
|
|
22
22
|
who: MCP host and server implementers who want a project's AGENTS.md, memory, and identity available over MCP without inventing an ad-hoc shape for each.
|
|
23
|
-
what:
|
|
24
|
-
why: AGENTS.md is the de-facto standard for agent instructions, but a client has to know the file exists and read it whole. There is no standard way for a server to publish "here is my AGENTS.md, here is what I remember, here is who I am". This does it through mechanisms that already exist.
|
|
23
|
+
what: The essential context, memory, and identity components for MCP — usable as a base MCP on its own, or dropped into any existing MCP server as an extension. Nine tools — read_agents_md / list_agents_md_sections / author_agents_md (context), remember / recall / forget (memory), whoami (identity), list_context_sources / render_context_card (discovery) — exposed through the Server Card _meta block and a self-published ai-catalog.json. Dual transport (stdio + stateless Streamable HTTP).
|
|
24
|
+
why: AGENTS.md is the de-facto standard for agent instructions, but a client has to know the file exists and read it whole. There is no standard way for a server to publish "here is my AGENTS.md, here is what I remember, here is who I am" — every server that wants this grows its own shape, or does without. This does it once, through mechanisms that already exist — as a base MCP, or dropped into what you've already built.
|
|
25
25
|
where: github.com/Wolfe-Jam/mcp-context-card
|
|
26
26
|
when: "2026-08-12"
|
|
27
27
|
how: TypeScript on the MCP SDK. Dual transport in src/bin.ts. The Server Card _meta block and ai-catalog.json are generated from the same three sources (AGENTS.md, project.fafm, .well-known/fafa) — a CI check fails on drift. remember/recall are real file-backed reads/writes proven across a process boundary in demo.ts and the test suite. See docs/MECHANISMS.md, docs/WIRING.md, docs/TRANSPORT.md.
|
|
28
|
-
key_files: [package.json, README.md, AGENTS.md, docs/MECHANISMS.md, src/server.ts, src/agents-md.ts, src/catalog-gen.ts, src/transport/http.ts]
|
|
28
|
+
key_files: [package.json, README.md, AGENTS.md, docs/MECHANISMS.md, src/server.ts, src/identity.ts, src/render-card.ts, src/author.ts, src/agents-md.ts, src/catalog-gen.ts, src/transport/http.ts]
|
package/project.fafm
CHANGED
|
@@ -17,9 +17,9 @@ index:
|
|
|
17
17
|
|
|
18
18
|
memory:
|
|
19
19
|
facts:
|
|
20
|
-
- text: "The context concern points at AGENTS.md — the de-facto standard for agent instructions. read_agents_md serves it whole or one section at a time, so a client pulls '## Test' without spending its context window on the whole file. Memory and identity have no de-facto standard, so
|
|
20
|
+
- text: "The context concern points at AGENTS.md — the de-facto standard for agent instructions. read_agents_md serves it whole or one section at a time, so a client pulls '## Test' without spending its context window on the whole file. Memory and identity have no de-facto standard, so this server uses .fafm and .fafa as one instantiation each."
|
|
21
21
|
id: "mcp-context-card-scope"
|
|
22
|
-
type: "
|
|
22
|
+
type: "fact"
|
|
23
23
|
priority: "high"
|
|
24
24
|
tags: ["scope", "agents-md"]
|
|
25
25
|
source: "README.md"
|
|
@@ -27,7 +27,7 @@ memory:
|
|
|
27
27
|
|
|
28
28
|
- text: "Both exposure mechanisms — the Server Card _meta block and a self-published ai-catalog.json — already exist in the MCP ecosystem. This server wires all three concerns through them, from one set of source files, with a CI check (catalog:check) that fails if the two surfaces drift apart."
|
|
29
29
|
id: "mechanisms-already-proven"
|
|
30
|
-
type: "
|
|
30
|
+
type: "fact"
|
|
31
31
|
priority: "high"
|
|
32
32
|
tags: ["mcp", "server-card", "ai-catalog"]
|
|
33
33
|
links: ["mcp-context-card-scope"]
|
|
@@ -36,11 +36,20 @@ memory:
|
|
|
36
36
|
|
|
37
37
|
- text: "Distribution: a published npm package (bin `mcp-context-card`, dual transport). The three source files (AGENTS.md, project.fafm, .well-known/fafa) ship with the package so it is a working discovery target on install. MCP_CONTEXT_CARD_ROOT points it at a real project."
|
|
38
38
|
id: "distribution-model"
|
|
39
|
-
type: "
|
|
39
|
+
type: "fact"
|
|
40
40
|
priority: "standard"
|
|
41
41
|
tags: ["distribution", "mit", "npm"]
|
|
42
42
|
source: "README.md"
|
|
43
43
|
verification_status: "verified"
|
|
44
|
+
|
|
45
|
+
- text: "author_agents_md authors the best AGENTS.md the project has the material for, not a fixed floor. BETTER is the facts-only draft (via agents-md-facts: build/test commands, entry points, conventions — nothing invented). BEST is that plus a '## Project' section ahead of it, read straight from project.faf when one exists — goal, who it's for, why, and a start-here file list. The rule is concrete: project.faf present means BEST, absent means BETTER."
|
|
46
|
+
id: "author-agents-md-best-not-just-better"
|
|
47
|
+
type: "fact"
|
|
48
|
+
priority: "high"
|
|
49
|
+
tags: ["agents-md", "author_agents_md", "faf"]
|
|
50
|
+
links: ["mcp-context-card-scope"]
|
|
51
|
+
source: "src/author.ts"
|
|
52
|
+
verification_status: "verified"
|
|
44
53
|
sessions: []
|
|
45
54
|
preferences: {}
|
|
46
55
|
custom: {}
|
package/server.json
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
3
|
"name": "io.github.wolfe-jam/mcp-context-card",
|
|
4
4
|
"title": "mcp-context-card",
|
|
5
|
-
"description": "
|
|
6
|
-
"version": "0.5.
|
|
5
|
+
"description": "The essential MCP components for a project's context (AGENTS.md), cross-session memory, and identity — a base MCP on its own, or a drop-in extension for any existing MCP server. Discoverable through the Server Card _meta block and ai-catalog.json sibling entries.",
|
|
6
|
+
"version": "0.5.2",
|
|
7
7
|
"repository": {
|
|
8
8
|
"url": "https://github.com/Wolfe-Jam/mcp-context-card",
|
|
9
9
|
"source": "github"
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
15
15
|
"identifier": "mcp-context-card",
|
|
16
|
-
"version": "0.5.
|
|
16
|
+
"version": "0.5.2",
|
|
17
17
|
"runtimeHint": "npx",
|
|
18
18
|
"transport": {
|
|
19
19
|
"type": "stdio"
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"environmentVariables": [
|
|
22
22
|
{
|
|
23
23
|
"name": "MCP_CONTEXT_CARD_ROOT",
|
|
24
|
-
"description": "Directory holding project.faf / project.fafm / .well-known/fafa. Omitted → the server's own bundled
|
|
24
|
+
"description": "Directory holding project.faf / project.fafm / .well-known/fafa. Omitted → the server's own bundled copies.",
|
|
25
25
|
"isRequired": false
|
|
26
26
|
}
|
|
27
27
|
]
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"source": "./project.fafm",
|
|
38
38
|
"mediaType": "application/vnd.fafm+yaml",
|
|
39
39
|
"iana": "https://www.iana.org/assignments/media-types/application/vnd.fafm+yaml",
|
|
40
|
-
"note": "no de-facto standard for agent memory yet — one instantiation"
|
|
40
|
+
"note": "no de-facto standard for agent memory yet — this is one instantiation"
|
|
41
41
|
},
|
|
42
42
|
"io.github.wolfe-jam.mcp-context-card/identity": {
|
|
43
43
|
"source": "./.well-known/fafa",
|