mcp-context-card 1.6.1 → 1.7.1
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 +3 -1
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +36 -0
- package/README.md +8 -5
- package/dist/bin.d.ts +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/faf/parse-fafa.js +1 -0
- package/dist/faf/types.d.ts +2 -0
- package/dist/render-card.d.ts +8 -43
- package/dist/render-card.js +5 -311
- package/dist/server.js +1 -1
- package/docs/MECHANISMS.md +2 -2
- package/docs/card-dark.html +3 -3
- package/docs/card-light.html +3 -3
- package/docs/card.html +3 -3
- 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 +3 -3
- package/package.json +2 -1
- 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.7.1",
|
|
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.7.1"
|
|
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
|
|
@@ -23,6 +23,8 @@ agent:
|
|
|
23
23
|
license: "MIT"
|
|
24
24
|
metadata:
|
|
25
25
|
cards:
|
|
26
|
+
# The card's colour: AAIF orange. Without one, a card is drawn in ink.
|
|
27
|
+
accent: "#FF702D"
|
|
26
28
|
packages:
|
|
27
29
|
- registryType: "npm"
|
|
28
30
|
identifier: "mcp-context-card"
|
package/AGENTS.md
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,42 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project. Adheres to [Semantic Versioning](https://semver.org).
|
|
4
4
|
|
|
5
|
+
## 1.7.1
|
|
6
|
+
|
|
7
|
+
The business card printer is now its own package.
|
|
8
|
+
|
|
9
|
+
- [agent-business-card](https://www.npmjs.com/package/agent-business-card)
|
|
10
|
+
renders the business card and prints it to screen. It is a new
|
|
11
|
+
dependency. Printing a business card no longer needs an MCP server: the
|
|
12
|
+
renderer has no dependencies and runs in the browser, so any page or tool
|
|
13
|
+
can print the same business card from its own facts (an A2A Agent Card,
|
|
14
|
+
an MCP Server Card, a `.fafa`). mcp-context-card is one reader that
|
|
15
|
+
supplies them.
|
|
16
|
+
- Same code, moved unchanged. The business cards are byte-identical to
|
|
17
|
+
1.7.0.
|
|
18
|
+
- `renderBusinessCard`, `cardInitials`, `safeAccent` and the `BusinessCard`
|
|
19
|
+
types are still exported from `render-card`, so nothing changes for
|
|
20
|
+
callers.
|
|
21
|
+
|
|
22
|
+
## 1.7.0
|
|
23
|
+
|
|
24
|
+
A card's colour is the owner's.
|
|
25
|
+
|
|
26
|
+
- **No colour declared = ink.** A card is drawn in its own ink, black on a
|
|
27
|
+
light card and white on a dark one, unless a colour is declared. Nothing
|
|
28
|
+
is guessed. The monogram's letter takes the card colour, so it stays
|
|
29
|
+
readable. Before, every card defaulted to the AAIF orange.
|
|
30
|
+
- **The owner declares it in the `.fafa`:** `metadata.cards.accent: "#0066cc"`.
|
|
31
|
+
A colour passed in (`--accent`, `?accent`, the tools' `accent`) still
|
|
32
|
+
wins.
|
|
33
|
+
- A bad value, passed or declared, is dropped and the card falls back to
|
|
34
|
+
ink. `safeAccent` now returns `undefined` for anything that isn't a hex
|
|
35
|
+
(it used to return the AAIF orange).
|
|
36
|
+
- This project's own `.fafa` declares the AAIF orange, so its card looks
|
|
37
|
+
the same.
|
|
38
|
+
- Docs: Node 22 or newer (README and AGENTS.md said 20; `engines` has
|
|
39
|
+
required `>=22`).
|
|
40
|
+
|
|
5
41
|
## 1.6.1
|
|
6
42
|
|
|
7
43
|
The logo is the first letter.
|
package/README.md
CHANGED
|
@@ -119,11 +119,14 @@ remembers. `detail: "full"` lists every fact whole. The server's
|
|
|
119
119
|
instructions tell the model to show that rather than paste the HTML into
|
|
120
120
|
the chat.
|
|
121
121
|
|
|
122
|
-
Light, dark, or auto
|
|
122
|
+
Light, dark, or auto. The colour is the owner's: set it in the project's
|
|
123
|
+
`.fafa` (`metadata.cards.accent: "#0066cc"`), or pass any hex with `--accent`
|
|
124
|
+
or `?accent`. With none, the card is drawn in ink, black or white; no colour
|
|
125
|
+
is guessed.
|
|
123
126
|
This repo's own card, live: [auto](https://wolfe-jam.github.io/mcp-context-card/) ·
|
|
124
127
|
[light](https://wolfe-jam.github.io/mcp-context-card/card-light.html) ·
|
|
125
128
|
[dark](https://wolfe-jam.github.io/mcp-context-card/card-dark.html)
|
|
126
|
-
(
|
|
129
|
+
(in the AAIF orange its `.fafa` declares).
|
|
127
130
|
|
|
128
131
|
## Add it to your setup
|
|
129
132
|
|
|
@@ -177,7 +180,7 @@ directory it was started in if that has an `AGENTS.md`. `list_context_sources`
|
|
|
177
180
|
reports which project it picked and how. To pin one project instead, set
|
|
178
181
|
`"env": { "MCP_CONTEXT_CARD_ROOT": "/abs/path/to/your/project" }`; that always
|
|
179
182
|
wins. Identity is optional. Over HTTP instead:
|
|
180
|
-
`PORT=8080 npx mcp-context-card`. Requires Node ≥
|
|
183
|
+
`PORT=8080 npx mcp-context-card`. Requires Node ≥22.
|
|
181
184
|
|
|
182
185
|
HTTP mode is local by default, as the MCP transports spec asks: it binds
|
|
183
186
|
`127.0.0.1`, refuses foreign browser origins with 403, and refuses DNS names
|
|
@@ -271,7 +274,7 @@ over both transports:
|
|
|
271
274
|
4. **Discovery** — `list_context_sources()`, then the same server over stateless
|
|
272
275
|
HTTP with its `.well-known` routes and `GET /card`.
|
|
273
276
|
|
|
274
|
-
|
|
277
|
+
210 tests on Linux, macOS, and Windows, coverage‑gated in CI.
|
|
275
278
|
`npm run wjttc` runs the WJTTC certification suite (seven tiers, from protocol
|
|
276
279
|
and Server Card conformance to stdio/HTTP parity and the shipped package). Two spawn a real
|
|
277
280
|
child process and check a remembered fact survives the restart — one against
|
|
@@ -289,7 +292,7 @@ transport security against the specs, one MUST or SHOULD at a time.
|
|
|
289
292
|
| `src/agents-md.ts` | reads and section‑splits `AGENTS.md` |
|
|
290
293
|
| `src/author.ts` | `author_agents_md` — BETTER via [`agents-md-facts`](https://github.com/Wolfe-Jam/agents-md-facts), BEST when `project.faf` exists |
|
|
291
294
|
| `src/md.ts` | a minimal dependency‑free Markdown → HTML renderer |
|
|
292
|
-
| `src/render-card.ts` | the card — identity + `AGENTS.md` + memory + discovery
|
|
295
|
+
| `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 |
|
|
293
296
|
| `src/memory.ts` | file‑backed `remember` / `recall` / `forget` |
|
|
294
297
|
| `src/identity.ts` | `whoami` (`.fafa` → `package.json` fallback) + the `_meta` block |
|
|
295
298
|
| `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.7.1\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/constants.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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 = "1.
|
|
4
|
+
export declare const VERSION = "1.7.1";
|
|
5
5
|
export declare const SERVER_CARD_URI = "mcp-context-card://server-card";
|
|
6
6
|
/** The server's registry identity: reverse-DNS, the same as server.json `name`.
|
|
7
7
|
* It is also `serverInfo.name`, so a Server Card never contradicts the live
|
package/dist/constants.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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 = "1.
|
|
4
|
+
export const VERSION = "1.7.1";
|
|
5
5
|
export const SERVER_CARD_URI = "mcp-context-card://server-card";
|
|
6
6
|
/** The server's registry identity: reverse-DNS, the same as server.json `name`.
|
|
7
7
|
* It is also `serverInfo.name`, so a Server Card never contradicts the live
|
package/dist/faf/parse-fafa.js
CHANGED
|
@@ -50,5 +50,6 @@ function extras(doc) {
|
|
|
50
50
|
...(endpoints.length ? { endpoints } : {}),
|
|
51
51
|
...(skills.length ? { skills } : {}),
|
|
52
52
|
...(packages.length ? { packages } : {}),
|
|
53
|
+
...(typeof cards.accent === "string" && cards.accent.trim() ? { accent: cards.accent.trim() } : {}),
|
|
53
54
|
};
|
|
54
55
|
}
|
package/dist/faf/types.d.ts
CHANGED
package/dist/render-card.d.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import type { AgentIdentity } from "./faf/types.js";
|
|
2
|
-
|
|
2
|
+
import { type BusinessCard, type Theme } from "agent-business-card";
|
|
3
|
+
export { cardInitials, renderBusinessCard, safeAccent } from "agent-business-card";
|
|
4
|
+
export type { BusinessCard, RenderOptions, Theme } from "agent-business-card";
|
|
3
5
|
export interface CardOptions {
|
|
4
6
|
theme?: Theme;
|
|
5
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* CSS hex colour for the accent. Validated; invalid is ignored. Wins over the
|
|
9
|
+
* owner's colour; with neither, the card is drawn in ink (black or white).
|
|
10
|
+
*/
|
|
6
11
|
accent?: string;
|
|
7
12
|
/**
|
|
8
13
|
* Render every AGENTS.md section open. Default: sections collapse to their
|
|
@@ -18,58 +23,18 @@ export interface CardOptions {
|
|
|
18
23
|
/** Business-card view. Default `landscape`; the reader can switch it too. */
|
|
19
24
|
layout?: "landscape" | "portrait";
|
|
20
25
|
}
|
|
21
|
-
/** AAIF brand orange (aaif.io)
|
|
26
|
+
/** AAIF brand orange (aaif.io): this project's own card colour, declared in its `.fafa`. */
|
|
22
27
|
export declare const AAIF_ACCENT = "#FF702D";
|
|
23
|
-
export declare function safeAccent(a?: string): string;
|
|
24
28
|
/** What the front calls this thing, from where it runs: "MCP server", "A2A agent", or both. */
|
|
25
29
|
export declare function cardKind(id: AgentIdentity | null): string[];
|
|
26
30
|
/** The front's title line: what it is, then its version. Empty when nothing is known. */
|
|
27
31
|
export declare function cardTitle(id: AgentIdentity | null): string;
|
|
28
|
-
/**
|
|
29
|
-
* The front's logo: the first letter of the name's first meaningful word
|
|
30
|
-
* (generic words like "mcp", "server", "sdk" skipped), plus a second letter
|
|
31
|
-
* only when it's obvious: a known name (github → GH, typescript → TS) or a
|
|
32
|
-
* word written with two capitals (GitHub, TypeScript). Never more than two.
|
|
33
|
-
*/
|
|
34
|
-
export declare function cardInitials(name: string): string;
|
|
35
32
|
/** The front's one-liner: the first sentence of the description. */
|
|
36
33
|
export declare function cardOneLiner(id: AgentIdentity | null, max?: number): string;
|
|
37
|
-
/**
|
|
38
|
-
* A business card, independent of where its facts came from: everything the
|
|
39
|
-
* renderer draws. `readCard` builds one from a project's files; another reader
|
|
40
|
-
* (an A2A Agent Card, an MCP Server Card, a person's card) can build one too,
|
|
41
|
-
* and `renderBusinessCard` draws any of them the same way.
|
|
42
|
-
*/
|
|
43
|
-
export interface BusinessCard {
|
|
44
|
-
name: string;
|
|
45
|
-
/** What it is (and its version): "MCP server · v1.5.0", or a person's role. */
|
|
46
|
-
title?: string;
|
|
47
|
-
oneLiner?: string;
|
|
48
|
-
/** Shown bottom-left on the front, e.g. the publisher domain. */
|
|
49
|
-
domain?: string;
|
|
50
|
-
/** Footer chips; `accent` highlights one (e.g. the status). Plain text. */
|
|
51
|
-
chips: {
|
|
52
|
-
text: string;
|
|
53
|
-
accent?: boolean;
|
|
54
|
-
}[];
|
|
55
|
-
/** The back's tabs, in order. `key` is [a-z0-9-]; `html` is already-safe markup. */
|
|
56
|
-
tabs: {
|
|
57
|
-
key: string;
|
|
58
|
-
label: string;
|
|
59
|
-
heading: string;
|
|
60
|
-
html: string;
|
|
61
|
-
}[];
|
|
62
|
-
/** The (i) panel, as already-safe markup. */
|
|
63
|
-
about: string;
|
|
64
|
-
}
|
|
65
|
-
/** How to draw a card: the owner's colour and accent, the view, and the flat (print) layout. */
|
|
66
|
-
export type RenderOptions = Pick<CardOptions, "theme" | "accent" | "layout" | "expanded">;
|
|
67
34
|
/** The project's card: read its files, then draw. */
|
|
68
35
|
export declare function renderCard(root: string, opts?: CardOptions): string;
|
|
69
36
|
/** Read a project's AGENTS.md, memory and identity into a business card. */
|
|
70
37
|
export declare function readCard(root: string, opts?: Pick<CardOptions, "expanded" | "memory">): BusinessCard;
|
|
71
|
-
/** Draw any business card as one self-contained HTML page. */
|
|
72
|
-
export declare function renderBusinessCard(card: BusinessCard, opts?: RenderOptions): string;
|
|
73
38
|
/** tl;dr: the first few facts, each cut to about a line. `full`: every fact, whole. */
|
|
74
39
|
export type Detail = "tldr" | "full";
|
|
75
40
|
/**
|
package/dist/render-card.js
CHANGED
|
@@ -16,192 +16,11 @@ import { parseFafm } from "./memory.js";
|
|
|
16
16
|
import { resolveIdentity, serverCardMeta, META_NS } from "./identity.js";
|
|
17
17
|
import { PUBLISH_MEMORY_ENV, SERVER_CARD_URI } from "./constants.js";
|
|
18
18
|
import { escapeHtml, renderInline, renderMarkdown, slug } from "./md.js";
|
|
19
|
-
|
|
19
|
+
import { renderBusinessCard } from "agent-business-card";
|
|
20
|
+
// The renderer lives in agent-business-card; these readers build the card from a project's files.
|
|
21
|
+
export { cardInitials, renderBusinessCard, safeAccent } from "agent-business-card";
|
|
22
|
+
/** AAIF brand orange (aaif.io): this project's own card colour, declared in its `.fafa`. */
|
|
20
23
|
export const AAIF_ACCENT = "#FF702D";
|
|
21
|
-
const ACCENT_OK = /^#[0-9a-fA-F]{3}(?:[0-9a-fA-F]{3}(?:[0-9a-fA-F]{2})?)?$/;
|
|
22
|
-
export function safeAccent(a) {
|
|
23
|
-
return a && ACCENT_OK.test(a) ? a : AAIF_ACCENT;
|
|
24
|
-
}
|
|
25
|
-
const CSS = (accent) => `
|
|
26
|
-
/* The page and the card are themed independently. The page follows the
|
|
27
|
-
viewer's OS. The card is the owner's choice: body[data-theme] (light | dark;
|
|
28
|
-
none = follow the OS), and the reader can switch it with the ◐ toggle (#ink). */
|
|
29
|
-
:root{
|
|
30
|
-
--accent:${accent};
|
|
31
|
-
--page-bg:#f4f4f5;--page-muted:#6b6b70;--page-line:rgba(0,0,0,.09);--page-chip:rgba(0,0,0,.05);
|
|
32
|
-
}
|
|
33
|
-
@media (prefers-color-scheme:dark){
|
|
34
|
-
:root{--page-bg:#000;--page-muted:#9a9aa0;--page-line:rgba(255,255,255,.13);--page-chip:rgba(255,255,255,.07)}
|
|
35
|
-
}
|
|
36
|
-
.bcard{--card:#fff;--fg:#0a0a0a;--muted:#6b6b70;--line:rgba(0,0,0,.09);--chip:rgba(0,0,0,.05);--card-shadow:0 1px 3px rgba(0,0,0,.06),0 12px 32px rgba(0,0,0,.10)}
|
|
37
|
-
body[data-theme="dark"] .bcard,
|
|
38
|
-
body[data-theme="light"] #ink:checked~.stage .bcard{--card:#0d0d0d;--fg:#fafafa;--muted:#9a9aa0;--line:rgba(255,255,255,.13);--chip:rgba(255,255,255,.07);--card-shadow:0 0 0 1px rgba(255,255,255,.16),0 8px 40px color-mix(in srgb,var(--accent) 20%,transparent)}
|
|
39
|
-
body[data-theme="dark"] #ink:checked~.stage .bcard{--card:#fff;--fg:#0a0a0a;--muted:#6b6b70;--line:rgba(0,0,0,.09);--chip:rgba(0,0,0,.05);--card-shadow:0 1px 3px rgba(0,0,0,.06),0 12px 32px rgba(0,0,0,.10)}
|
|
40
|
-
@media (prefers-color-scheme:dark){
|
|
41
|
-
body:not([data-theme]) .bcard{--card:#0d0d0d;--fg:#fafafa;--muted:#9a9aa0;--line:rgba(255,255,255,.13);--chip:rgba(255,255,255,.07);--card-shadow:0 0 0 1px rgba(255,255,255,.16),0 8px 40px color-mix(in srgb,var(--accent) 20%,transparent)}
|
|
42
|
-
body:not([data-theme]) #ink:checked~.stage .bcard{--card:#fff;--fg:#0a0a0a;--muted:#6b6b70;--line:rgba(0,0,0,.09);--chip:rgba(0,0,0,.05);--card-shadow:0 1px 3px rgba(0,0,0,.06),0 12px 32px rgba(0,0,0,.10)}
|
|
43
|
-
}
|
|
44
|
-
@media (prefers-color-scheme:light){
|
|
45
|
-
body:not([data-theme]) #ink:checked~.stage .bcard{--card:#0d0d0d;--fg:#fafafa;--muted:#9a9aa0;--line:rgba(255,255,255,.13);--chip:rgba(255,255,255,.07);--card-shadow:0 0 0 1px rgba(255,255,255,.16),0 8px 40px color-mix(in srgb,var(--accent) 20%,transparent)}
|
|
46
|
-
}
|
|
47
|
-
.bcard{color:var(--fg)}
|
|
48
|
-
*{box-sizing:border-box}
|
|
49
|
-
body{margin:0;background:var(--page-bg);color:var(--page-muted);
|
|
50
|
-
font:15px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
|
|
51
|
-
padding:40px 16px}
|
|
52
|
-
/* ── the business card: two faces, flip, two views ─────────────────── */
|
|
53
|
-
.sr{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
|
|
54
|
-
.stage{max-width:760px;margin:0 auto}
|
|
55
|
-
.views{display:flex;justify-content:flex-end;margin:0 0 10px}
|
|
56
|
-
.view,.hint label{cursor:pointer}
|
|
57
|
-
.view{font-size:.78rem;font-weight:600;padding:3px 11px;border-radius:20px;border:1px solid var(--page-line);
|
|
58
|
-
background:var(--page-chip);color:var(--page-muted);letter-spacing:.2em}
|
|
59
|
-
.views{gap:8px}
|
|
60
|
-
.view:hover,.hint label:hover{color:var(--accent);border-color:var(--accent)}
|
|
61
|
-
.bcard{margin:0 auto;width:100%;aspect-ratio:7/4;perspective:1600px}
|
|
62
|
-
#portrait:checked~.stage{max-width:480px}
|
|
63
|
-
#portrait:checked~.stage .bcard{aspect-ratio:4/7}
|
|
64
|
-
.faces{position:relative;width:100%;height:100%;transform-style:preserve-3d;transition:transform .6s ease}
|
|
65
|
-
#flip:checked~.stage .faces{transform:rotateY(180deg)}
|
|
66
|
-
.face{position:absolute;inset:0;background:var(--card);border:1px solid var(--line);border-radius:16px;
|
|
67
|
-
box-shadow:var(--card-shadow);backface-visibility:hidden;-webkit-backface-visibility:hidden;overflow:hidden}
|
|
68
|
-
.back{transform:rotateY(180deg) translateZ(1px);display:flex;flex-direction:column}
|
|
69
|
-
/* The face turned away takes no pointer or wheel events, so the visible face
|
|
70
|
-
scrolls (a hidden backface can still win hit-testing, notably in Chrome/Safari on macOS). */
|
|
71
|
-
#flip:checked~.stage .front,#flip:not(:checked)~.stage .back{pointer-events:none;visibility:hidden;transition:visibility 0s .3s}
|
|
72
|
-
#flip:checked~.stage .back,#flip:not(:checked)~.stage .front{visibility:visible;transition:visibility 0s .3s}
|
|
73
|
-
.panes{overscroll-behavior:contain;-webkit-overflow-scrolling:touch}
|
|
74
|
-
.front{display:flex;flex-direction:column;justify-content:center;padding:34px 44px;
|
|
75
|
-
border-top:5px solid var(--accent);
|
|
76
|
-
background:linear-gradient(135deg,color-mix(in srgb,var(--accent) 10%,var(--card)) 0%,var(--card) 55%)}
|
|
77
|
-
.front .id{max-width:34em}
|
|
78
|
-
h1{margin:0;font-size:2.1rem;line-height:1.15;letter-spacing:-.025em}
|
|
79
|
-
.title{margin:8px 0 0;font-size:.82rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--accent)}
|
|
80
|
-
.oneliner{margin:16px 0 0;font-size:1.05rem;color:var(--muted);line-height:1.5}
|
|
81
|
-
.foot-front{position:absolute;left:44px;right:130px;bottom:22px;display:flex;flex-wrap:wrap;align-items:center;gap:6px 12px}
|
|
82
|
-
.domain{font:.8rem ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--muted)}
|
|
83
|
-
.corner{position:absolute;width:30px;height:30px;border-radius:50%;display:grid;place-items:center;
|
|
84
|
-
cursor:pointer;font-weight:700;font-size:.9rem;color:var(--muted);background:var(--chip);border:1px solid var(--line);z-index:4}
|
|
85
|
-
.corner:hover{color:var(--accent);border-color:var(--accent)}
|
|
86
|
-
.corner.tr{top:16px;right:16px;font-family:Georgia,serif;font-style:italic}
|
|
87
|
-
.logo{position:absolute;top:34px;left:44px;width:84px;height:84px;border-radius:50%;display:grid;place-items:center;
|
|
88
|
-
color:#fff;font-weight:800;font-size:2rem;letter-spacing:-.02em;line-height:1;
|
|
89
|
-
background:radial-gradient(circle at 30% 25%,color-mix(in srgb,var(--accent) 80%,#fff),var(--accent) 45%,color-mix(in srgb,var(--accent) 50%,#000));
|
|
90
|
-
box-shadow:0 0 0 3px var(--card),0 0 0 4px color-mix(in srgb,var(--accent) 45%,transparent),0 6px 20px color-mix(in srgb,var(--accent) 30%,transparent)}
|
|
91
|
-
.front .id{margin-top:70px}
|
|
92
|
-
.corner.br{bottom:16px;right:16px}
|
|
93
|
-
.flipbtn{position:absolute;right:18px;bottom:16px;z-index:4;cursor:pointer;width:42px;height:42px;border-radius:50%;
|
|
94
|
-
display:grid;place-items:center;color:var(--fg);background:transparent;box-shadow:inset 0 0 0 2px var(--fg);
|
|
95
|
-
transition:transform .2s ease}
|
|
96
|
-
.flipbtn span{font-size:1.3rem;line-height:1;font-weight:700}
|
|
97
|
-
|
|
98
|
-
/* the back's button: same spot and outline as the front's; ↺ instead of ↻. Over
|
|
99
|
-
scrolling text it takes the card's colour, so the arrow stays readable. */
|
|
100
|
-
.flipbtn.back-btn{background:var(--card)}
|
|
101
|
-
/* fast tooltip: shows at once on hover or keyboard focus (a title tooltip waits ~1 s) */
|
|
102
|
-
.flipbtn[data-tip]::after{content:attr(data-tip);position:absolute;right:0;bottom:calc(100% + 8px);white-space:nowrap;
|
|
103
|
-
font:600 .74rem/1 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;letter-spacing:0;padding:6px 9px;border-radius:7px;
|
|
104
|
-
color:var(--card);background:var(--fg);opacity:0;transform:translateY(3px);pointer-events:none;transition:opacity .08s,transform .08s}
|
|
105
|
-
.flipbtn[data-tip]:hover::after,#flip:focus-visible~.stage .flipbtn[data-tip]::after{opacity:1;transform:none}
|
|
106
|
-
.flipbtn:hover{transform:none}.flipbtn:hover span{transform:rotate(-25deg)}.flipbtn span{transition:transform .2s ease}
|
|
107
|
-
.whatis{position:absolute;top:16px;right:16px;z-index:5}
|
|
108
|
-
.whatis>summary{position:static;list-style:none}
|
|
109
|
-
.whatis>summary::-webkit-details-marker{display:none}
|
|
110
|
-
.whatis[open]>summary{color:var(--accent);border-color:var(--accent)}
|
|
111
|
-
.whatis-panel{position:absolute;right:0;top:38px;width:min(320px,70vw);padding:14px 16px;border-radius:12px;
|
|
112
|
-
background:var(--card);border:1px solid var(--line);box-shadow:var(--card-shadow);font-size:.84rem;line-height:1.5}
|
|
113
|
-
.whatis-panel p{margin:0 0 8px}.whatis-head{font-weight:800;color:var(--accent);letter-spacing:-.01em;font-size:.95rem}
|
|
114
|
-
.whatis-foot{color:var(--muted);margin:0!important}.whatis-panel code{font:.86em ui-monospace,SFMono-Regular,Menlo,monospace}
|
|
115
|
-
.tabbar{display:flex;flex-wrap:wrap;gap:4px;padding:14px 60px 0 18px;border-bottom:1px solid var(--line);border-top:5px solid var(--accent)}
|
|
116
|
-
.tabbar label{cursor:pointer;font-size:.8rem;font-weight:600;color:var(--muted);padding:6px 11px;border-radius:8px 8px 0 0}
|
|
117
|
-
.tabbar label:hover{color:var(--fg)}
|
|
118
|
-
.panes{flex:1;overflow:auto;padding:20px 26px 72px}
|
|
119
|
-
.pane{display:none}
|
|
120
|
-
.lead{margin:0 0 14px;font-size:1rem;line-height:1.6}
|
|
121
|
-
.kv{border-collapse:collapse;font-size:.86rem;width:100%}
|
|
122
|
-
.kv th{text-align:left;font-weight:600;color:var(--muted);padding:6px 14px 6px 0;white-space:nowrap;vertical-align:top}
|
|
123
|
-
.kv td{padding:6px 0;border-bottom:1px solid var(--line)}
|
|
124
|
-
.kv code,.lead code{font:.86em ui-monospace,SFMono-Regular,Menlo,monospace}
|
|
125
|
-
.hint{text-align:center;color:var(--page-muted);font-size:.78rem;margin:14px 0 0}
|
|
126
|
-
.hint label{color:var(--accent)}
|
|
127
|
-
#flip:focus-visible~.stage .flipbtn,#portrait:focus-visible~.stage .view[for=portrait],#ink:focus-visible~.stage .view[for=ink]{outline:2px solid var(--accent);outline-offset:2px}
|
|
128
|
-
@media (max-width:640px){
|
|
129
|
-
.bcard,#portrait:checked~.stage .bcard{aspect-ratio:auto;height:min(78vh,720px)}
|
|
130
|
-
.front{padding:28px 26px}.foot-front{left:26px}
|
|
131
|
-
.logo{top:24px;left:26px;width:64px;height:64px;font-size:1.5rem}.front .id{margin-top:56px}
|
|
132
|
-
h1{font-size:1.7rem}
|
|
133
|
-
}
|
|
134
|
-
/* flat: expanded render and print — both faces, every tab, no flip */
|
|
135
|
-
.flat .faces,.flat .face{position:static;transform:none!important;height:auto}
|
|
136
|
-
.flat .bcard{aspect-ratio:auto;perspective:none}
|
|
137
|
-
.flat .face{margin:0 0 18px}.flat .front{min-height:260px;position:relative}
|
|
138
|
-
.flat .pane{display:block;margin:0 0 22px}.flat .bcard{color:var(--fg)}.flat .tabbar,.flat .views,.flat .hint,.flat .corner,.flat .flipbtn,.flat .whatis{display:none}
|
|
139
|
-
.flat .panes{overflow:visible}
|
|
140
|
-
@media print{
|
|
141
|
-
.faces,.face{position:static!important;transform:none!important;height:auto!important}
|
|
142
|
-
.bcard{aspect-ratio:auto!important}.face{margin:0 0 18px;box-shadow:none}
|
|
143
|
-
.pane{display:block!important;margin:0 0 22px}.tabbar,.views,.hint,.corner,.flipbtn,.whatis{display:none!important}
|
|
144
|
-
.panes{overflow:visible}
|
|
145
|
-
}
|
|
146
|
-
.pills{display:flex;flex-wrap:wrap;gap:6px}
|
|
147
|
-
.pill{font-size:.74rem;font-weight:600;padding:3px 9px;border-radius:20px;background:var(--chip);color:var(--muted)}
|
|
148
|
-
.pill.accent{background:color-mix(in srgb,var(--accent) 16%,transparent);color:var(--accent)}
|
|
149
|
-
.label{font-size:.7rem;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
|
|
150
|
-
color:var(--accent);margin:0 0 14px}
|
|
151
|
-
.toc{display:flex;flex-wrap:wrap;gap:6px 14px;margin:0;padding:0;list-style:none}
|
|
152
|
-
.toc a{font-size:.82rem;color:var(--muted);text-decoration:none}
|
|
153
|
-
.toc a:hover{color:var(--accent)}
|
|
154
|
-
/* ── collapsible context ─────────────────────────────────────────── */
|
|
155
|
-
.ctx-nav{position:sticky;top:-20px;z-index:3;background:var(--card);
|
|
156
|
-
margin:0 -26px 16px;padding:11px 26px;border-bottom:1px solid var(--line);
|
|
157
|
-
display:flex;flex-wrap:wrap;align-items:flex-start;gap:8px 16px}
|
|
158
|
-
.xall{margin-left:auto;flex:none;font:inherit;font-size:.76rem;font-weight:600;
|
|
159
|
-
white-space:nowrap;padding:3px 11px;border-radius:20px;border:1px solid var(--line);
|
|
160
|
-
background:var(--chip);color:var(--muted);cursor:pointer}
|
|
161
|
-
.xall:hover{color:var(--accent);border-color:var(--accent)}
|
|
162
|
-
.ctx-preamble{padding-bottom:4px}
|
|
163
|
-
details.ctx-section{border-top:1px solid var(--line)}
|
|
164
|
-
details.ctx-section>summary{cursor:pointer;list-style:none;padding:11px 0;
|
|
165
|
-
font-weight:600;font-size:1rem;letter-spacing:-.01em;display:flex;gap:9px}
|
|
166
|
-
details.ctx-section>summary::-webkit-details-marker{display:none}
|
|
167
|
-
details.ctx-section>summary::before{content:"›";color:var(--accent);font-weight:700;
|
|
168
|
-
transition:transform .15s ease}
|
|
169
|
-
details.ctx-section[open]>summary::before{transform:rotate(90deg)}
|
|
170
|
-
details.ctx-section>.md{padding:0 0 16px}
|
|
171
|
-
@media print{
|
|
172
|
-
.ctx-nav{display:none}
|
|
173
|
-
details.ctx-section:not([open])>.md{display:block!important}
|
|
174
|
-
details.ctx-section>summary::before{content:""}
|
|
175
|
-
}
|
|
176
|
-
.md h1,.md h2,.md h3,.md h4{margin:22px 0 8px;font-size:1rem;letter-spacing:-.01em}
|
|
177
|
-
.md h1{font-size:1.15rem}
|
|
178
|
-
.md p{margin:8px 0}
|
|
179
|
-
.md ul,.md ol{margin:8px 0;padding-left:22px}
|
|
180
|
-
.md li{margin:3px 0}
|
|
181
|
-
.md code{background:var(--chip);padding:1px 5px;border-radius:5px;
|
|
182
|
-
font:.86em ui-monospace,SFMono-Regular,Menlo,monospace}
|
|
183
|
-
.md pre{background:var(--chip);padding:14px 16px;border-radius:9px;overflow:auto}
|
|
184
|
-
.md pre code{background:none;padding:0}
|
|
185
|
-
.md table{border-collapse:collapse;width:100%;margin:12px 0;font-size:.88rem;display:block;overflow:auto}
|
|
186
|
-
.md th,.md td{border:1px solid var(--line);padding:6px 10px;text-align:left}
|
|
187
|
-
.md blockquote{margin:10px 0;padding-left:14px;border-left:3px solid var(--line);color:var(--muted)}
|
|
188
|
-
.md a{color:var(--accent)}
|
|
189
|
-
.fact{padding:12px 0;border-bottom:1px solid var(--line)}
|
|
190
|
-
.fact:last-child{border-bottom:0}
|
|
191
|
-
.fact p{margin:0 0 7px}
|
|
192
|
-
.meta{display:flex;flex-wrap:wrap;gap:6px;align-items:center}
|
|
193
|
-
.tag{font-size:.72rem;padding:2px 8px;border-radius:5px;background:var(--chip);color:var(--muted)}
|
|
194
|
-
.dot{width:7px;height:7px;border-radius:50%;background:var(--accent);display:inline-block}
|
|
195
|
-
.dot.pending{background:var(--muted)}
|
|
196
|
-
.disc{width:100%;border-collapse:collapse;font-size:.84rem}
|
|
197
|
-
.disc th,.disc td{text-align:left;padding:6px 10px;border-bottom:1px solid var(--line)}
|
|
198
|
-
.disc th{color:var(--muted);font-weight:600}
|
|
199
|
-
.disc code{font:.86em ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--muted)}
|
|
200
|
-
.fetch{margin:14px 0 0;font-size:.82rem;color:var(--muted)}
|
|
201
|
-
.fetch code{background:var(--chip);padding:1px 5px;border-radius:5px}
|
|
202
|
-
.none{color:var(--muted);font-style:italic}
|
|
203
|
-
`;
|
|
204
|
-
const htmlAttr = (theme) => theme === "auto" ? "" : ` data-theme="${theme}"`;
|
|
205
24
|
/** What the front calls this thing, from where it runs: "MCP server", "A2A agent", or both. */
|
|
206
25
|
export function cardKind(id) {
|
|
207
26
|
const kinds = [];
|
|
@@ -216,28 +35,6 @@ export function cardKind(id) {
|
|
|
216
35
|
export function cardTitle(id) {
|
|
217
36
|
return [cardKind(id).join(" · "), id?.agentVersion ? `v${id.agentVersion}` : ""].filter(Boolean).join(" · ");
|
|
218
37
|
}
|
|
219
|
-
/** The front's logo: the first letters of the name's first two words ("mcp-context-card" → "MC"). */
|
|
220
|
-
/** Words that say what kind of thing it is, not whose: never the logo ("mcp-context-card" → C, not M). */
|
|
221
|
-
const GENERIC_WORDS = new Set(["mcp", "server", "servers", "sdk", "agent", "agents", "api", "cli", "app", "tool", "tools", "plugin", "core", "the"]);
|
|
222
|
-
/** Names whose two-letter mark is obvious. */
|
|
223
|
-
const OBVIOUS_MARKS = { github: "GH", gitlab: "GL", typescript: "TS", javascript: "JS" };
|
|
224
|
-
/**
|
|
225
|
-
* The front's logo: the first letter of the name's first meaningful word
|
|
226
|
-
* (generic words like "mcp", "server", "sdk" skipped), plus a second letter
|
|
227
|
-
* only when it's obvious: a known name (github → GH, typescript → TS) or a
|
|
228
|
-
* word written with two capitals (GitHub, TypeScript). Never more than two.
|
|
229
|
-
*/
|
|
230
|
-
export function cardInitials(name) {
|
|
231
|
-
const words = name.split(/[^\p{L}\p{N}]+/u).filter(Boolean);
|
|
232
|
-
const first = words.find((w) => !GENERIC_WORDS.has(w.toLowerCase())) ?? words[0] ?? "";
|
|
233
|
-
const known = OBVIOUS_MARKS[first.toLowerCase()];
|
|
234
|
-
if (known)
|
|
235
|
-
return known;
|
|
236
|
-
const capitals = first.match(/\p{Lu}/gu) ?? [];
|
|
237
|
-
if (capitals.length === 2 && /^\p{Lu}/u.test(first) && /\p{Ll}/u.test(first))
|
|
238
|
-
return capitals.join("");
|
|
239
|
-
return (Array.from(first)[0] ?? "").toUpperCase();
|
|
240
|
-
}
|
|
241
38
|
/** The front's one-liner: the first sentence of the description. */
|
|
242
39
|
export function cardOneLiner(id, max = 140) {
|
|
243
40
|
const d = id?.description;
|
|
@@ -368,112 +165,9 @@ export function readCard(root, opts = {}) {
|
|
|
368
165
|
chips,
|
|
369
166
|
tabs: tabs.map(([key, label, heading, html]) => ({ key, label, heading, html })),
|
|
370
167
|
about: AGENT_ABOUT,
|
|
168
|
+
...(id?.accent ? { accent: id.accent } : {}),
|
|
371
169
|
};
|
|
372
170
|
}
|
|
373
|
-
/** Draw any business card as one self-contained HTML page. */
|
|
374
|
-
export function renderBusinessCard(card, opts = {}) {
|
|
375
|
-
const theme = opts.theme ?? "auto";
|
|
376
|
-
const accent = safeAccent(opts.accent);
|
|
377
|
-
const portrait = opts.layout === "portrait";
|
|
378
|
-
const flat = !!opts.expanded;
|
|
379
|
-
const { name, title, oneLiner, domain } = card;
|
|
380
|
-
const tabs = card.tabs.map((t) => ({ ...t, key: t.key.replace(/[^a-z0-9-]/gi, "").toLowerCase() || "tab" }));
|
|
381
|
-
const pills = card.chips
|
|
382
|
-
.map((c) => `<span class="pill${c.accent ? " accent" : ""}">${escapeHtml(c.text)}</span>`)
|
|
383
|
-
.join("");
|
|
384
|
-
const radios = tabs
|
|
385
|
-
.map((t, i) => `<input type="radio" name="tab" id="t-${t.key}" class="sr"${i === 0 ? " checked" : ""}>`)
|
|
386
|
-
.join("");
|
|
387
|
-
const tabbar = tabs.map((t) => `<label for="t-${t.key}">${escapeHtml(t.label)}</label>`).join("");
|
|
388
|
-
const panes = tabs
|
|
389
|
-
.map((t) => `<div class="pane p-${t.key}"><p class="label">${escapeHtml(t.heading)}</p>${t.html}</div>`)
|
|
390
|
-
.join("");
|
|
391
|
-
// One CSS rule pair per tab: its pane shows, its label lights, when its radio is checked.
|
|
392
|
-
const tabCss = tabs
|
|
393
|
-
.map((t) => `#t-${t.key}:checked~.panes .p-${t.key}{display:block}#t-${t.key}:checked~.tabbar label[for=t-${t.key}]{color:var(--accent);background:var(--chip)}`)
|
|
394
|
-
.join("");
|
|
395
|
-
// The (i) panel: the same control, in the same spot, on both faces.
|
|
396
|
-
const WHATIS = `<details class="whatis">
|
|
397
|
-
<summary class="corner tr" title="About this card" aria-label="About this card">i</summary>
|
|
398
|
-
<div class="whatis-panel">
|
|
399
|
-
${card.about}
|
|
400
|
-
</div>
|
|
401
|
-
</details>`;
|
|
402
|
-
return `<!doctype html>
|
|
403
|
-
<html lang="en">
|
|
404
|
-
<head>
|
|
405
|
-
<meta charset="utf-8">
|
|
406
|
-
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
407
|
-
<title>${escapeHtml(name)} — business card</title>
|
|
408
|
-
<style>${CSS(accent)}${tabCss}</style>
|
|
409
|
-
</head>
|
|
410
|
-
<body${flat ? ` class="flat"` : ""}${htmlAttr(theme)}>
|
|
411
|
-
<input type="checkbox" id="flip" class="sr" aria-label="Flip the card">
|
|
412
|
-
<input type="checkbox" id="ink" class="sr" aria-label="Switch the card between light and dark">
|
|
413
|
-
<input type="checkbox" id="portrait" class="sr" aria-label="Portrait view"${portrait ? " checked" : ""}>
|
|
414
|
-
<div class="stage">
|
|
415
|
-
<div class="views"><label for="ink" class="view" title="Card: light or dark">◐</label><label for="portrait" class="view" title="Landscape or portrait">▭ ▯</label></div>
|
|
416
|
-
<main class="bcard">
|
|
417
|
-
<div class="faces">
|
|
418
|
-
<section class="face front">
|
|
419
|
-
<div class="logo" aria-hidden="true">${escapeHtml(cardInitials(name))}</div>
|
|
420
|
-
${WHATIS}
|
|
421
|
-
<div class="id">
|
|
422
|
-
<h1>${escapeHtml(name)}</h1>
|
|
423
|
-
${title ? `<p class="title">${escapeHtml(title)}</p>` : ""}
|
|
424
|
-
${oneLiner ? `<p class="oneliner">${escapeHtml(oneLiner)}</p>` : ""}
|
|
425
|
-
</div>
|
|
426
|
-
<div class="foot-front">${domain ? `<span class="domain">${escapeHtml(domain)}</span>` : ""}${pills ? `<div class="pills">${pills}</div>` : ""}</div>
|
|
427
|
-
<label for="flip" class="flipbtn" data-tip="Flip the card" aria-label="Flip the card"><span aria-hidden="true">↻</span></label>
|
|
428
|
-
</section>
|
|
429
|
-
<section class="face back">
|
|
430
|
-
${radios}
|
|
431
|
-
${WHATIS}
|
|
432
|
-
<div class="tabbar">${tabbar}</div>
|
|
433
|
-
<div class="panes">${panes}</div>
|
|
434
|
-
<label for="flip" class="flipbtn back-btn" data-tip="Flip back" aria-label="Flip back"><span aria-hidden="true">↺</span></label>
|
|
435
|
-
</section>
|
|
436
|
-
</div>
|
|
437
|
-
</main>
|
|
438
|
-
<p class="hint">${escapeHtml(name)} · business card · <label for="flip">flip it over</label></p>
|
|
439
|
-
</div>
|
|
440
|
-
${CARD_SCRIPT}
|
|
441
|
-
</body>
|
|
442
|
-
</html>
|
|
443
|
-
`;
|
|
444
|
-
}
|
|
445
|
-
/**
|
|
446
|
-
* The card's only script — a progressive enhancement. Flip, tabs and the view
|
|
447
|
-
* toggle are CSS (checkbox and radio inputs) and work without it. It adds:
|
|
448
|
-
* Expand all / Collapse all for the context sections, opening the section a
|
|
449
|
-
* `#hash` names (flipping to the back and its Context tab first), and opening
|
|
450
|
-
* every section for printing (browsers disagree on printing a closed
|
|
451
|
-
* `<details>`).
|
|
452
|
-
*/
|
|
453
|
-
const CARD_SCRIPT = `<script>
|
|
454
|
-
(function(){
|
|
455
|
-
var secs=[].slice.call(document.querySelectorAll("details.ctx-section"));
|
|
456
|
-
var btn=document.querySelector(".xall");
|
|
457
|
-
var sync=function(){if(btn)btn.textContent=secs.every(function(d){return d.open})?"Collapse all":"Expand all"};
|
|
458
|
-
if(btn&&secs.length){
|
|
459
|
-
btn.hidden=false;
|
|
460
|
-
btn.addEventListener("click",function(){var open=!secs.every(function(d){return d.open});secs.forEach(function(d){d.open=open});sync()});
|
|
461
|
-
secs.forEach(function(d){d.addEventListener("toggle",sync)});
|
|
462
|
-
}
|
|
463
|
-
var openHash=function(){
|
|
464
|
-
var d=document.getElementById(decodeURIComponent(location.hash.slice(1)));
|
|
465
|
-
if(!d||d.tagName!=="DETAILS")return;
|
|
466
|
-
var f=document.getElementById("flip"),t=document.getElementById("t-context");
|
|
467
|
-
if(f)f.checked=true;if(t)t.checked=true;d.open=true;sync();
|
|
468
|
-
setTimeout(function(){d.scrollIntoView({block:"nearest"})},620);
|
|
469
|
-
};
|
|
470
|
-
addEventListener("hashchange",openHash);openHash();
|
|
471
|
-
var pre=[];
|
|
472
|
-
addEventListener("beforeprint",function(){pre=secs.map(function(d){return d.open});secs.forEach(function(d){d.open=true})});
|
|
473
|
-
addEventListener("afterprint",function(){secs.forEach(function(d,i){d.open=pre[i]});sync()});
|
|
474
|
-
sync();
|
|
475
|
-
})();
|
|
476
|
-
</script>`;
|
|
477
171
|
const TLDR_FACTS = 5;
|
|
478
172
|
const TLDR_CHARS = 160;
|
|
479
173
|
/**
|
package/dist/server.js
CHANGED
|
@@ -62,7 +62,7 @@ function cardOptions(args) {
|
|
|
62
62
|
}
|
|
63
63
|
const CARD_ARGS = {
|
|
64
64
|
theme: { type: "string", enum: ["light", "dark", "auto"], description: "default: auto" },
|
|
65
|
-
accent: { type: "string", description: "CSS hex colour, e.g. #
|
|
65
|
+
accent: { type: "string", description: "CSS hex colour, e.g. #0066cc (default: the .fafa metadata.cards.accent, else black/white ink)" },
|
|
66
66
|
expanded: { type: "boolean", description: "render every AGENTS.md section open (default: collapsed)" },
|
|
67
67
|
layout: { type: "string", enum: ["landscape", "portrait"], description: "business-card view (default: landscape)" },
|
|
68
68
|
};
|
package/docs/MECHANISMS.md
CHANGED
|
@@ -32,7 +32,7 @@ Streamable HTTP endpoint at `<origin>/mcp` and its protocol versions):
|
|
|
32
32
|
{
|
|
33
33
|
"$schema": "https://static.modelcontextprotocol.io/schemas/v1/server-card.schema.json",
|
|
34
34
|
"name": "io.github.Wolfe-Jam/mcp-context-card",
|
|
35
|
-
"version": "1.
|
|
35
|
+
"version": "1.7.1",
|
|
36
36
|
"title": "MCP Context Card",
|
|
37
37
|
"description": "MCP server for a project's context (AGENTS.md), memory, and identity — base or drop-in extension.",
|
|
38
38
|
"websiteUrl": "https://github.com/Wolfe-Jam/mcp-context-card",
|
|
@@ -85,7 +85,7 @@ publisher lists artifacts, each entry keyed by its **media type** (`type`).
|
|
|
85
85
|
GET /.well-known/ai-catalog.json
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
-
Served from `https://ctx.example.com` (1.
|
|
88
|
+
Served from `https://ctx.example.com` (1.7.1, this repo's own files):
|
|
89
89
|
|
|
90
90
|
```jsonc
|
|
91
91
|
{
|
package/docs/card-dark.html
CHANGED
|
@@ -205,7 +205,7 @@ details.ctx-section>.md{padding:0 0 16px}
|
|
|
205
205
|
</details>
|
|
206
206
|
<div class="id">
|
|
207
207
|
<h1>mcp-context-card</h1>
|
|
208
|
-
<p class="title">MCP server · v1.
|
|
208
|
+
<p class="title">MCP server · v1.7.1</p>
|
|
209
209
|
<p class="oneliner">The essential MCP components for a project's context (AGENTS.md), cross-session memory, and identity</p>
|
|
210
210
|
</div>
|
|
211
211
|
<div class="foot-front"><span class="domain">faf.one</span><div class="pills"><span class="pill">io.github.Wolfe-Jam</span><span class="pill accent">published</span><span class="pill">MIT</span></div></div>
|
|
@@ -223,11 +223,11 @@ details.ctx-section>.md{padding:0 0 16px}
|
|
|
223
223
|
</div>
|
|
224
224
|
</details>
|
|
225
225
|
<div class="tabbar"><label for="t-about">About</label><label for="t-context">Context</label><label for="t-memory">Memory</label><label for="t-discovery">Discovery</label></div>
|
|
226
|
-
<div class="panes"><div class="pane p-about"><p class="label">About</p><p class="lead">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.</p><table class="kv"><tbody><tr><th>Agent ID</th><td><code>urn:air:faf.one:agent:mcp-context-card</code></td></tr><tr><th>Publisher</th><td>io.github.Wolfe-Jam</td></tr><tr><th>Version</th><td>v1.
|
|
226
|
+
<div class="panes"><div class="pane p-about"><p class="label">About</p><p class="lead">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.</p><table class="kv"><tbody><tr><th>Agent ID</th><td><code>urn:air:faf.one:agent:mcp-context-card</code></td></tr><tr><th>Publisher</th><td>io.github.Wolfe-Jam</td></tr><tr><th>Version</th><td>v1.7.1</td></tr><tr><th>Status</th><td>published</td></tr><tr><th>License</th><td>MIT</td></tr><tr><th>Package (npm)</th><td><code>mcp-context-card</code></td></tr></tbody></table></div><div class="pane p-context"><p class="label">Context — AGENTS.md</p><div class="ctx-nav"><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><button type="button" class="xall" hidden>Expand all</button></div>
|
|
227
227
|
<div class="ctx-preamble 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>
|
|
228
228
|
<p><code>read_agents_md</code> serves this file, section by section, over the same MCP connection.</p></div>
|
|
229
229
|
<div class="ctx-body"><details class="ctx-section" id="setup"><summary>Setup</summary><div class="md"><pre><code class="language-bash">npm ci</code></pre>
|
|
230
|
-
<p>Node
|
|
230
|
+
<p>Node 22 or newer. No other system dependencies.</p></div></details><details class="ctx-section" id="build"><summary>Build</summary><div class="md"><pre><code class="language-bash">npm run build # tsc -p tsconfig.build.json → dist/
|
|
231
231
|
npm run typecheck # tsc --noEmit over src/ + test/</code></pre></div></details><details class="ctx-section" id="test"><summary>Test</summary><div class="md"><pre><code class="language-bash">npm test # node:test — every test/*.test.ts
|
|
232
232
|
npm run test:coverage # + the coverage gate (lines 90 / funcs 85 / branches 80, src/ only)
|
|
233
233
|
npm run demo # end to end: all tools over stdio, then over stateless HTTP
|
package/docs/card-light.html
CHANGED
|
@@ -205,7 +205,7 @@ details.ctx-section>.md{padding:0 0 16px}
|
|
|
205
205
|
</details>
|
|
206
206
|
<div class="id">
|
|
207
207
|
<h1>mcp-context-card</h1>
|
|
208
|
-
<p class="title">MCP server · v1.
|
|
208
|
+
<p class="title">MCP server · v1.7.1</p>
|
|
209
209
|
<p class="oneliner">The essential MCP components for a project's context (AGENTS.md), cross-session memory, and identity</p>
|
|
210
210
|
</div>
|
|
211
211
|
<div class="foot-front"><span class="domain">faf.one</span><div class="pills"><span class="pill">io.github.Wolfe-Jam</span><span class="pill accent">published</span><span class="pill">MIT</span></div></div>
|
|
@@ -223,11 +223,11 @@ details.ctx-section>.md{padding:0 0 16px}
|
|
|
223
223
|
</div>
|
|
224
224
|
</details>
|
|
225
225
|
<div class="tabbar"><label for="t-about">About</label><label for="t-context">Context</label><label for="t-memory">Memory</label><label for="t-discovery">Discovery</label></div>
|
|
226
|
-
<div class="panes"><div class="pane p-about"><p class="label">About</p><p class="lead">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.</p><table class="kv"><tbody><tr><th>Agent ID</th><td><code>urn:air:faf.one:agent:mcp-context-card</code></td></tr><tr><th>Publisher</th><td>io.github.Wolfe-Jam</td></tr><tr><th>Version</th><td>v1.
|
|
226
|
+
<div class="panes"><div class="pane p-about"><p class="label">About</p><p class="lead">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.</p><table class="kv"><tbody><tr><th>Agent ID</th><td><code>urn:air:faf.one:agent:mcp-context-card</code></td></tr><tr><th>Publisher</th><td>io.github.Wolfe-Jam</td></tr><tr><th>Version</th><td>v1.7.1</td></tr><tr><th>Status</th><td>published</td></tr><tr><th>License</th><td>MIT</td></tr><tr><th>Package (npm)</th><td><code>mcp-context-card</code></td></tr></tbody></table></div><div class="pane p-context"><p class="label">Context — AGENTS.md</p><div class="ctx-nav"><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><button type="button" class="xall" hidden>Expand all</button></div>
|
|
227
227
|
<div class="ctx-preamble 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>
|
|
228
228
|
<p><code>read_agents_md</code> serves this file, section by section, over the same MCP connection.</p></div>
|
|
229
229
|
<div class="ctx-body"><details class="ctx-section" id="setup"><summary>Setup</summary><div class="md"><pre><code class="language-bash">npm ci</code></pre>
|
|
230
|
-
<p>Node
|
|
230
|
+
<p>Node 22 or newer. No other system dependencies.</p></div></details><details class="ctx-section" id="build"><summary>Build</summary><div class="md"><pre><code class="language-bash">npm run build # tsc -p tsconfig.build.json → dist/
|
|
231
231
|
npm run typecheck # tsc --noEmit over src/ + test/</code></pre></div></details><details class="ctx-section" id="test"><summary>Test</summary><div class="md"><pre><code class="language-bash">npm test # node:test — every test/*.test.ts
|
|
232
232
|
npm run test:coverage # + the coverage gate (lines 90 / funcs 85 / branches 80, src/ only)
|
|
233
233
|
npm run demo # end to end: all tools over stdio, then over stateless HTTP
|
package/docs/card.html
CHANGED
|
@@ -205,7 +205,7 @@ details.ctx-section>.md{padding:0 0 16px}
|
|
|
205
205
|
</details>
|
|
206
206
|
<div class="id">
|
|
207
207
|
<h1>mcp-context-card</h1>
|
|
208
|
-
<p class="title">MCP server · v1.
|
|
208
|
+
<p class="title">MCP server · v1.7.1</p>
|
|
209
209
|
<p class="oneliner">The essential MCP components for a project's context (AGENTS.md), cross-session memory, and identity</p>
|
|
210
210
|
</div>
|
|
211
211
|
<div class="foot-front"><span class="domain">faf.one</span><div class="pills"><span class="pill">io.github.Wolfe-Jam</span><span class="pill accent">published</span><span class="pill">MIT</span></div></div>
|
|
@@ -223,11 +223,11 @@ details.ctx-section>.md{padding:0 0 16px}
|
|
|
223
223
|
</div>
|
|
224
224
|
</details>
|
|
225
225
|
<div class="tabbar"><label for="t-about">About</label><label for="t-context">Context</label><label for="t-memory">Memory</label><label for="t-discovery">Discovery</label></div>
|
|
226
|
-
<div class="panes"><div class="pane p-about"><p class="label">About</p><p class="lead">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.</p><table class="kv"><tbody><tr><th>Agent ID</th><td><code>urn:air:faf.one:agent:mcp-context-card</code></td></tr><tr><th>Publisher</th><td>io.github.Wolfe-Jam</td></tr><tr><th>Version</th><td>v1.
|
|
226
|
+
<div class="panes"><div class="pane p-about"><p class="label">About</p><p class="lead">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.</p><table class="kv"><tbody><tr><th>Agent ID</th><td><code>urn:air:faf.one:agent:mcp-context-card</code></td></tr><tr><th>Publisher</th><td>io.github.Wolfe-Jam</td></tr><tr><th>Version</th><td>v1.7.1</td></tr><tr><th>Status</th><td>published</td></tr><tr><th>License</th><td>MIT</td></tr><tr><th>Package (npm)</th><td><code>mcp-context-card</code></td></tr></tbody></table></div><div class="pane p-context"><p class="label">Context — AGENTS.md</p><div class="ctx-nav"><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><button type="button" class="xall" hidden>Expand all</button></div>
|
|
227
227
|
<div class="ctx-preamble 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>
|
|
228
228
|
<p><code>read_agents_md</code> serves this file, section by section, over the same MCP connection.</p></div>
|
|
229
229
|
<div class="ctx-body"><details class="ctx-section" id="setup"><summary>Setup</summary><div class="md"><pre><code class="language-bash">npm ci</code></pre>
|
|
230
|
-
<p>Node
|
|
230
|
+
<p>Node 22 or newer. No other system dependencies.</p></div></details><details class="ctx-section" id="build"><summary>Build</summary><div class="md"><pre><code class="language-bash">npm run build # tsc -p tsconfig.build.json → dist/
|
|
231
231
|
npm run typecheck # tsc --noEmit over src/ + test/</code></pre></div></details><details class="ctx-section" id="test"><summary>Test</summary><div class="md"><pre><code class="language-bash">npm test # node:test — every test/*.test.ts
|
|
232
232
|
npm run test:coverage # + the coverage gate (lines 90 / funcs 85 / branches 80, src/ only)
|
|
233
233
|
npm run demo # end to end: all tools over stdio, then over stateless HTTP
|
package/docs/img/card-dark.png
CHANGED
|
Binary file
|
|
Binary file
|
package/docs/img/card-light.png
CHANGED
|
Binary file
|
package/docs/index.html
CHANGED
|
@@ -205,7 +205,7 @@ details.ctx-section>.md{padding:0 0 16px}
|
|
|
205
205
|
</details>
|
|
206
206
|
<div class="id">
|
|
207
207
|
<h1>mcp-context-card</h1>
|
|
208
|
-
<p class="title">MCP server · v1.
|
|
208
|
+
<p class="title">MCP server · v1.7.1</p>
|
|
209
209
|
<p class="oneliner">The essential MCP components for a project's context (AGENTS.md), cross-session memory, and identity</p>
|
|
210
210
|
</div>
|
|
211
211
|
<div class="foot-front"><span class="domain">faf.one</span><div class="pills"><span class="pill">io.github.Wolfe-Jam</span><span class="pill accent">published</span><span class="pill">MIT</span></div></div>
|
|
@@ -223,11 +223,11 @@ details.ctx-section>.md{padding:0 0 16px}
|
|
|
223
223
|
</div>
|
|
224
224
|
</details>
|
|
225
225
|
<div class="tabbar"><label for="t-about">About</label><label for="t-context">Context</label><label for="t-memory">Memory</label><label for="t-discovery">Discovery</label></div>
|
|
226
|
-
<div class="panes"><div class="pane p-about"><p class="label">About</p><p class="lead">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.</p><table class="kv"><tbody><tr><th>Agent ID</th><td><code>urn:air:faf.one:agent:mcp-context-card</code></td></tr><tr><th>Publisher</th><td>io.github.Wolfe-Jam</td></tr><tr><th>Version</th><td>v1.
|
|
226
|
+
<div class="panes"><div class="pane p-about"><p class="label">About</p><p class="lead">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.</p><table class="kv"><tbody><tr><th>Agent ID</th><td><code>urn:air:faf.one:agent:mcp-context-card</code></td></tr><tr><th>Publisher</th><td>io.github.Wolfe-Jam</td></tr><tr><th>Version</th><td>v1.7.1</td></tr><tr><th>Status</th><td>published</td></tr><tr><th>License</th><td>MIT</td></tr><tr><th>Package (npm)</th><td><code>mcp-context-card</code></td></tr></tbody></table></div><div class="pane p-context"><p class="label">Context — AGENTS.md</p><div class="ctx-nav"><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><button type="button" class="xall" hidden>Expand all</button></div>
|
|
227
227
|
<div class="ctx-preamble 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>
|
|
228
228
|
<p><code>read_agents_md</code> serves this file, section by section, over the same MCP connection.</p></div>
|
|
229
229
|
<div class="ctx-body"><details class="ctx-section" id="setup"><summary>Setup</summary><div class="md"><pre><code class="language-bash">npm ci</code></pre>
|
|
230
|
-
<p>Node
|
|
230
|
+
<p>Node 22 or newer. No other system dependencies.</p></div></details><details class="ctx-section" id="build"><summary>Build</summary><div class="md"><pre><code class="language-bash">npm run build # tsc -p tsconfig.build.json → dist/
|
|
231
231
|
npm run typecheck # tsc --noEmit over src/ + test/</code></pre></div></details><details class="ctx-section" id="test"><summary>Test</summary><div class="md"><pre><code class="language-bash">npm test # node:test — every test/*.test.ts
|
|
232
232
|
npm run test:coverage # + the coverage gate (lines 90 / funcs 85 / branches 80, src/ only)
|
|
233
233
|
npm run demo # end to end: all tools over stdio, then over stateless HTTP
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-context-card",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.1",
|
|
4
4
|
"mcpName": "io.github.Wolfe-Jam/mcp-context-card",
|
|
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
6
|
"keywords": [
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
"dependencies": {
|
|
67
67
|
"@hono/node-server": "^1.19.17",
|
|
68
68
|
"@modelcontextprotocol/sdk": "^1.31.0",
|
|
69
|
+
"agent-business-card": "^0.1.0",
|
|
69
70
|
"agents-md-facts": "^0.1.0",
|
|
70
71
|
"hono": "^4.13.7",
|
|
71
72
|
"yaml": "^2.9.0"
|
package/project.faf
CHANGED
|
@@ -24,7 +24,7 @@ stack:
|
|
|
24
24
|
cache: slotignored
|
|
25
25
|
search: slotignored
|
|
26
26
|
storage: slotignored
|
|
27
|
-
tech_stack: [TypeScript, "@modelcontextprotocol/sdk", "agents-md-facts", hono, "@hono/node-server", yaml]
|
|
27
|
+
tech_stack: [TypeScript, "@modelcontextprotocol/sdk", "agents-md-facts", "agent-business-card", hono, "@hono/node-server", yaml]
|
|
28
28
|
human_context:
|
|
29
29
|
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.
|
|
30
30
|
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. Ten tools — read_agents_md / list_agents_md_sections / author_agents_md (context), remember / recall / forget (memory), whoami (identity), list_context_sources / render_context_card / save_context_card (discovery) — exposed through the Server Card _meta block and a self-published ai-catalog.json. Dual transport (stdio + stateless Streamable HTTP).
|
package/server.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "io.github.Wolfe-Jam/mcp-context-card",
|
|
4
4
|
"title": "MCP Context Card",
|
|
5
5
|
"description": "MCP server for a project's context (AGENTS.md), memory, and identity — base or drop-in extension.",
|
|
6
|
-
"version": "1.
|
|
6
|
+
"version": "1.7.1",
|
|
7
7
|
"repository": {
|
|
8
8
|
"url": "https://github.com/Wolfe-Jam/mcp-context-card",
|
|
9
9
|
"source": "github"
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"registryType": "npm",
|
|
15
15
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
16
16
|
"identifier": "mcp-context-card",
|
|
17
|
-
"version": "1.
|
|
17
|
+
"version": "1.7.1",
|
|
18
18
|
"runtimeHint": "npx",
|
|
19
19
|
"transport": {
|
|
20
20
|
"type": "stdio"
|