Skip to main content
Glama
run-mcp-scenario.js5.23 kB
#!/usr/bin/env node /* End-to-end MCP tool scenario for ACF using JSON-RPC over stdio. - Starts MCP server bound to the demo workspace - Exercises core, filesystem, terminal, search/edit, and browser tools (headless) */ const { spawn } = require('child_process'); const path = require('path'); const fs = require('fs'); const ROOT = path.resolve(__dirname, '..'); const WORKSPACE = path.join(ROOT, 'workspaces', 'acf-demo'); const SERVER = path.join(ROOT, 'bin', 'agentic-control-framework-mcp'); if (!fs.existsSync(WORKSPACE)) { fs.mkdirSync(WORKSPACE, { recursive: true }); } const proc = spawn('node', [SERVER, '--workspaceRoot', WORKSPACE], { cwd: ROOT, stdio: ['pipe', 'pipe', 'pipe'], env: { ...process.env, ACF_PATH: ROOT, WORKSPACE_ROOT: WORKSPACE, ALLOWED_DIRS: `${WORKSPACE}:/tmp`, READONLY_MODE: 'false', BROWSER_HEADLESS: 'true' } }); proc.stderr.on('data', (d) => { // log server diagnostics to stderr process.stderr.write(d); }); let id = 0; function req(method, params = {}) { id += 1; const message = JSON.stringify({ jsonrpc: '2.0', id, method, params }) + '\n'; proc.stdin.write(message); return new Promise((resolve, reject) => { const onData = (chunk) => { const lines = chunk.toString().split('\n').filter(Boolean); for (const line of lines) { try { const obj = JSON.parse(line); if (obj.id === id) { proc.stdout.off('data', onData); resolve(obj); return; } } catch (_) { // ignore partial lines } } }; proc.stdout.on('data', onData); setTimeout(() => reject(new Error(`Timeout waiting for response to ${method}`)), 20000); }); } function unwrapCall(res) { // tools/call returns {result: {content: [{text}]}} if (res && res.result && Array.isArray(res.result.content)) { const t = res.result.content.find((c) => c.type === 'text'); if (t) { try { return JSON.parse(t.text); } catch { return { raw: t.text }; } } } return res.result; } async function main() { console.log(`[MCP] Workspace: ${WORKSPACE}`); // Initialize await req('initialize', { protocolVersion: '2024-11-05' }); // notifications/initialized is a notification; no response expected proc.stdin.write(JSON.stringify({ jsonrpc: '2.0', method: 'notifications/initialized', params: {} }) + '\n'); // Tools list const tools = await req('tools/list'); console.log(`[MCP] tools/list count=${tools.result.tools.length}`); // Workspace + project console.log('[MCP] setWorkspace'); console.log(unwrapCall(await req('tools/call', { name: 'setWorkspace', arguments: { workspacePath: WORKSPACE } }))); console.log('[MCP] initProject'); console.log(unwrapCall(await req('tools/call', { name: 'initProject', arguments: { projectName: 'ACF Demo', projectDescription: 'MCP scenario' } }))); // Filesystem const demoDir = path.join(WORKSPACE, 'mcp-demo'); const demoFile = path.join(demoDir, 'hello.txt'); console.log('[MCP] create_directory'); console.log(unwrapCall(await req('tools/call', { name: 'create_directory', arguments: { path: demoDir } }))); console.log('[MCP] write_file'); console.log(unwrapCall(await req('tools/call', { name: 'write_file', arguments: { path: demoFile, content: 'hello from mcp' } }))); console.log('[MCP] read_file'); console.log(unwrapCall(await req('tools/call', { name: 'read_file', arguments: { path: demoFile } }))); console.log('[MCP] list_directory'); console.log(unwrapCall(await req('tools/call', { name: 'list_directory', arguments: { path: WORKSPACE } }))); // Terminal console.log('[MCP] execute_command'); console.log(unwrapCall(await req('tools/call', { name: 'execute_command', arguments: { command: 'echo ACF_OK', timeout: 2000 } }))); // Search & Edit console.log('[MCP] search_code'); console.log(unwrapCall(await req('tools/call', { name: 'search_code', arguments: { query: 'ACF Demo', path: WORKSPACE, case_sensitive: false } }))); console.log('[MCP] edit_block'); const indexHtml = path.join(WORKSPACE, 'index.html'); if (fs.existsSync(indexHtml)) { console.log(unwrapCall(await req('tools/call', { name: 'edit_block', arguments: { file_path: indexHtml, old_string: 'ACF Demo Workspace', new_string: 'ACF MCP Demo Workspace', expected_replacements: 1 } }))); } else { console.log({ skip: 'index.html not found' }); } // Browser (headless, local file URL) console.log('[MCP] browser_navigate to file URL'); const fileUrl = 'file://' + indexHtml; console.log(unwrapCall(await req('tools/call', { name: 'browser_navigate', arguments: { url: fileUrl } }))); console.log('[MCP] browser_tab_list'); console.log(unwrapCall(await req('tools/call', { name: 'browser_tab_list', arguments: { random_string: 'x' } }))); console.log('[MCP] browser_resize 800x600'); console.log(unwrapCall(await req('tools/call', { name: 'browser_resize', arguments: { width: 800, height: 600 } }))); console.log('[MCP] Completed scenario'); proc.kill('SIGTERM'); } main().catch((err) => { console.error('[MCP] Scenario error:', err.message); try { proc.kill('SIGTERM'); } catch {} process.exit(1); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/FutureAtoms/agentic-control-framework'

If you have feedback or need assistance with the MCP directory API, please join our Discord server