LibreChat/e2e/setup/fake-mcp-server.js
Danny Avila d8427ffc5e
🛂 test: Cover Tool Approval Workflows End to End (#14427)
* test: cover tool approval workflows end to end

* fix: preserve tool approval state across resume

* fix: preserve agent context in mock stream responses

* fix: preserve nested approvals in collapsed groups
2026-07-26 21:58:25 -04:00

109 lines
2.5 KiB
JavaScript

#!/usr/bin/env node
const fs = require('node:fs');
const path = require('node:path');
const { McpServer } = require('@modelcontextprotocol/sdk/server/mcp.js');
const { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js');
const z = require('zod/v4');
const APPROVAL_AUDIT_DIR = path.join('/tmp', 'librechat-e2e-approval-audit');
function recordApprovalInvocation(value) {
fs.mkdirSync(APPROVAL_AUDIT_DIR, { recursive: true });
const filename = Buffer.from(value).toString('base64url');
fs.appendFileSync(path.join(APPROVAL_AUDIT_DIR, filename), `${value}\n`);
}
const server = new McpServer({
name: 'e2e-memory',
version: '1.0.0',
});
server.registerTool(
'remember_fact',
{
description: 'Stores a deterministic fact for LibreChat mock end-to-end tests.',
inputSchema: {
fact: z.string().optional(),
},
},
async ({ fact = 'LibreChat MCP e2e fact' }) => ({
content: [
{
type: 'text',
text: `E2E MCP memory noted: ${fact}`,
},
],
}),
);
server.registerTool(
'recall_fact',
{
description: 'Returns a deterministic fact for LibreChat mock end-to-end tests.',
inputSchema: {},
},
async () => ({
content: [
{
type: 'text',
text: 'E2E MCP memory recalled: LibreChat can persist MCP tools on agents.',
},
],
}),
);
server.registerTool(
'slow_echo',
{
description:
'Echoes text after a delay; used to verify background tool dispatch in mock e2e tests.',
inputSchema: {
text: z.string(),
delay_ms: z.number().optional(),
},
},
async ({ text, delay_ms = 1500 }) => {
await new Promise((resolve) => setTimeout(resolve, delay_ms));
return {
content: [
{
type: 'text',
text: `E2E slow echo: ${text}`,
},
],
};
},
);
server.registerTool(
'approval_probe',
{
description:
'Echoes reviewed input so LibreChat mock end-to-end tests can verify tool approval decisions.',
inputSchema: {
value: z.string(),
review: z.string().optional(),
},
},
async ({ value }) => {
recordApprovalInvocation(value);
return {
content: [
{
type: 'text',
text: `E2E approval probe executed: ${value}`,
},
],
};
},
);
async function main() {
await server.connect(new StdioServerTransport());
}
main().catch((error) => {
console.error('[fake-mcp-server] failed to start', error);
process.exit(1);
});