mcp-context-card 1.7.0 → 1.8.0
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 +1 -1
- package/.well-known/fafa +1 -1
- package/AGENTS.md +5 -3
- package/CHANGELOG.md +72 -0
- package/README.md +26 -4
- package/dist/bin.d.ts +1 -1
- package/dist/bin.js +12 -3
- package/dist/card-app.bundle.js +103 -0
- package/dist/card-gen.js +15 -6
- package/dist/constants.d.ts +17 -1
- package/dist/constants.js +35 -1
- package/dist/render-card.d.ts +14 -43
- package/dist/render-card.js +96 -327
- package/dist/server-card.js +3 -2
- package/dist/server.d.ts +19 -3
- package/dist/server.js +88 -33
- package/dist/transport/http.js +23 -9
- package/docs/MECHANISMS.md +2 -2
- package/docs/TRANSPORT.md +76 -11
- package/docs/WIRING.md +6 -0
- package/docs/card-dark.html +5 -5
- package/docs/card-light.html +5 -5
- package/docs/card.html +5 -5
- package/docs/img/card-dark.png +0 -0
- package/docs/img/card-identity.png +0 -0
- package/docs/img/card-light.png +0 -0
- package/docs/index.html +5 -5
- package/package.json +10 -6
- package/project.faf +1 -1
- package/server.json +2 -2
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"data": {
|
|
12
12
|
"$schema": "https://static.modelcontextprotocol.io/schemas/v1/server-card.schema.json",
|
|
13
13
|
"name": "io.github.Wolfe-Jam/mcp-context-card",
|
|
14
|
-
"version": "1.
|
|
14
|
+
"version": "1.8.0",
|
|
15
15
|
"title": "MCP Context Card",
|
|
16
16
|
"description": "MCP server for a project's context (AGENTS.md), memory, and identity — base or drop-in extension.",
|
|
17
17
|
"websiteUrl": "https://github.com/Wolfe-Jam/mcp-context-card",
|
package/.well-known/fafa
CHANGED
|
@@ -13,7 +13,7 @@ agent:
|
|
|
13
13
|
# a deployment for your own project uses your domain.
|
|
14
14
|
id: "urn:air:faf.one:agent:mcp-context-card"
|
|
15
15
|
vendor: "io.github.Wolfe-Jam"
|
|
16
|
-
version: "1.
|
|
16
|
+
version: "1.8.0"
|
|
17
17
|
description: >-
|
|
18
18
|
The essential MCP components for a project's context (AGENTS.md),
|
|
19
19
|
cross-session memory, and identity — a base MCP on its own, or a
|
package/AGENTS.md
CHANGED
|
@@ -20,8 +20,8 @@ Node 22 or newer. No other system dependencies.
|
|
|
20
20
|
## Build
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
npm run build # tsc -p tsconfig.build.json
|
|
24
|
-
npm run typecheck # tsc --noEmit over src/ + test
|
|
23
|
+
npm run build # tsc -p tsconfig.build.json, then copy the bundled card script → dist/
|
|
24
|
+
npm run typecheck # tsc --noEmit over src/ + test/, then the browser script
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
## Test
|
|
@@ -50,6 +50,8 @@ code's shape moved without `project.faf`) on Linux.
|
|
|
50
50
|
| `src/author.ts` | `author_agents_md` — BETTER via `agents-md-facts`, BEST when `project.faf` exists |
|
|
51
51
|
| `src/md.ts` | a minimal dependency-free Markdown → HTML renderer |
|
|
52
52
|
| `src/render-card.ts` | the card — identity + this file + memory + discovery, as one HTML page |
|
|
53
|
+
| `src/browser/card-app.ts` | the card's MCP Apps script (size, inline view), inlined only into the `ui://` resource |
|
|
54
|
+
| `scripts/bundle-card-app.mjs` | bundles the script so the sandbox loads nothing from the network |
|
|
53
55
|
| `src/memory.ts` → `src/faf/parse-fafm.ts` | file-backed `remember` / `recall` / `forget` |
|
|
54
56
|
| `src/identity.ts` | `whoami` (`.fafa` → `package.json` fallback) + the `_meta` context block |
|
|
55
57
|
| `src/catalog-gen.ts` | writes `.well-known/ai-catalog.json` from the same three sources |
|
|
@@ -70,7 +72,7 @@ code's shape moved without `project.faf`) on Linux.
|
|
|
70
72
|
the **same three sources**: this file, `project.fafm`, `.well-known/fafa`.
|
|
71
73
|
Change what one exposes and you must change the others. `npm run catalog:check`
|
|
72
74
|
and `npm run card:check` enforce it in CI — each regenerates its surface and
|
|
73
|
-
fails on any diff.
|
|
75
|
+
fails on any diff. `card:check` also fails if a plain card exceeds 64 KB.
|
|
74
76
|
|
|
75
77
|
## Safety
|
|
76
78
|
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,78 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project. Adheres to [Semantic Versioning](https://semver.org).
|
|
4
4
|
|
|
5
|
+
## 1.8.0
|
|
6
|
+
|
|
7
|
+
Speaks MCP 2026-07-28 as well as 2025, on the MCP SDK v2, and the card fits a chat panel. Library users: see the breaking note at the end.
|
|
8
|
+
|
|
9
|
+
- **The card tells the host how big it is.** Hosts that support MCP Apps
|
|
10
|
+
read `ui://mcp-context-card/card.html`. That resource is the card plus
|
|
11
|
+
the start-up exchange (`ui/initialize`, then
|
|
12
|
+
`ui/notifications/initialized`) and `ui/notifications/size-changed`
|
|
13
|
+
when the document's size changes. The helper is
|
|
14
|
+
`@modelcontextprotocol/ext-apps` `App` with `autoResize: true`, bundled
|
|
15
|
+
at build time (`scripts/bundle-card-app.mjs`) into that resource only, so
|
|
16
|
+
the sandbox still has no CDN and no external request. The tool text for a
|
|
17
|
+
client without MCP Apps, `save_context_card`, `GET /card`, and the CLI
|
|
18
|
+
are the plain card, without that script. `card:check` fails if a plain
|
|
19
|
+
card exceeds 64 KB. The card still works with the script off.
|
|
20
|
+
`card --stdout` exits 0 when the reader closes the pipe early, and exits
|
|
21
|
+
1 with a message on any other failed write.
|
|
22
|
+
- **You choose whether the host's card carries the helper.**
|
|
23
|
+
`MCP_CONTEXT_CARD_APP=helper` (the default) or `plain`. `plain` makes the
|
|
24
|
+
`ui://` card the plain card (~30 KB, no MCP Apps messages) for hosts where
|
|
25
|
+
the ~700 KB helper isn't worth it. Only that resource changes.
|
|
26
|
+
`list_context_sources` reports the active value. Any case is read; an
|
|
27
|
+
unknown value warns once on stderr and uses `helper`.
|
|
28
|
+
- **An inline view for chat panels.** Inside an MCP Apps host, display mode
|
|
29
|
+
`inline` or `pip` (`McpUiHostContext.displayMode`) shows a mini card:
|
|
30
|
+
monogram, name, kind · version, one line, and a counts strip (sections ·
|
|
31
|
+
facts · identity). One action, "Open full card", calls
|
|
32
|
+
`requestDisplayMode({ mode: "fullscreen" })` when `availableDisplayModes`
|
|
33
|
+
includes `fullscreen`. The full card shows when the host is fullscreen, or
|
|
34
|
+
when there is no host. A host that stays smaller points to
|
|
35
|
+
`save_context_card`, which writes the full card to `context-card.html`.
|
|
36
|
+
The card declares the display modes it supports (inline, pip,
|
|
37
|
+
fullscreen) when it starts, as the MCP Apps spec requires. The mini card
|
|
38
|
+
is part of the `ui://` resource only, hidden until the host says the
|
|
39
|
+
panel is inline. The plain card does not include it, and the script off
|
|
40
|
+
still shows the full card.
|
|
41
|
+
- **Both protocol eras, both transports.** A client that opens with
|
|
42
|
+
`server/discover` (Claude Code, goose) connects on 2026-07-28; a client
|
|
43
|
+
that opens with `initialize` gets 2025, unchanged. The Server Card lists
|
|
44
|
+
2026-07-28 first. See [docs/TRANSPORT.md](docs/TRANSPORT.md#protocol-eras).
|
|
45
|
+
- **Roots on 2026-07-28** are asked in-band (`input_required`), once per
|
|
46
|
+
connection, since that revision has no server-to-client requests and no
|
|
47
|
+
`roots/list_changed`. Roots sent with a later call replace the first. A
|
|
48
|
+
client that declares `roots` but can't answer now fails the tool call on
|
|
49
|
+
2026-07-28; on 2025 it still falls back to the start directory.
|
|
50
|
+
- **Breaking for library users** (the `mcp-context-card/server` export): it
|
|
51
|
+
is built on `@modelcontextprotocol/server` 2.x instead of
|
|
52
|
+
`@modelcontextprotocol/sdk` 1.x. `createServer()` returns a v2 `Server`, so
|
|
53
|
+
`setRequestHandler(SomeRequestSchema, …)` now throws; register by method
|
|
54
|
+
string (`setRequestHandler("prompts/list", …)`). The types come from
|
|
55
|
+
`@modelcontextprotocol/server`, and `zod` 4 comes with it. See the SDK's
|
|
56
|
+
[upgrade guide](https://github.com/modelcontextprotocol/typescript-sdk/blob/main/docs/migration/upgrade-to-v2.md).
|
|
57
|
+
New: `serveStdioServer()` serves stdio on both eras; `serve(transport)` is
|
|
58
|
+
kept and serves 2025. The CLI and the MCP surface are unchanged.
|
|
59
|
+
|
|
60
|
+
## 1.7.1
|
|
61
|
+
|
|
62
|
+
The business card printer is now its own package.
|
|
63
|
+
|
|
64
|
+
- [agent-business-card](https://www.npmjs.com/package/agent-business-card)
|
|
65
|
+
renders the business card and prints it to screen. It is a new
|
|
66
|
+
dependency. Printing a business card no longer needs an MCP server: the
|
|
67
|
+
renderer has no dependencies and runs in the browser, so any page or tool
|
|
68
|
+
can print the same business card from its own facts (an A2A Agent Card,
|
|
69
|
+
an MCP Server Card, a `.fafa`). mcp-context-card is one reader that
|
|
70
|
+
supplies them.
|
|
71
|
+
- Same code, moved unchanged. The business cards are byte-identical to
|
|
72
|
+
1.7.0.
|
|
73
|
+
- `renderBusinessCard`, `cardInitials`, `safeAccent` and the `BusinessCard`
|
|
74
|
+
types are still exported from `render-card`, so nothing changes for
|
|
75
|
+
callers.
|
|
76
|
+
|
|
5
77
|
## 1.7.0
|
|
6
78
|
|
|
7
79
|
A card's colour is the owner's.
|
package/README.md
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
[](https://github.com/Wolfe-Jam/mcp-context-card/actions/workflows/ci.yml)
|
|
5
5
|
[](./LICENSE)
|
|
6
6
|
[](https://glama.ai/mcp/servers/Wolfe-Jam/mcp-context-card)
|
|
7
|
+
[](https://wolfe-jam.github.io/agent-business-card/?repo=Wolfe-Jam/mcp-context-card)
|
|
7
8
|
|
|
8
9
|
**Get one. Or add it to yours.** The essential MCP server for a project's
|
|
9
10
|
context, memory, and identity — discoverable to any MCP client, and
|
|
@@ -95,8 +96,22 @@ people: read it, screenshot it, drop it in a PR, put it on a status page.
|
|
|
95
96
|
|
|
96
97
|
Flip, tabs and the view switch are plain CSS, so they work with scripts off.
|
|
97
98
|
The one small inline script adds Expand all, opens a `#section` link on the
|
|
98
|
-
back, and opens every section for printing.
|
|
99
|
-
|
|
99
|
+
back, and opens every section for printing. Hosts that support MCP Apps read
|
|
100
|
+
`ui://mcp-context-card/card.html`: this same page, plus a hidden inline view
|
|
101
|
+
and the helper bundled in (`scripts/bundle-card-app.mjs`), so the host can
|
|
102
|
+
fit its frame. Nothing is loaded from the network. The saved
|
|
103
|
+
`context-card.html`, `GET /card`, and the CLI are the plain page, without
|
|
104
|
+
that helper and without the inline view.
|
|
105
|
+
|
|
106
|
+
In a host, the inline view is a mini card for the panel: monogram, name,
|
|
107
|
+
kind · version, one line, and a strip of counts (sections · facts ·
|
|
108
|
+
identity), with one action, "Open full card". It shows when the host's
|
|
109
|
+
display mode is inline (or picture-in-picture). Fullscreen, and any page
|
|
110
|
+
with no host, is the full card. "Open full card" asks the host for
|
|
111
|
+
fullscreen; a host that stays smaller points to `save_context_card`, which
|
|
112
|
+
writes the full card to `context-card.html`.
|
|
113
|
+
`--expanded` / `?expand=all` renders both faces flat, every section open,
|
|
114
|
+
for a screenshot or print.
|
|
100
115
|
|
|
101
116
|
```
|
|
102
117
|
npx mcp-context-card card # at a terminal: writes context-card.html and opens it
|
|
@@ -192,6 +207,13 @@ never serves or lists `project.fafm`, unless you set
|
|
|
192
207
|
`MCP_CONTEXT_CARD_PUBLISH_MEMORY=1`. Details:
|
|
193
208
|
[docs/TRANSPORT.md](./docs/TRANSPORT.md#security-local-by-default).
|
|
194
209
|
|
|
210
|
+
In a host that shows MCP Apps (goose, for one), the card comes with the
|
|
211
|
+
official MCP Apps helper, so it reports its size and fits its frame (about
|
|
212
|
+
700 KB, loaded by the host, not the model). For the plain card instead
|
|
213
|
+
(about 30 KB, the host's default frame), set
|
|
214
|
+
`"env": { "MCP_CONTEXT_CARD_APP": "plain" }`. Everywhere else the card is
|
|
215
|
+
plain either way.
|
|
216
|
+
|
|
195
217
|
If `command: "npx"` fails to spawn (`spawn npx ENOENT` — seen on Cursor, whose
|
|
196
218
|
host process doesn't inherit a shell `PATH`), point `command` at `node` and
|
|
197
219
|
the installed `dist/bin.js` instead — see
|
|
@@ -274,7 +296,7 @@ over both transports:
|
|
|
274
296
|
4. **Discovery** — `list_context_sources()`, then the same server over stateless
|
|
275
297
|
HTTP with its `.well-known` routes and `GET /card`.
|
|
276
298
|
|
|
277
|
-
|
|
299
|
+
245 tests on Linux, macOS, and Windows, coverage‑gated in CI.
|
|
278
300
|
`npm run wjttc` runs the WJTTC certification suite (seven tiers, from protocol
|
|
279
301
|
and Server Card conformance to stdio/HTTP parity and the shipped package). Two spawn a real
|
|
280
302
|
child process and check a remembered fact survives the restart — one against
|
|
@@ -292,7 +314,7 @@ transport security against the specs, one MUST or SHOULD at a time.
|
|
|
292
314
|
| `src/agents-md.ts` | reads and section‑splits `AGENTS.md` |
|
|
293
315
|
| `src/author.ts` | `author_agents_md` — BETTER via [`agents-md-facts`](https://github.com/Wolfe-Jam/agents-md-facts), BEST when `project.faf` exists |
|
|
294
316
|
| `src/md.ts` | a minimal dependency‑free Markdown → HTML renderer |
|
|
295
|
-
| `src/render-card.ts` | the card — identity + `AGENTS.md` + memory + discovery
|
|
317
|
+
| `src/render-card.ts` | the card — reads identity + `AGENTS.md` + memory + discovery into a card; [`agent-business-card`](https://github.com/Wolfe-Jam/agent-business-card) draws it as one HTML page |
|
|
296
318
|
| `src/memory.ts` | file‑backed `remember` / `recall` / `forget` |
|
|
297
319
|
| `src/identity.ts` | `whoami` (`.fafa` → `package.json` fallback) + the `_meta` block |
|
|
298
320
|
| `src/server-card.ts` | the MCP Server Card (SEP-2127, schema v1) |
|
package/dist/bin.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export interface Launch {
|
|
|
8
8
|
root: string;
|
|
9
9
|
}
|
|
10
10
|
/** what a bare `--help` / `help` prints. */
|
|
11
|
-
export declare const HELP = "mcp-context-card 1.
|
|
11
|
+
export declare const HELP = "mcp-context-card 1.8.0\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 this dir's context card \u2014 opens it in your browser\n at a terminal; HTML to stdout when piped ( > f.html )\n --theme light|dark --accent #hex\n --expanded (all sections open) --portrait --stdout\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 HOST HTTP bind address (default 127.0.0.1, this machine\n only); 0.0.0.0 exposes it, e.g. in a container\n MCP_CONTEXT_CARD_ALLOWED_HOSTS / _ALLOWED_ORIGINS\n comma-separated Host names / browser origins to\n accept besides this machine's own (reverse proxy, web app)\n MCP_CONTEXT_CARD_PUBLISH_MEMORY=1\n HTTP: serve project.fafm, list it in the AI Catalog,\n and show its facts on an exposed /card (off: memory\n is session data). HTTP has no auth\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` (opens your context in a browser) or `--http`.\nhttps://github.com/Wolfe-Jam/mcp-context-card\n";
|
|
12
12
|
/**
|
|
13
13
|
* The address the HTTP server binds: `HOST`, else 127.0.0.1. Local by default,
|
|
14
14
|
* as the MCP transports spec recommends; a hosted deploy sets HOST=0.0.0.0.
|
package/dist/bin.js
CHANGED
|
@@ -20,9 +20,8 @@
|
|
|
20
20
|
import { realpathSync } from "node:fs";
|
|
21
21
|
import { resolve } from "node:path";
|
|
22
22
|
import { pathToFileURL } from "node:url";
|
|
23
|
-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
24
23
|
import { NAME, VERSION } from "./constants.js";
|
|
25
|
-
import { ROOT,
|
|
24
|
+
import { ROOT, serveStdioServer } from "./server.js";
|
|
26
25
|
/** what a bare `--help` / `help` prints. */
|
|
27
26
|
export const HELP = `${NAME} ${VERSION}
|
|
28
27
|
Serve a project's context (AGENTS.md), memory, and identity over MCP.
|
|
@@ -133,6 +132,16 @@ if (entryPath && import.meta.url === pathToFileURL(entryPath).href) {
|
|
|
133
132
|
// Piped / redirected (or --stdout) → raw HTML on stdout, unchanged.
|
|
134
133
|
// A bare run at a terminal → the HTML is noise; write a file and open it.
|
|
135
134
|
if (!process.stdout.isTTY || argv.includes("--stdout")) {
|
|
135
|
+
// A large project's card can be bigger than a pipe buffer. `head` closes
|
|
136
|
+
// after the first bytes; the rest of the write is EPIPE, which is the
|
|
137
|
+
// reader finishing. Any other error (disk full, bad descriptor) is a
|
|
138
|
+
// failed write: say so and exit 1.
|
|
139
|
+
process.stdout.on("error", (err) => {
|
|
140
|
+
if (err.code === "EPIPE")
|
|
141
|
+
process.exit(0);
|
|
142
|
+
process.stderr.write(`${NAME} · card --stdout: ${err.message}\n`);
|
|
143
|
+
process.exit(1);
|
|
144
|
+
});
|
|
136
145
|
process.stdout.write(html);
|
|
137
146
|
}
|
|
138
147
|
else {
|
|
@@ -168,7 +177,7 @@ if (entryPath && import.meta.url === pathToFileURL(entryPath).href) {
|
|
|
168
177
|
// With no MCP_CONTEXT_CARD_ROOT, find the user's project: the host's MCP
|
|
169
178
|
// roots, then the start directory. So a host needs no config to show yours.
|
|
170
179
|
const { openInBrowser } = await import("./open.js");
|
|
171
|
-
|
|
180
|
+
serveStdioServer(root, {
|
|
172
181
|
openFile: openInBrowser,
|
|
173
182
|
detectRoot: !process.env.MCP_CONTEXT_CARD_ROOT,
|
|
174
183
|
});
|