@nyuchi/mzizi-mcp 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api-client.d.ts +86 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +179 -0
- package/dist/api-client.js.map +1 -0
- package/dist/http.js +1 -1
- package/dist/http.js.map +1 -1
- package/dist/server.d.ts +24 -26
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +52 -709
- package/dist/server.js.map +1 -1
- package/dist/stdio.js +1 -1
- package/dist/stdio.js.map +1 -1
- package/dist/tools.d.ts +30 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +307 -0
- package/dist/tools.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client for the Mzizi API — the MCP's only data source.
|
|
3
|
+
*
|
|
4
|
+
* The architecture: the Next.js app at mzizi.dev builds the registry from files at
|
|
5
|
+
* build time and serves it over `/api/v1/*`. This MCP is a client of that API. It does
|
|
6
|
+
* NOT talk to Supabase, and it does not hold a database credential, because component
|
|
7
|
+
* documents and doctrine are files in `nyuchi/mzizi` — not rows.
|
|
8
|
+
*
|
|
9
|
+
* What that buys, beyond matching the architecture:
|
|
10
|
+
*
|
|
11
|
+
* - One source of truth. The API and the MCP answer from the same build, so an agent
|
|
12
|
+
* over MCP and a consumer over HTTP cannot get different answers.
|
|
13
|
+
* - No credential. The previous design read `mcp_tool_registry` and dispatched to
|
|
14
|
+
* Supabase RPCs with an anon key; there is nothing to leak or rotate here.
|
|
15
|
+
* - The tool surface stops being data. It was built at startup from a table, which
|
|
16
|
+
* meant a row edit silently changed what the server exposed with no review. The
|
|
17
|
+
* tools are now code (see `tools.ts`), so a change to them is a diff.
|
|
18
|
+
*
|
|
19
|
+
* Failure policy: every method returns a discriminated result rather than throwing, so
|
|
20
|
+
* a tool can turn an upstream outage into a sentence the caller can act on. An MCP tool
|
|
21
|
+
* that throws an opaque fetch error teaches the agent nothing.
|
|
22
|
+
*/
|
|
23
|
+
export declare const DEFAULT_API_BASE = "https://mzizi.dev/api/v1";
|
|
24
|
+
export type ApiOk<T> = {
|
|
25
|
+
ok: true;
|
|
26
|
+
data: T;
|
|
27
|
+
};
|
|
28
|
+
export type ApiErr = {
|
|
29
|
+
ok: false;
|
|
30
|
+
/** Machine-readable reason, for a tool to branch on. */
|
|
31
|
+
reason: "not_found" | "timeout" | "network" | "bad_status" | "bad_body";
|
|
32
|
+
/** A sentence for the caller. Not a status code. */
|
|
33
|
+
message: string;
|
|
34
|
+
status?: number;
|
|
35
|
+
};
|
|
36
|
+
export type ApiResult<T> = ApiOk<T> | ApiErr;
|
|
37
|
+
export type MziziApiOptions = {
|
|
38
|
+
/** Base URL, no trailing slash. Defaults to the public API. */
|
|
39
|
+
baseUrl?: string;
|
|
40
|
+
timeoutMs?: number;
|
|
41
|
+
/** Injectable for tests and for a Worker's bound fetch. */
|
|
42
|
+
fetchImpl?: typeof fetch;
|
|
43
|
+
};
|
|
44
|
+
export declare class MziziApiClient {
|
|
45
|
+
private readonly baseUrl;
|
|
46
|
+
private readonly timeoutMs;
|
|
47
|
+
private readonly fetchImpl;
|
|
48
|
+
constructor(opts?: MziziApiOptions);
|
|
49
|
+
/**
|
|
50
|
+
* GET a JSON path under the API base.
|
|
51
|
+
*
|
|
52
|
+
* `path` is appended verbatim, so every caller must encode its own segments —
|
|
53
|
+
* a component name arriving from an agent is untrusted input, and an unencoded
|
|
54
|
+
* `../` would climb out of /api/v1.
|
|
55
|
+
*/
|
|
56
|
+
get<T>(path: string, query?: Record<string, string | number | undefined>): Promise<ApiResult<T>>;
|
|
57
|
+
/** Registry index. */
|
|
58
|
+
listComponents(): Promise<ApiResult<unknown>>;
|
|
59
|
+
/** One component, shadcn-shaped, with metadata and files. */
|
|
60
|
+
getComponent(name: string): Promise<ApiResult<unknown>>;
|
|
61
|
+
/** Per-component docs: use cases, variants, a11y. */
|
|
62
|
+
getComponentDocs(name: string): Promise<ApiResult<unknown>>;
|
|
63
|
+
/** Per-component version history. */
|
|
64
|
+
getComponentVersions(name: string): Promise<ApiResult<unknown>>;
|
|
65
|
+
/** Cross-resource search — components, docs, changelog. */
|
|
66
|
+
search(query: string): Promise<ApiResult<unknown>>;
|
|
67
|
+
/** The DNA double helix: nodes, rungs, strands, live counts. */
|
|
68
|
+
getArchitecture(): Promise<ApiResult<unknown>>;
|
|
69
|
+
/** One node. `n` is uncapped — the node set grows, so never bound it here. */
|
|
70
|
+
getNode(n: number): Promise<ApiResult<unknown>>;
|
|
71
|
+
/** Brand system: minerals, heritage, typography, spacing, ecosystem. */
|
|
72
|
+
getBrand(): Promise<ApiResult<unknown>>;
|
|
73
|
+
getUbuntuPillars(): Promise<ApiResult<unknown>>;
|
|
74
|
+
getUbuntuPrinciples(): Promise<ApiResult<unknown>>;
|
|
75
|
+
listAiInstructions(): Promise<ApiResult<unknown>>;
|
|
76
|
+
getAiInstructions(name: string): Promise<ApiResult<unknown>>;
|
|
77
|
+
listSkills(): Promise<ApiResult<unknown>>;
|
|
78
|
+
getSkill(name: string): Promise<ApiResult<unknown>>;
|
|
79
|
+
listChangelog(): Promise<ApiResult<unknown>>;
|
|
80
|
+
getRelease(version: string): Promise<ApiResult<unknown>>;
|
|
81
|
+
/** Live counts + usage metrics. Derived upstream, never a stored number. */
|
|
82
|
+
getStats(): Promise<ApiResult<unknown>>;
|
|
83
|
+
/** Service health. */
|
|
84
|
+
getHealth(): Promise<ApiResult<unknown>>;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=api-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,eAAO,MAAM,gBAAgB,6BAA6B,CAAA;AAK1D,MAAM,MAAM,KAAK,CAAC,CAAC,IAAI;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,CAAA;AAC5C,MAAM,MAAM,MAAM,GAAG;IACnB,EAAE,EAAE,KAAK,CAAA;IACT,wDAAwD;IACxD,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,YAAY,GAAG,UAAU,CAAA;IACvE,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AACD,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAA;AAE5C,MAAM,MAAM,eAAe,GAAG;IAC5B,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CACzB,CAAA;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;gBAE5B,IAAI,GAAE,eAAoB;IAMtC;;;;;;OAMG;IACG,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAyEtG,sBAAsB;IACtB,cAAc;IAId,6DAA6D;IAC7D,YAAY,CAAC,IAAI,EAAE,MAAM;IAIzB,qDAAqD;IACrD,gBAAgB,CAAC,IAAI,EAAE,MAAM;IAI7B,qCAAqC;IACrC,oBAAoB,CAAC,IAAI,EAAE,MAAM;IAIjC,2DAA2D;IAC3D,MAAM,CAAC,KAAK,EAAE,MAAM;IAIpB,gEAAgE;IAChE,eAAe;IAIf,8EAA8E;IAC9E,OAAO,CAAC,CAAC,EAAE,MAAM;IAIjB,wEAAwE;IACxE,QAAQ;IAIR,gBAAgB;IAIhB,mBAAmB;IAInB,kBAAkB;IAIlB,iBAAiB,CAAC,IAAI,EAAE,MAAM;IAI9B,UAAU;IAIV,QAAQ,CAAC,IAAI,EAAE,MAAM;IAIrB,aAAa;IAIb,UAAU,CAAC,OAAO,EAAE,MAAM;IAI1B,4EAA4E;IAC5E,QAAQ;IAIR,sBAAsB;IACtB,SAAS;CAGV"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client for the Mzizi API — the MCP's only data source.
|
|
3
|
+
*
|
|
4
|
+
* The architecture: the Next.js app at mzizi.dev builds the registry from files at
|
|
5
|
+
* build time and serves it over `/api/v1/*`. This MCP is a client of that API. It does
|
|
6
|
+
* NOT talk to Supabase, and it does not hold a database credential, because component
|
|
7
|
+
* documents and doctrine are files in `nyuchi/mzizi` — not rows.
|
|
8
|
+
*
|
|
9
|
+
* What that buys, beyond matching the architecture:
|
|
10
|
+
*
|
|
11
|
+
* - One source of truth. The API and the MCP answer from the same build, so an agent
|
|
12
|
+
* over MCP and a consumer over HTTP cannot get different answers.
|
|
13
|
+
* - No credential. The previous design read `mcp_tool_registry` and dispatched to
|
|
14
|
+
* Supabase RPCs with an anon key; there is nothing to leak or rotate here.
|
|
15
|
+
* - The tool surface stops being data. It was built at startup from a table, which
|
|
16
|
+
* meant a row edit silently changed what the server exposed with no review. The
|
|
17
|
+
* tools are now code (see `tools.ts`), so a change to them is a diff.
|
|
18
|
+
*
|
|
19
|
+
* Failure policy: every method returns a discriminated result rather than throwing, so
|
|
20
|
+
* a tool can turn an upstream outage into a sentence the caller can act on. An MCP tool
|
|
21
|
+
* that throws an opaque fetch error teaches the agent nothing.
|
|
22
|
+
*/
|
|
23
|
+
export const DEFAULT_API_BASE = "https://mzizi.dev/api/v1";
|
|
24
|
+
/** How long any single upstream call may take before it is abandoned. */
|
|
25
|
+
const DEFAULT_TIMEOUT_MS = 10_000;
|
|
26
|
+
export class MziziApiClient {
|
|
27
|
+
baseUrl;
|
|
28
|
+
timeoutMs;
|
|
29
|
+
fetchImpl;
|
|
30
|
+
constructor(opts = {}) {
|
|
31
|
+
this.baseUrl = (opts.baseUrl ?? DEFAULT_API_BASE).replace(/\/+$/, "");
|
|
32
|
+
this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
33
|
+
this.fetchImpl = opts.fetchImpl ?? fetch;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* GET a JSON path under the API base.
|
|
37
|
+
*
|
|
38
|
+
* `path` is appended verbatim, so every caller must encode its own segments —
|
|
39
|
+
* a component name arriving from an agent is untrusted input, and an unencoded
|
|
40
|
+
* `../` would climb out of /api/v1.
|
|
41
|
+
*/
|
|
42
|
+
async get(path, query) {
|
|
43
|
+
let url = `${this.baseUrl}${path.startsWith("/") ? path : `/${path}`}`;
|
|
44
|
+
if (query) {
|
|
45
|
+
const qs = new URLSearchParams();
|
|
46
|
+
for (const [k, v] of Object.entries(query)) {
|
|
47
|
+
if (v !== undefined && v !== "")
|
|
48
|
+
qs.set(k, String(v));
|
|
49
|
+
}
|
|
50
|
+
const s = qs.toString();
|
|
51
|
+
if (s)
|
|
52
|
+
url += `?${s}`;
|
|
53
|
+
}
|
|
54
|
+
const controller = new AbortController();
|
|
55
|
+
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
56
|
+
try {
|
|
57
|
+
const res = await this.fetchImpl(url, {
|
|
58
|
+
signal: controller.signal,
|
|
59
|
+
headers: { accept: "application/json" },
|
|
60
|
+
});
|
|
61
|
+
if (res.status === 404) {
|
|
62
|
+
return {
|
|
63
|
+
ok: false,
|
|
64
|
+
reason: "not_found",
|
|
65
|
+
status: 404,
|
|
66
|
+
message: `The Mzizi API has no record at ${path}. Check the name — list_components returns the valid set.`,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
if (!res.ok) {
|
|
70
|
+
// 503 is the API's documented "database not configured" signal. It is worth
|
|
71
|
+
// distinguishing in words, because it means the deployment is misconfigured
|
|
72
|
+
// rather than that the caller asked for something wrong.
|
|
73
|
+
const hint = res.status === 503
|
|
74
|
+
? " The API reports it is not fully configured; this is a deployment problem, not a bad request."
|
|
75
|
+
: "";
|
|
76
|
+
return {
|
|
77
|
+
ok: false,
|
|
78
|
+
reason: "bad_status",
|
|
79
|
+
status: res.status,
|
|
80
|
+
message: `The Mzizi API answered ${res.status} for ${path}.${hint}`,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
return { ok: true, data: (await res.json()) };
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return {
|
|
88
|
+
ok: false,
|
|
89
|
+
reason: "bad_body",
|
|
90
|
+
status: res.status,
|
|
91
|
+
message: `The Mzizi API returned a non-JSON body for ${path}. The endpoint may be behind a redirect or an auth gate.`,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
if (err?.name === "AbortError") {
|
|
97
|
+
return {
|
|
98
|
+
ok: false,
|
|
99
|
+
reason: "timeout",
|
|
100
|
+
message: `The Mzizi API did not respond within ${this.timeoutMs}ms for ${path}.`,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
ok: false,
|
|
105
|
+
reason: "network",
|
|
106
|
+
message: `Could not reach the Mzizi API at ${this.baseUrl}: ${err?.message ?? "unknown error"}.`,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
finally {
|
|
110
|
+
clearTimeout(timer);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// ── The endpoints the 10 tools are built from ──────────────────────
|
|
114
|
+
/** Registry index. */
|
|
115
|
+
listComponents() {
|
|
116
|
+
return this.get("/ui");
|
|
117
|
+
}
|
|
118
|
+
/** One component, shadcn-shaped, with metadata and files. */
|
|
119
|
+
getComponent(name) {
|
|
120
|
+
return this.get(`/ui/${encodeURIComponent(name)}`);
|
|
121
|
+
}
|
|
122
|
+
/** Per-component docs: use cases, variants, a11y. */
|
|
123
|
+
getComponentDocs(name) {
|
|
124
|
+
return this.get(`/ui/${encodeURIComponent(name)}/docs`);
|
|
125
|
+
}
|
|
126
|
+
/** Per-component version history. */
|
|
127
|
+
getComponentVersions(name) {
|
|
128
|
+
return this.get(`/ui/${encodeURIComponent(name)}/versions`);
|
|
129
|
+
}
|
|
130
|
+
/** Cross-resource search — components, docs, changelog. */
|
|
131
|
+
search(query) {
|
|
132
|
+
return this.get("/search", { q: query });
|
|
133
|
+
}
|
|
134
|
+
/** The DNA double helix: nodes, rungs, strands, live counts. */
|
|
135
|
+
getArchitecture() {
|
|
136
|
+
return this.get("/architecture");
|
|
137
|
+
}
|
|
138
|
+
/** One node. `n` is uncapped — the node set grows, so never bound it here. */
|
|
139
|
+
getNode(n) {
|
|
140
|
+
return this.get(`/architecture/nodes/${encodeURIComponent(String(n))}`);
|
|
141
|
+
}
|
|
142
|
+
/** Brand system: minerals, heritage, typography, spacing, ecosystem. */
|
|
143
|
+
getBrand() {
|
|
144
|
+
return this.get("/brand");
|
|
145
|
+
}
|
|
146
|
+
getUbuntuPillars() {
|
|
147
|
+
return this.get("/ubuntu/pillars");
|
|
148
|
+
}
|
|
149
|
+
getUbuntuPrinciples() {
|
|
150
|
+
return this.get("/ubuntu/principles");
|
|
151
|
+
}
|
|
152
|
+
listAiInstructions() {
|
|
153
|
+
return this.get("/ai/instructions");
|
|
154
|
+
}
|
|
155
|
+
getAiInstructions(name) {
|
|
156
|
+
return this.get(`/ai/instructions/${encodeURIComponent(name)}`);
|
|
157
|
+
}
|
|
158
|
+
listSkills() {
|
|
159
|
+
return this.get("/skills");
|
|
160
|
+
}
|
|
161
|
+
getSkill(name) {
|
|
162
|
+
return this.get(`/skills/${encodeURIComponent(name)}`);
|
|
163
|
+
}
|
|
164
|
+
listChangelog() {
|
|
165
|
+
return this.get("/changelog");
|
|
166
|
+
}
|
|
167
|
+
getRelease(version) {
|
|
168
|
+
return this.get(`/changelog/${encodeURIComponent(version)}`);
|
|
169
|
+
}
|
|
170
|
+
/** Live counts + usage metrics. Derived upstream, never a stored number. */
|
|
171
|
+
getStats() {
|
|
172
|
+
return this.get("/stats");
|
|
173
|
+
}
|
|
174
|
+
/** Service health. */
|
|
175
|
+
getHealth() {
|
|
176
|
+
return this.get("/health");
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
|
package/dist/http.js
CHANGED
|
@@ -63,7 +63,7 @@ export function createMziziHttpHandler(options = {}) {
|
|
|
63
63
|
sessionIdGenerator: undefined,
|
|
64
64
|
enableJsonResponse: true,
|
|
65
65
|
});
|
|
66
|
-
const server = await createMziziMcpServer(
|
|
66
|
+
const server = await createMziziMcpServer({ fundi: options.fundi });
|
|
67
67
|
await server.connect(transport);
|
|
68
68
|
const response = await transport.handleRequest(request);
|
|
69
69
|
return withCors(response);
|
package/dist/http.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,wCAAwC,EAAE,MAAM,+DAA+D,CAAA;AACxH,OAAO,EAAE,qBAAqB,EAA2B,MAAM,kBAAkB,CAAA;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAGlD,MAAM,YAAY,GAAG;IACnB,6BAA6B,EAAE,GAAG;IAClC,8BAA8B,EAAE,4BAA4B;IAC5D,8BAA8B,EAAE,4DAA4D;CAC7F,CAAA;AAED,SAAS,QAAQ,CAAC,QAAkB;IAClC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;IAC7C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IAChF,OAAO,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE;QACjC,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,OAAO;KACR,CAAC,CAAA;AACJ,CAAC;AAED,2EAA2E;AAC3E,0EAA0E;AAC1E,uEAAuE;AACvE,6EAA6E;AAC7E,2EAA2E;AAC3E,MAAM,wBAAwB,GAAG;IAC/B,uCAAuC;IACvC,yCAAyC;IACzC,mCAAmC;CACpC,CAAA;AAED,SAAS,oBAAoB,CAAC,QAAgB;IAC5C,OAAO,wBAAwB,CAAC,IAAI,CAClC,CAAC,MAAM,EAAE,EAAE,CAAC,QAAQ,KAAK,MAAM,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC,CACrE,CAAA;AACH,CAAC;AAYD;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,UAA8B,EAAE;IACrE,MAAM,MAAM,GAAuB,OAAO,CAAC,cAAc,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;IAE1F,OAAO,KAAK,UAAU,MAAM,CAAC,OAAgB;QAC3C,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACjC,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAA;QACnE,CAAC;QACD,2EAA2E;QAC3E,4EAA4E;QAC5E,2EAA2E;QAC3E,uEAAuE;QACvE,8DAA8D;QAC9D,IAAI,oBAAoB,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxD,OAAO,QAAQ,CAAC,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAA;QAC7D,CAAC;QACD,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,MAAM,qBAAqB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;QACzE,IAAI,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC;YAClB,OAAO,QAAQ,CACb,QAAQ,CAAC,IAAI,CACX,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,IAAI,mCAAmC,EAAE,EAChE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,IAAI,GAAG,EAAE,CACjC,CACF,CAAA;QACH,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,wCAAwC,CAAC;YAC7D,kBAAkB,EAAE,SAAS;YAC7B,kBAAkB,EAAE,IAAI;SACzB,CAAC,CAAA;QACF,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,36 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Mzizi MCP
|
|
2
|
+
* The Mzizi MCP server.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* `mcp_tool_registry` table (the same registry that powers the design system's
|
|
6
|
-
* MCP), and each tool is dispatched dynamically to its backing implementation:
|
|
4
|
+
* Backed by `mzizi.dev/api/v1` over HTTP. There is no Supabase client here.
|
|
7
5
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* WHAT CHANGED AND WHY. This server used to build its tool catalog at startup from the
|
|
7
|
+
* `mcp_tool_registry` table and dispatch each call to a Supabase RPC, edge function or
|
|
8
|
+
* table read — 62 enabled tools, defined as data. Two things were wrong with that:
|
|
11
9
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
10
|
+
* 1. Components are not rows. They are real files in `nyuchi/mzizi` that the Next.js
|
|
11
|
+
* app compiles and typechecks, so an error in one fails the build. The app serves
|
|
12
|
+
* them over `/api/v1/*`, which makes that API the source of truth and this server
|
|
13
|
+
* one of its clients. Reading the database put a second, uncompiled representation
|
|
14
|
+
* in the path — one that could disagree with the code while still looking correct.
|
|
17
15
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
16
|
+
* 2. A tool surface defined in a table changes whenever someone edits a row: no diff,
|
|
17
|
+
* no review, no test. The 10 tools live in `tools.ts` as code, so changing them is
|
|
18
|
+
* a pull request.
|
|
19
|
+
*
|
|
20
|
+
* The 10 are specified in `docs/mcp-tool-consolidation.md` (mzizi repo). Each carries its
|
|
21
|
+
* `replaces` list in `TOOL_COVERAGE`, so coverage of the old 62 is checkable rather than
|
|
22
|
+
* asserted.
|
|
22
23
|
*/
|
|
23
24
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
24
|
-
import type { SupabaseClient } from "@supabase/supabase-js";
|
|
25
25
|
import type { FundiToolContext } from "./fundi-client.js";
|
|
26
|
-
export declare const MZIZI_MCP_VERSION = "0.
|
|
27
|
-
|
|
28
|
-
* Build the Mzizi MCP server bound to a Supabase client with public read on
|
|
29
|
-
* `mcp_tool_registry` / `component_documents` and EXECUTE on the backing RPCs.
|
|
30
|
-
* The tool catalog is loaded from the registry; write-kind tools are excluded
|
|
31
|
-
* from this (anonymous, public) surface.
|
|
32
|
-
*/
|
|
33
|
-
export declare function createMziziMcpServer(supabase: SupabaseClient, opts?: {
|
|
26
|
+
export declare const MZIZI_MCP_VERSION = "0.7.0";
|
|
27
|
+
export type CreateServerOptions = {
|
|
34
28
|
fundi?: FundiToolContext;
|
|
35
|
-
|
|
29
|
+
/** Override the API base — used by tests and by a preview deployment. */
|
|
30
|
+
apiBaseUrl?: string;
|
|
31
|
+
fetchImpl?: typeof fetch;
|
|
32
|
+
};
|
|
33
|
+
export declare function createMziziMcpServer(opts?: CreateServerOptions): Promise<McpServer>;
|
|
36
34
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAEnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAIzD,eAAO,MAAM,iBAAiB,UAAU,CAAA;AAExC,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,CAAC,EAAE,gBAAgB,CAAA;IACxB,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CACzB,CAAA;AAED,wBAAsB,oBAAoB,CAAC,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,SAAS,CAAC,CA+D7F"}
|