mcp-context-card 1.7.0 → 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 +1 -1
- package/CHANGELOG.md +17 -0
- package/README.md +1 -1
- package/dist/bin.d.ts +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/render-card.d.ts +3 -44
- package/dist/render-card.js +3 -323
- package/docs/MECHANISMS.md +2 -2
- package/docs/card-dark.html +2 -2
- package/docs/card-light.html +2 -2
- package/docs/card.html +2 -2
- 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 +2 -2
- 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.7.
|
|
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.7.
|
|
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
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,23 @@
|
|
|
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
|
+
|
|
5
22
|
## 1.7.0
|
|
6
23
|
|
|
7
24
|
A card's colour is the owner's.
|
package/README.md
CHANGED
|
@@ -292,7 +292,7 @@ transport security against the specs, one MUST or SHOULD at a time.
|
|
|
292
292
|
| `src/agents-md.ts` | reads and section‑splits `AGENTS.md` |
|
|
293
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 |
|
|
294
294
|
| `src/md.ts` | a minimal dependency‑free Markdown → HTML renderer |
|
|
295
|
-
| `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 |
|
|
296
296
|
| `src/memory.ts` | file‑backed `remember` / `recall` / `forget` |
|
|
297
297
|
| `src/identity.ts` | `whoami` (`.fafa` → `package.json` fallback) + the `_meta` block |
|
|
298
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.7.
|
|
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.7.
|
|
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.7.
|
|
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/render-card.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
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
|
/**
|
|
@@ -23,59 +25,16 @@ export interface CardOptions {
|
|
|
23
25
|
}
|
|
24
26
|
/** AAIF brand orange (aaif.io): this project's own card colour, declared in its `.fafa`. */
|
|
25
27
|
export declare const AAIF_ACCENT = "#FF702D";
|
|
26
|
-
/** A valid hex colour, or undefined. Nothing else ever reaches the stylesheet. */
|
|
27
|
-
export declare function safeAccent(a?: string): string | undefined;
|
|
28
28
|
/** What the front calls this thing, from where it runs: "MCP server", "A2A agent", or both. */
|
|
29
29
|
export declare function cardKind(id: AgentIdentity | null): string[];
|
|
30
30
|
/** The front's title line: what it is, then its version. Empty when nothing is known. */
|
|
31
31
|
export declare function cardTitle(id: AgentIdentity | null): string;
|
|
32
|
-
/**
|
|
33
|
-
* The front's logo: the first letter of the name's first meaningful word
|
|
34
|
-
* (generic words like "mcp", "server", "sdk" skipped), plus a second letter
|
|
35
|
-
* only when it's obvious: a known name (github → GH, typescript → TS) or a
|
|
36
|
-
* word written with two capitals (GitHub, TypeScript). Never more than two.
|
|
37
|
-
*/
|
|
38
|
-
export declare function cardInitials(name: string): string;
|
|
39
32
|
/** The front's one-liner: the first sentence of the description. */
|
|
40
33
|
export declare function cardOneLiner(id: AgentIdentity | null, max?: number): string;
|
|
41
|
-
/**
|
|
42
|
-
* A business card, independent of where its facts came from: everything the
|
|
43
|
-
* renderer draws. `readCard` builds one from a project's files; another reader
|
|
44
|
-
* (an A2A Agent Card, an MCP Server Card, a person's card) can build one too,
|
|
45
|
-
* and `renderBusinessCard` draws any of them the same way.
|
|
46
|
-
*/
|
|
47
|
-
export interface BusinessCard {
|
|
48
|
-
name: string;
|
|
49
|
-
/** What it is (and its version): "MCP server · v1.5.0", or a person's role. */
|
|
50
|
-
title?: string;
|
|
51
|
-
oneLiner?: string;
|
|
52
|
-
/** Shown bottom-left on the front, e.g. the publisher domain. */
|
|
53
|
-
domain?: string;
|
|
54
|
-
/** Footer chips; `accent` highlights one (e.g. the status). Plain text. */
|
|
55
|
-
chips: {
|
|
56
|
-
text: string;
|
|
57
|
-
accent?: boolean;
|
|
58
|
-
}[];
|
|
59
|
-
/** The back's tabs, in order. `key` is [a-z0-9-]; `html` is already-safe markup. */
|
|
60
|
-
tabs: {
|
|
61
|
-
key: string;
|
|
62
|
-
label: string;
|
|
63
|
-
heading: string;
|
|
64
|
-
html: string;
|
|
65
|
-
}[];
|
|
66
|
-
/** The (i) panel, as already-safe markup. */
|
|
67
|
-
about: string;
|
|
68
|
-
/** The owner's colour, a hex. None = ink (black or white). */
|
|
69
|
-
accent?: string;
|
|
70
|
-
}
|
|
71
|
-
/** How to draw a card: the owner's colour and accent, the view, and the flat (print) layout. */
|
|
72
|
-
export type RenderOptions = Pick<CardOptions, "theme" | "accent" | "layout" | "expanded">;
|
|
73
34
|
/** The project's card: read its files, then draw. */
|
|
74
35
|
export declare function renderCard(root: string, opts?: CardOptions): string;
|
|
75
36
|
/** Read a project's AGENTS.md, memory and identity into a business card. */
|
|
76
37
|
export declare function readCard(root: string, opts?: Pick<CardOptions, "expanded" | "memory">): BusinessCard;
|
|
77
|
-
/** Draw any business card as one self-contained HTML page. */
|
|
78
|
-
export declare function renderBusinessCard(card: BusinessCard, opts?: RenderOptions): string;
|
|
79
38
|
/** tl;dr: the first few facts, each cut to about a line. `full`: every fact, whole. */
|
|
80
39
|
export type Detail = "tldr" | "full";
|
|
81
40
|
/**
|
package/dist/render-card.js
CHANGED
|
@@ -16,205 +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
|
+
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";
|
|
19
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
|
-
/** A valid hex colour, or undefined. Nothing else ever reaches the stylesheet. */
|
|
23
|
-
export function safeAccent(a) {
|
|
24
|
-
return a && ACCENT_OK.test(a) ? a : undefined;
|
|
25
|
-
}
|
|
26
|
-
/*
|
|
27
|
-
* No colour = ink. A card's colour is the owner's to declare (or the reader's
|
|
28
|
-
* to pass); nothing is guessed. Without one the accent is the card's own ink:
|
|
29
|
-
* black on a light card, white on a dark one, and the monogram's letter takes
|
|
30
|
-
* the card colour so it stays readable.
|
|
31
|
-
*/
|
|
32
|
-
const INK_CSS = `
|
|
33
|
-
:root{--accent:#0a0a0a}
|
|
34
|
-
@media (prefers-color-scheme:dark){:root{--accent:#fafafa}}
|
|
35
|
-
.bcard{--accent:var(--fg)}
|
|
36
|
-
.logo{color:var(--card)}
|
|
37
|
-
`;
|
|
38
|
-
const CSS = (accent) => `
|
|
39
|
-
/* The page and the card are themed independently. The page follows the
|
|
40
|
-
viewer's OS. The card is the owner's choice: body[data-theme] (light | dark;
|
|
41
|
-
none = follow the OS), and the reader can switch it with the ◐ toggle (#ink). */
|
|
42
|
-
:root{
|
|
43
|
-
${accent ? `--accent:${accent};` : ""}
|
|
44
|
-
--page-bg:#f4f4f5;--page-muted:#6b6b70;--page-line:rgba(0,0,0,.09);--page-chip:rgba(0,0,0,.05);
|
|
45
|
-
}
|
|
46
|
-
@media (prefers-color-scheme:dark){
|
|
47
|
-
:root{--page-bg:#000;--page-muted:#9a9aa0;--page-line:rgba(255,255,255,.13);--page-chip:rgba(255,255,255,.07)}
|
|
48
|
-
}
|
|
49
|
-
.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)}
|
|
50
|
-
body[data-theme="dark"] .bcard,
|
|
51
|
-
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)}
|
|
52
|
-
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)}
|
|
53
|
-
@media (prefers-color-scheme:dark){
|
|
54
|
-
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)}
|
|
55
|
-
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)}
|
|
56
|
-
}
|
|
57
|
-
@media (prefers-color-scheme:light){
|
|
58
|
-
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)}
|
|
59
|
-
}
|
|
60
|
-
.bcard{color:var(--fg)}
|
|
61
|
-
*{box-sizing:border-box}
|
|
62
|
-
body{margin:0;background:var(--page-bg);color:var(--page-muted);
|
|
63
|
-
font:15px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
|
|
64
|
-
padding:40px 16px}
|
|
65
|
-
/* ── the business card: two faces, flip, two views ─────────────────── */
|
|
66
|
-
.sr{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
|
|
67
|
-
.stage{max-width:760px;margin:0 auto}
|
|
68
|
-
.views{display:flex;justify-content:flex-end;margin:0 0 10px}
|
|
69
|
-
.view,.hint label{cursor:pointer}
|
|
70
|
-
.view{font-size:.78rem;font-weight:600;padding:3px 11px;border-radius:20px;border:1px solid var(--page-line);
|
|
71
|
-
background:var(--page-chip);color:var(--page-muted);letter-spacing:.2em}
|
|
72
|
-
.views{gap:8px}
|
|
73
|
-
.view:hover,.hint label:hover{color:var(--accent);border-color:var(--accent)}
|
|
74
|
-
.bcard{margin:0 auto;width:100%;aspect-ratio:7/4;perspective:1600px}
|
|
75
|
-
#portrait:checked~.stage{max-width:480px}
|
|
76
|
-
#portrait:checked~.stage .bcard{aspect-ratio:4/7}
|
|
77
|
-
.faces{position:relative;width:100%;height:100%;transform-style:preserve-3d;transition:transform .6s ease}
|
|
78
|
-
#flip:checked~.stage .faces{transform:rotateY(180deg)}
|
|
79
|
-
.face{position:absolute;inset:0;background:var(--card);border:1px solid var(--line);border-radius:16px;
|
|
80
|
-
box-shadow:var(--card-shadow);backface-visibility:hidden;-webkit-backface-visibility:hidden;overflow:hidden}
|
|
81
|
-
.back{transform:rotateY(180deg) translateZ(1px);display:flex;flex-direction:column}
|
|
82
|
-
/* The face turned away takes no pointer or wheel events, so the visible face
|
|
83
|
-
scrolls (a hidden backface can still win hit-testing, notably in Chrome/Safari on macOS). */
|
|
84
|
-
#flip:checked~.stage .front,#flip:not(:checked)~.stage .back{pointer-events:none;visibility:hidden;transition:visibility 0s .3s}
|
|
85
|
-
#flip:checked~.stage .back,#flip:not(:checked)~.stage .front{visibility:visible;transition:visibility 0s .3s}
|
|
86
|
-
.panes{overscroll-behavior:contain;-webkit-overflow-scrolling:touch}
|
|
87
|
-
.front{display:flex;flex-direction:column;justify-content:center;padding:34px 44px;
|
|
88
|
-
border-top:5px solid var(--accent);
|
|
89
|
-
background:linear-gradient(135deg,color-mix(in srgb,var(--accent) 10%,var(--card)) 0%,var(--card) 55%)}
|
|
90
|
-
.front .id{max-width:34em}
|
|
91
|
-
h1{margin:0;font-size:2.1rem;line-height:1.15;letter-spacing:-.025em}
|
|
92
|
-
.title{margin:8px 0 0;font-size:.82rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--accent)}
|
|
93
|
-
.oneliner{margin:16px 0 0;font-size:1.05rem;color:var(--muted);line-height:1.5}
|
|
94
|
-
.foot-front{position:absolute;left:44px;right:130px;bottom:22px;display:flex;flex-wrap:wrap;align-items:center;gap:6px 12px}
|
|
95
|
-
.domain{font:.8rem ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--muted)}
|
|
96
|
-
.corner{position:absolute;width:30px;height:30px;border-radius:50%;display:grid;place-items:center;
|
|
97
|
-
cursor:pointer;font-weight:700;font-size:.9rem;color:var(--muted);background:var(--chip);border:1px solid var(--line);z-index:4}
|
|
98
|
-
.corner:hover{color:var(--accent);border-color:var(--accent)}
|
|
99
|
-
.corner.tr{top:16px;right:16px;font-family:Georgia,serif;font-style:italic}
|
|
100
|
-
.logo{position:absolute;top:34px;left:44px;width:84px;height:84px;border-radius:50%;display:grid;place-items:center;
|
|
101
|
-
color:#fff;font-weight:800;font-size:2rem;letter-spacing:-.02em;line-height:1;
|
|
102
|
-
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));
|
|
103
|
-
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)}
|
|
104
|
-
.front .id{margin-top:70px}
|
|
105
|
-
.corner.br{bottom:16px;right:16px}
|
|
106
|
-
.flipbtn{position:absolute;right:18px;bottom:16px;z-index:4;cursor:pointer;width:42px;height:42px;border-radius:50%;
|
|
107
|
-
display:grid;place-items:center;color:var(--fg);background:transparent;box-shadow:inset 0 0 0 2px var(--fg);
|
|
108
|
-
transition:transform .2s ease}
|
|
109
|
-
.flipbtn span{font-size:1.3rem;line-height:1;font-weight:700}
|
|
110
|
-
|
|
111
|
-
/* the back's button: same spot and outline as the front's; ↺ instead of ↻. Over
|
|
112
|
-
scrolling text it takes the card's colour, so the arrow stays readable. */
|
|
113
|
-
.flipbtn.back-btn{background:var(--card)}
|
|
114
|
-
/* fast tooltip: shows at once on hover or keyboard focus (a title tooltip waits ~1 s) */
|
|
115
|
-
.flipbtn[data-tip]::after{content:attr(data-tip);position:absolute;right:0;bottom:calc(100% + 8px);white-space:nowrap;
|
|
116
|
-
font:600 .74rem/1 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;letter-spacing:0;padding:6px 9px;border-radius:7px;
|
|
117
|
-
color:var(--card);background:var(--fg);opacity:0;transform:translateY(3px);pointer-events:none;transition:opacity .08s,transform .08s}
|
|
118
|
-
.flipbtn[data-tip]:hover::after,#flip:focus-visible~.stage .flipbtn[data-tip]::after{opacity:1;transform:none}
|
|
119
|
-
.flipbtn:hover{transform:none}.flipbtn:hover span{transform:rotate(-25deg)}.flipbtn span{transition:transform .2s ease}
|
|
120
|
-
.whatis{position:absolute;top:16px;right:16px;z-index:5}
|
|
121
|
-
.whatis>summary{position:static;list-style:none}
|
|
122
|
-
.whatis>summary::-webkit-details-marker{display:none}
|
|
123
|
-
.whatis[open]>summary{color:var(--accent);border-color:var(--accent)}
|
|
124
|
-
.whatis-panel{position:absolute;right:0;top:38px;width:min(320px,70vw);padding:14px 16px;border-radius:12px;
|
|
125
|
-
background:var(--card);border:1px solid var(--line);box-shadow:var(--card-shadow);font-size:.84rem;line-height:1.5}
|
|
126
|
-
.whatis-panel p{margin:0 0 8px}.whatis-head{font-weight:800;color:var(--accent);letter-spacing:-.01em;font-size:.95rem}
|
|
127
|
-
.whatis-foot{color:var(--muted);margin:0!important}.whatis-panel code{font:.86em ui-monospace,SFMono-Regular,Menlo,monospace}
|
|
128
|
-
.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)}
|
|
129
|
-
.tabbar label{cursor:pointer;font-size:.8rem;font-weight:600;color:var(--muted);padding:6px 11px;border-radius:8px 8px 0 0}
|
|
130
|
-
.tabbar label:hover{color:var(--fg)}
|
|
131
|
-
.panes{flex:1;overflow:auto;padding:20px 26px 72px}
|
|
132
|
-
.pane{display:none}
|
|
133
|
-
.lead{margin:0 0 14px;font-size:1rem;line-height:1.6}
|
|
134
|
-
.kv{border-collapse:collapse;font-size:.86rem;width:100%}
|
|
135
|
-
.kv th{text-align:left;font-weight:600;color:var(--muted);padding:6px 14px 6px 0;white-space:nowrap;vertical-align:top}
|
|
136
|
-
.kv td{padding:6px 0;border-bottom:1px solid var(--line)}
|
|
137
|
-
.kv code,.lead code{font:.86em ui-monospace,SFMono-Regular,Menlo,monospace}
|
|
138
|
-
.hint{text-align:center;color:var(--page-muted);font-size:.78rem;margin:14px 0 0}
|
|
139
|
-
.hint label{color:var(--accent)}
|
|
140
|
-
#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}
|
|
141
|
-
@media (max-width:640px){
|
|
142
|
-
.bcard,#portrait:checked~.stage .bcard{aspect-ratio:auto;height:min(78vh,720px)}
|
|
143
|
-
.front{padding:28px 26px}.foot-front{left:26px}
|
|
144
|
-
.logo{top:24px;left:26px;width:64px;height:64px;font-size:1.5rem}.front .id{margin-top:56px}
|
|
145
|
-
h1{font-size:1.7rem}
|
|
146
|
-
}
|
|
147
|
-
/* flat: expanded render and print — both faces, every tab, no flip */
|
|
148
|
-
.flat .faces,.flat .face{position:static;transform:none!important;height:auto}
|
|
149
|
-
.flat .bcard{aspect-ratio:auto;perspective:none}
|
|
150
|
-
.flat .face{margin:0 0 18px}.flat .front{min-height:260px;position:relative}
|
|
151
|
-
.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}
|
|
152
|
-
.flat .panes{overflow:visible}
|
|
153
|
-
@media print{
|
|
154
|
-
.faces,.face{position:static!important;transform:none!important;height:auto!important}
|
|
155
|
-
.bcard{aspect-ratio:auto!important}.face{margin:0 0 18px;box-shadow:none}
|
|
156
|
-
.pane{display:block!important;margin:0 0 22px}.tabbar,.views,.hint,.corner,.flipbtn,.whatis{display:none!important}
|
|
157
|
-
.panes{overflow:visible}
|
|
158
|
-
}
|
|
159
|
-
.pills{display:flex;flex-wrap:wrap;gap:6px}
|
|
160
|
-
.pill{font-size:.74rem;font-weight:600;padding:3px 9px;border-radius:20px;background:var(--chip);color:var(--muted)}
|
|
161
|
-
.pill.accent{background:color-mix(in srgb,var(--accent) 16%,transparent);color:var(--accent)}
|
|
162
|
-
.label{font-size:.7rem;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
|
|
163
|
-
color:var(--accent);margin:0 0 14px}
|
|
164
|
-
.toc{display:flex;flex-wrap:wrap;gap:6px 14px;margin:0;padding:0;list-style:none}
|
|
165
|
-
.toc a{font-size:.82rem;color:var(--muted);text-decoration:none}
|
|
166
|
-
.toc a:hover{color:var(--accent)}
|
|
167
|
-
/* ── collapsible context ─────────────────────────────────────────── */
|
|
168
|
-
.ctx-nav{position:sticky;top:-20px;z-index:3;background:var(--card);
|
|
169
|
-
margin:0 -26px 16px;padding:11px 26px;border-bottom:1px solid var(--line);
|
|
170
|
-
display:flex;flex-wrap:wrap;align-items:flex-start;gap:8px 16px}
|
|
171
|
-
.xall{margin-left:auto;flex:none;font:inherit;font-size:.76rem;font-weight:600;
|
|
172
|
-
white-space:nowrap;padding:3px 11px;border-radius:20px;border:1px solid var(--line);
|
|
173
|
-
background:var(--chip);color:var(--muted);cursor:pointer}
|
|
174
|
-
.xall:hover{color:var(--accent);border-color:var(--accent)}
|
|
175
|
-
.ctx-preamble{padding-bottom:4px}
|
|
176
|
-
details.ctx-section{border-top:1px solid var(--line)}
|
|
177
|
-
details.ctx-section>summary{cursor:pointer;list-style:none;padding:11px 0;
|
|
178
|
-
font-weight:600;font-size:1rem;letter-spacing:-.01em;display:flex;gap:9px}
|
|
179
|
-
details.ctx-section>summary::-webkit-details-marker{display:none}
|
|
180
|
-
details.ctx-section>summary::before{content:"›";color:var(--accent);font-weight:700;
|
|
181
|
-
transition:transform .15s ease}
|
|
182
|
-
details.ctx-section[open]>summary::before{transform:rotate(90deg)}
|
|
183
|
-
details.ctx-section>.md{padding:0 0 16px}
|
|
184
|
-
@media print{
|
|
185
|
-
.ctx-nav{display:none}
|
|
186
|
-
details.ctx-section:not([open])>.md{display:block!important}
|
|
187
|
-
details.ctx-section>summary::before{content:""}
|
|
188
|
-
}
|
|
189
|
-
.md h1,.md h2,.md h3,.md h4{margin:22px 0 8px;font-size:1rem;letter-spacing:-.01em}
|
|
190
|
-
.md h1{font-size:1.15rem}
|
|
191
|
-
.md p{margin:8px 0}
|
|
192
|
-
.md ul,.md ol{margin:8px 0;padding-left:22px}
|
|
193
|
-
.md li{margin:3px 0}
|
|
194
|
-
.md code{background:var(--chip);padding:1px 5px;border-radius:5px;
|
|
195
|
-
font:.86em ui-monospace,SFMono-Regular,Menlo,monospace}
|
|
196
|
-
.md pre{background:var(--chip);padding:14px 16px;border-radius:9px;overflow:auto}
|
|
197
|
-
.md pre code{background:none;padding:0}
|
|
198
|
-
.md table{border-collapse:collapse;width:100%;margin:12px 0;font-size:.88rem;display:block;overflow:auto}
|
|
199
|
-
.md th,.md td{border:1px solid var(--line);padding:6px 10px;text-align:left}
|
|
200
|
-
.md blockquote{margin:10px 0;padding-left:14px;border-left:3px solid var(--line);color:var(--muted)}
|
|
201
|
-
.md a{color:var(--accent)}
|
|
202
|
-
.fact{padding:12px 0;border-bottom:1px solid var(--line)}
|
|
203
|
-
.fact:last-child{border-bottom:0}
|
|
204
|
-
.fact p{margin:0 0 7px}
|
|
205
|
-
.meta{display:flex;flex-wrap:wrap;gap:6px;align-items:center}
|
|
206
|
-
.tag{font-size:.72rem;padding:2px 8px;border-radius:5px;background:var(--chip);color:var(--muted)}
|
|
207
|
-
.dot{width:7px;height:7px;border-radius:50%;background:var(--accent);display:inline-block}
|
|
208
|
-
.dot.pending{background:var(--muted)}
|
|
209
|
-
.disc{width:100%;border-collapse:collapse;font-size:.84rem}
|
|
210
|
-
.disc th,.disc td{text-align:left;padding:6px 10px;border-bottom:1px solid var(--line)}
|
|
211
|
-
.disc th{color:var(--muted);font-weight:600}
|
|
212
|
-
.disc code{font:.86em ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--muted)}
|
|
213
|
-
.fetch{margin:14px 0 0;font-size:.82rem;color:var(--muted)}
|
|
214
|
-
.fetch code{background:var(--chip);padding:1px 5px;border-radius:5px}
|
|
215
|
-
.none{color:var(--muted);font-style:italic}
|
|
216
|
-
`;
|
|
217
|
-
const htmlAttr = (theme) => theme === "auto" ? "" : ` data-theme="${theme}"`;
|
|
218
24
|
/** What the front calls this thing, from where it runs: "MCP server", "A2A agent", or both. */
|
|
219
25
|
export function cardKind(id) {
|
|
220
26
|
const kinds = [];
|
|
@@ -229,28 +35,6 @@ export function cardKind(id) {
|
|
|
229
35
|
export function cardTitle(id) {
|
|
230
36
|
return [cardKind(id).join(" · "), id?.agentVersion ? `v${id.agentVersion}` : ""].filter(Boolean).join(" · ");
|
|
231
37
|
}
|
|
232
|
-
/** The front's logo: the first letters of the name's first two words ("mcp-context-card" → "MC"). */
|
|
233
|
-
/** Words that say what kind of thing it is, not whose: never the logo ("mcp-context-card" → C, not M). */
|
|
234
|
-
const GENERIC_WORDS = new Set(["mcp", "server", "servers", "sdk", "agent", "agents", "api", "cli", "app", "tool", "tools", "plugin", "core", "the"]);
|
|
235
|
-
/** Names whose two-letter mark is obvious. */
|
|
236
|
-
const OBVIOUS_MARKS = { github: "GH", gitlab: "GL", typescript: "TS", javascript: "JS" };
|
|
237
|
-
/**
|
|
238
|
-
* The front's logo: the first letter of the name's first meaningful word
|
|
239
|
-
* (generic words like "mcp", "server", "sdk" skipped), plus a second letter
|
|
240
|
-
* only when it's obvious: a known name (github → GH, typescript → TS) or a
|
|
241
|
-
* word written with two capitals (GitHub, TypeScript). Never more than two.
|
|
242
|
-
*/
|
|
243
|
-
export function cardInitials(name) {
|
|
244
|
-
const words = name.split(/[^\p{L}\p{N}]+/u).filter(Boolean);
|
|
245
|
-
const first = words.find((w) => !GENERIC_WORDS.has(w.toLowerCase())) ?? words[0] ?? "";
|
|
246
|
-
const known = OBVIOUS_MARKS[first.toLowerCase()];
|
|
247
|
-
if (known)
|
|
248
|
-
return known;
|
|
249
|
-
const capitals = first.match(/\p{Lu}/gu) ?? [];
|
|
250
|
-
if (capitals.length === 2 && /^\p{Lu}/u.test(first) && /\p{Ll}/u.test(first))
|
|
251
|
-
return capitals.join("");
|
|
252
|
-
return (Array.from(first)[0] ?? "").toUpperCase();
|
|
253
|
-
}
|
|
254
38
|
/** The front's one-liner: the first sentence of the description. */
|
|
255
39
|
export function cardOneLiner(id, max = 140) {
|
|
256
40
|
const d = id?.description;
|
|
@@ -384,110 +168,6 @@ export function readCard(root, opts = {}) {
|
|
|
384
168
|
...(id?.accent ? { accent: id.accent } : {}),
|
|
385
169
|
};
|
|
386
170
|
}
|
|
387
|
-
/** Draw any business card as one self-contained HTML page. */
|
|
388
|
-
export function renderBusinessCard(card, opts = {}) {
|
|
389
|
-
const theme = opts.theme ?? "auto";
|
|
390
|
-
const accent = safeAccent(opts.accent) ?? safeAccent(card.accent);
|
|
391
|
-
const portrait = opts.layout === "portrait";
|
|
392
|
-
const flat = !!opts.expanded;
|
|
393
|
-
const { name, title, oneLiner, domain } = card;
|
|
394
|
-
const tabs = card.tabs.map((t) => ({ ...t, key: t.key.replace(/[^a-z0-9-]/gi, "").toLowerCase() || "tab" }));
|
|
395
|
-
const pills = card.chips
|
|
396
|
-
.map((c) => `<span class="pill${c.accent ? " accent" : ""}">${escapeHtml(c.text)}</span>`)
|
|
397
|
-
.join("");
|
|
398
|
-
const radios = tabs
|
|
399
|
-
.map((t, i) => `<input type="radio" name="tab" id="t-${t.key}" class="sr"${i === 0 ? " checked" : ""}>`)
|
|
400
|
-
.join("");
|
|
401
|
-
const tabbar = tabs.map((t) => `<label for="t-${t.key}">${escapeHtml(t.label)}</label>`).join("");
|
|
402
|
-
const panes = tabs
|
|
403
|
-
.map((t) => `<div class="pane p-${t.key}"><p class="label">${escapeHtml(t.heading)}</p>${t.html}</div>`)
|
|
404
|
-
.join("");
|
|
405
|
-
// One CSS rule pair per tab: its pane shows, its label lights, when its radio is checked.
|
|
406
|
-
const tabCss = tabs
|
|
407
|
-
.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)}`)
|
|
408
|
-
.join("");
|
|
409
|
-
// The (i) panel: the same control, in the same spot, on both faces.
|
|
410
|
-
const WHATIS = `<details class="whatis">
|
|
411
|
-
<summary class="corner tr" title="About this card" aria-label="About this card">i</summary>
|
|
412
|
-
<div class="whatis-panel">
|
|
413
|
-
${card.about}
|
|
414
|
-
</div>
|
|
415
|
-
</details>`;
|
|
416
|
-
return `<!doctype html>
|
|
417
|
-
<html lang="en">
|
|
418
|
-
<head>
|
|
419
|
-
<meta charset="utf-8">
|
|
420
|
-
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
421
|
-
<title>${escapeHtml(name)} — business card</title>
|
|
422
|
-
<style>${CSS(accent)}${accent ? "" : INK_CSS}${tabCss}</style>
|
|
423
|
-
</head>
|
|
424
|
-
<body${flat ? ` class="flat"` : ""}${htmlAttr(theme)}>
|
|
425
|
-
<input type="checkbox" id="flip" class="sr" aria-label="Flip the card">
|
|
426
|
-
<input type="checkbox" id="ink" class="sr" aria-label="Switch the card between light and dark">
|
|
427
|
-
<input type="checkbox" id="portrait" class="sr" aria-label="Portrait view"${portrait ? " checked" : ""}>
|
|
428
|
-
<div class="stage">
|
|
429
|
-
<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>
|
|
430
|
-
<main class="bcard">
|
|
431
|
-
<div class="faces">
|
|
432
|
-
<section class="face front">
|
|
433
|
-
<div class="logo" aria-hidden="true">${escapeHtml(cardInitials(name))}</div>
|
|
434
|
-
${WHATIS}
|
|
435
|
-
<div class="id">
|
|
436
|
-
<h1>${escapeHtml(name)}</h1>
|
|
437
|
-
${title ? `<p class="title">${escapeHtml(title)}</p>` : ""}
|
|
438
|
-
${oneLiner ? `<p class="oneliner">${escapeHtml(oneLiner)}</p>` : ""}
|
|
439
|
-
</div>
|
|
440
|
-
<div class="foot-front">${domain ? `<span class="domain">${escapeHtml(domain)}</span>` : ""}${pills ? `<div class="pills">${pills}</div>` : ""}</div>
|
|
441
|
-
<label for="flip" class="flipbtn" data-tip="Flip the card" aria-label="Flip the card"><span aria-hidden="true">↻</span></label>
|
|
442
|
-
</section>
|
|
443
|
-
<section class="face back">
|
|
444
|
-
${radios}
|
|
445
|
-
${WHATIS}
|
|
446
|
-
<div class="tabbar">${tabbar}</div>
|
|
447
|
-
<div class="panes">${panes}</div>
|
|
448
|
-
<label for="flip" class="flipbtn back-btn" data-tip="Flip back" aria-label="Flip back"><span aria-hidden="true">↺</span></label>
|
|
449
|
-
</section>
|
|
450
|
-
</div>
|
|
451
|
-
</main>
|
|
452
|
-
<p class="hint">${escapeHtml(name)} · business card · <label for="flip">flip it over</label></p>
|
|
453
|
-
</div>
|
|
454
|
-
${CARD_SCRIPT}
|
|
455
|
-
</body>
|
|
456
|
-
</html>
|
|
457
|
-
`;
|
|
458
|
-
}
|
|
459
|
-
/**
|
|
460
|
-
* The card's only script — a progressive enhancement. Flip, tabs and the view
|
|
461
|
-
* toggle are CSS (checkbox and radio inputs) and work without it. It adds:
|
|
462
|
-
* Expand all / Collapse all for the context sections, opening the section a
|
|
463
|
-
* `#hash` names (flipping to the back and its Context tab first), and opening
|
|
464
|
-
* every section for printing (browsers disagree on printing a closed
|
|
465
|
-
* `<details>`).
|
|
466
|
-
*/
|
|
467
|
-
const CARD_SCRIPT = `<script>
|
|
468
|
-
(function(){
|
|
469
|
-
var secs=[].slice.call(document.querySelectorAll("details.ctx-section"));
|
|
470
|
-
var btn=document.querySelector(".xall");
|
|
471
|
-
var sync=function(){if(btn)btn.textContent=secs.every(function(d){return d.open})?"Collapse all":"Expand all"};
|
|
472
|
-
if(btn&&secs.length){
|
|
473
|
-
btn.hidden=false;
|
|
474
|
-
btn.addEventListener("click",function(){var open=!secs.every(function(d){return d.open});secs.forEach(function(d){d.open=open});sync()});
|
|
475
|
-
secs.forEach(function(d){d.addEventListener("toggle",sync)});
|
|
476
|
-
}
|
|
477
|
-
var openHash=function(){
|
|
478
|
-
var d=document.getElementById(decodeURIComponent(location.hash.slice(1)));
|
|
479
|
-
if(!d||d.tagName!=="DETAILS")return;
|
|
480
|
-
var f=document.getElementById("flip"),t=document.getElementById("t-context");
|
|
481
|
-
if(f)f.checked=true;if(t)t.checked=true;d.open=true;sync();
|
|
482
|
-
setTimeout(function(){d.scrollIntoView({block:"nearest"})},620);
|
|
483
|
-
};
|
|
484
|
-
addEventListener("hashchange",openHash);openHash();
|
|
485
|
-
var pre=[];
|
|
486
|
-
addEventListener("beforeprint",function(){pre=secs.map(function(d){return d.open});secs.forEach(function(d){d.open=true})});
|
|
487
|
-
addEventListener("afterprint",function(){secs.forEach(function(d,i){d.open=pre[i]});sync()});
|
|
488
|
-
sync();
|
|
489
|
-
})();
|
|
490
|
-
</script>`;
|
|
491
171
|
const TLDR_FACTS = 5;
|
|
492
172
|
const TLDR_CHARS = 160;
|
|
493
173
|
/**
|
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.7.
|
|
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.7.
|
|
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.7.
|
|
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,7 +223,7 @@ 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.7.
|
|
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>
|
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.7.
|
|
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,7 +223,7 @@ 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.7.
|
|
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>
|
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.7.
|
|
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,7 +223,7 @@ 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.7.
|
|
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>
|
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.7.
|
|
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,7 +223,7 @@ 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.7.
|
|
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>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-context-card",
|
|
3
|
-
"version": "1.7.
|
|
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.7.
|
|
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.7.
|
|
17
|
+
"version": "1.7.1",
|
|
18
18
|
"runtimeHint": "npx",
|
|
19
19
|
"transport": {
|
|
20
20
|
"type": "stdio"
|