@pyxmate/memory 1.0.1 → 1.1.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/cli/pyx-mem.mjs +92 -7
- package/package.json +1 -1
package/dist/cli/pyx-mem.mjs
CHANGED
|
@@ -563,9 +563,91 @@ function createReadCredentials(providerFactory) {
|
|
|
563
563
|
};
|
|
564
564
|
}
|
|
565
565
|
|
|
566
|
+
// src/mcp/proxy-server.ts
|
|
567
|
+
import { Client as McpClient } from "@modelcontextprotocol/sdk/client/index.js";
|
|
568
|
+
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
569
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
570
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
571
|
+
import {
|
|
572
|
+
CallToolRequestSchema,
|
|
573
|
+
GetPromptRequestSchema,
|
|
574
|
+
ListPromptsRequestSchema,
|
|
575
|
+
ListToolsRequestSchema
|
|
576
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
577
|
+
var REMOTE_MCP_PATH = "/mcp";
|
|
578
|
+
function createProxyServer(client, version) {
|
|
579
|
+
const caps = client.getServerCapabilities();
|
|
580
|
+
const server = new Server(client.getServerVersion() ?? { name: "pyx-memory", version }, {
|
|
581
|
+
capabilities: {
|
|
582
|
+
// Advertise the PRESENCE of tools/prompts, but NOT their `listChanged`
|
|
583
|
+
// sub-capability: this proxy does not relay the remote's list_changed
|
|
584
|
+
// notifications, so claiming listChanged would be a capability the host
|
|
585
|
+
// could rely on but we never honor (Codex: keep the proxy transparent).
|
|
586
|
+
...caps?.tools ? { tools: {} } : {},
|
|
587
|
+
...caps?.prompts ? { prompts: {} } : {}
|
|
588
|
+
},
|
|
589
|
+
instructions: client.getInstructions()
|
|
590
|
+
});
|
|
591
|
+
if (caps?.tools) {
|
|
592
|
+
server.setRequestHandler(
|
|
593
|
+
ListToolsRequestSchema,
|
|
594
|
+
(req) => client.listTools(req.params)
|
|
595
|
+
);
|
|
596
|
+
server.setRequestHandler(
|
|
597
|
+
CallToolRequestSchema,
|
|
598
|
+
(req) => client.callTool(req.params)
|
|
599
|
+
);
|
|
600
|
+
}
|
|
601
|
+
if (caps?.prompts) {
|
|
602
|
+
server.setRequestHandler(
|
|
603
|
+
ListPromptsRequestSchema,
|
|
604
|
+
(req) => client.listPrompts(req.params)
|
|
605
|
+
);
|
|
606
|
+
server.setRequestHandler(
|
|
607
|
+
GetPromptRequestSchema,
|
|
608
|
+
(req) => client.getPrompt(req.params)
|
|
609
|
+
);
|
|
610
|
+
}
|
|
611
|
+
return server;
|
|
612
|
+
}
|
|
613
|
+
async function runMcpProxyServer(opts) {
|
|
614
|
+
const version = opts.version ?? (true ? "1.1.0" : "0.0.0-dev");
|
|
615
|
+
const read = await opts.readCredentials();
|
|
616
|
+
if (!read.ok) {
|
|
617
|
+
const text = read.result.content.map((c) => c.type === "text" ? c.text : "").join(" ").trim();
|
|
618
|
+
throw new Error(text || "pyx-memory credentials are unavailable. Run: pyx-mem login");
|
|
619
|
+
}
|
|
620
|
+
const { endpoint, apiKey } = read.credentials;
|
|
621
|
+
const url = new URL(`${endpoint.replace(/\/+$/, "")}${REMOTE_MCP_PATH}`);
|
|
622
|
+
const client = new McpClient({ name: "pyx-mem-proxy", version }, { capabilities: {} });
|
|
623
|
+
const clientTransport = new StreamableHTTPClientTransport(url, {
|
|
624
|
+
requestInit: { headers: { Authorization: `Bearer ${apiKey}` } }
|
|
625
|
+
});
|
|
626
|
+
try {
|
|
627
|
+
await client.connect(clientTransport);
|
|
628
|
+
} catch (err) {
|
|
629
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
630
|
+
throw new Error(
|
|
631
|
+
`Could not reach the pyx-memory remote MCP at ${url.href}: ${msg}. Verify the endpoint and key with \`pyx-mem doctor\`, or run the bundled server with \`pyx-mem mcp\`.`
|
|
632
|
+
);
|
|
633
|
+
}
|
|
634
|
+
try {
|
|
635
|
+
const server = createProxyServer(client, version);
|
|
636
|
+
const transport = new StdioServerTransport();
|
|
637
|
+
const closed = new Promise((resolve3) => {
|
|
638
|
+
transport.onclose = () => resolve3();
|
|
639
|
+
});
|
|
640
|
+
await server.connect(transport);
|
|
641
|
+
await closed;
|
|
642
|
+
} finally {
|
|
643
|
+
await client.close().catch(() => {
|
|
644
|
+
});
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
|
|
566
648
|
// src/mcp/server.ts
|
|
567
649
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
568
|
-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
650
|
+
import { StdioServerTransport as StdioServerTransport2 } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
569
651
|
|
|
570
652
|
// src/mcp/prompts/index.ts
|
|
571
653
|
import { z } from "zod";
|
|
@@ -1377,7 +1459,7 @@ var ALL_TOOL_NAMES = ALL_TOOLS.map((t) => t.name);
|
|
|
1377
1459
|
// src/mcp/server.ts
|
|
1378
1460
|
async function runMcpServer(opts) {
|
|
1379
1461
|
const fetchImpl = opts.fetchImpl ?? fetch;
|
|
1380
|
-
const version = opts.version ?? (true ? "1.0
|
|
1462
|
+
const version = opts.version ?? (true ? "1.1.0" : "0.0.0-dev");
|
|
1381
1463
|
const server = new McpServer(
|
|
1382
1464
|
{ name: "pyx-memory", version },
|
|
1383
1465
|
{ instructions: PYX_MEMORY_INSTRUCTIONS, capabilities: { tools: {}, prompts: {} } }
|
|
@@ -1396,7 +1478,7 @@ async function runMcpServer(opts) {
|
|
|
1396
1478
|
for (const prompt of ALL_PROMPTS) {
|
|
1397
1479
|
prompt.register(server);
|
|
1398
1480
|
}
|
|
1399
|
-
const transport = new
|
|
1481
|
+
const transport = new StdioServerTransport2();
|
|
1400
1482
|
const closed = new Promise((resolve3) => {
|
|
1401
1483
|
transport.onclose = () => resolve3();
|
|
1402
1484
|
});
|
|
@@ -1405,14 +1487,15 @@ async function runMcpServer(opts) {
|
|
|
1405
1487
|
}
|
|
1406
1488
|
|
|
1407
1489
|
// src/cli/commands/mcp.ts
|
|
1408
|
-
async function mcpCommand() {
|
|
1490
|
+
async function mcpCommand(opts = {}) {
|
|
1409
1491
|
const readCredentials = createReadCredentials(() => getDefaultKeychain());
|
|
1410
1492
|
const onStdinEnd = new Promise((resolve3) => {
|
|
1411
1493
|
process.stdin.once("end", resolve3);
|
|
1412
1494
|
process.stdin.once("close", resolve3);
|
|
1413
1495
|
});
|
|
1414
1496
|
try {
|
|
1415
|
-
|
|
1497
|
+
const run = opts.remote ? runMcpProxyServer({ readCredentials }) : runMcpServer({ readCredentials });
|
|
1498
|
+
await Promise.race([run, onStdinEnd]);
|
|
1416
1499
|
return EXIT.OK;
|
|
1417
1500
|
} catch (err) {
|
|
1418
1501
|
process.stderr.write(`Internal error: ${err instanceof Error ? err.message : String(err)}
|
|
@@ -2101,7 +2184,9 @@ Commands:
|
|
|
2101
2184
|
logout Delete stored pyx-memory credentials.
|
|
2102
2185
|
doctor [--json] Diagnose keychain, credentials, backend, MCP startup.
|
|
2103
2186
|
scaffold [--name <dir>] Generate Docker, env, SDK, and memory design-guide starter files.
|
|
2104
|
-
mcp
|
|
2187
|
+
mcp [--remote] Start stdio MCP server. --remote proxies to the hosted
|
|
2188
|
+
server so tools + instructions stay server-owned
|
|
2189
|
+
(zero-touch updates; key stays in the keychain).
|
|
2105
2190
|
mcp install <target> [--scope user|local|project]
|
|
2106
2191
|
Install pyx-memory MCP config for your AI agent.
|
|
2107
2192
|
Targets: claude-code, codex, cursor, cline, continue, windsurf, gemini-cli, pi, oh-my-pi, openclaw, hermes.
|
|
@@ -2183,7 +2268,7 @@ function runMcpInstall(target, scope) {
|
|
|
2183
2268
|
return handler({ scope });
|
|
2184
2269
|
}
|
|
2185
2270
|
function runMcpCommand(parsed) {
|
|
2186
|
-
if (parsed.subcommand === void 0) return mcpCommand();
|
|
2271
|
+
if (parsed.subcommand === void 0) return mcpCommand({ remote: parsed.flags.remote === true });
|
|
2187
2272
|
if (parsed.subcommand === "install") {
|
|
2188
2273
|
const target = parsed.positional[0];
|
|
2189
2274
|
const scope = typeof parsed.flags.scope === "string" ? parsed.flags.scope : void 0;
|