chore: Update environment configuration and package dependencies for MCP server
- Change MCP_SERVER in .env.example to use port 7123 - Add USE_STDIO_TRANSPORT flag in .env.example for stdio transport mode - Update bun.lock to include new dependencies: cors, express, ajv, and their type definitions - Add new scripts for building and running the MCP server with stdio transport - Introduce PUBLISHING.md for npm publishing guidelines - Enhance README with detailed setup instructions and tool descriptions
This commit is contained in:
84
bin/mcp-stdio.cjs
Executable file
84
bin/mcp-stdio.cjs
Executable file
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const dotenv = require('dotenv');
|
||||
|
||||
/**
|
||||
* MCP Server - Stdio Transport Mode (CommonJS)
|
||||
*
|
||||
* This is the CommonJS entry point for running the MCP server via NPX in stdio mode.
|
||||
* It will directly load the stdio-server.js file which is optimized for the CLI usage.
|
||||
*/
|
||||
|
||||
// Set environment variable for stdio transport
|
||||
process.env.USE_STDIO_TRANSPORT = 'true';
|
||||
|
||||
// Load environment variables from .env file (if exists)
|
||||
try {
|
||||
const envPath = path.resolve(process.cwd(), '.env');
|
||||
if (fs.existsSync(envPath)) {
|
||||
dotenv.config({ path: envPath });
|
||||
} else {
|
||||
// Load .env.example if it exists
|
||||
const examplePath = path.resolve(process.cwd(), '.env.example');
|
||||
if (fs.existsSync(examplePath)) {
|
||||
dotenv.config({ path: examplePath });
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// Silent error handling
|
||||
}
|
||||
|
||||
// Ensure logs directory exists
|
||||
try {
|
||||
const logsDir = path.join(process.cwd(), 'logs');
|
||||
if (!fs.existsSync(logsDir)) {
|
||||
fs.mkdirSync(logsDir, { recursive: true });
|
||||
}
|
||||
} catch (error) {
|
||||
// Silent error handling
|
||||
}
|
||||
|
||||
// Try to load the server
|
||||
try {
|
||||
// Check for simplified stdio server build first (preferred for CLI usage)
|
||||
const stdioServerPath = path.resolve(__dirname, '../dist/stdio-server.js');
|
||||
|
||||
if (fs.existsSync(stdioServerPath)) {
|
||||
// If we're running in Node.js (not Bun), we need to handle ESM imports differently
|
||||
if (typeof Bun === 'undefined') {
|
||||
// Use dynamic import for ESM modules in CommonJS
|
||||
import(stdioServerPath).catch((err) => {
|
||||
console.error('Failed to import stdio server:', err.message);
|
||||
process.exit(1);
|
||||
});
|
||||
} else {
|
||||
// In Bun, we can directly require the module
|
||||
require(stdioServerPath);
|
||||
}
|
||||
} else {
|
||||
// Fall back to full server if available
|
||||
const fullServerPath = path.resolve(__dirname, '../dist/index.js');
|
||||
|
||||
if (fs.existsSync(fullServerPath)) {
|
||||
console.warn('Warning: stdio-server.js not found, falling back to index.js');
|
||||
console.warn('For optimal CLI performance, build with "npm run build:stdio"');
|
||||
|
||||
if (typeof Bun === 'undefined') {
|
||||
import(fullServerPath).catch((err) => {
|
||||
console.error('Failed to import server:', err.message);
|
||||
process.exit(1);
|
||||
});
|
||||
} else {
|
||||
require(fullServerPath);
|
||||
}
|
||||
} else {
|
||||
console.error('Error: No server implementation found. Please build the project first.');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error starting server:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
41
bin/mcp-stdio.js
Executable file
41
bin/mcp-stdio.js
Executable file
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* MCP Server - Stdio Transport Mode
|
||||
*
|
||||
* This is the entry point for running the MCP server via NPX in stdio mode.
|
||||
* It automatically configures the server to use JSON-RPC 2.0 over stdin/stdout.
|
||||
*/
|
||||
|
||||
// Set environment variables for stdio transport
|
||||
process.env.USE_STDIO_TRANSPORT = 'true';
|
||||
|
||||
// Import and run the MCP server from the compiled output
|
||||
try {
|
||||
// First make sure required directories exist
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// Ensure logs directory exists
|
||||
const logsDir = path.join(process.cwd(), 'logs');
|
||||
if (!fs.existsSync(logsDir)) {
|
||||
console.error('Creating logs directory...');
|
||||
fs.mkdirSync(logsDir, { recursive: true });
|
||||
}
|
||||
|
||||
// Get the entry module path
|
||||
const entryPath = require.resolve('../dist/index.js');
|
||||
|
||||
// Print initial message to stderr
|
||||
console.error('Starting MCP server in stdio transport mode...');
|
||||
console.error('Logs will be written to the logs/ directory');
|
||||
console.error('Communication will use JSON-RPC 2.0 format via stdin/stdout');
|
||||
|
||||
// Run the server
|
||||
require(entryPath);
|
||||
} catch (error) {
|
||||
console.error('Failed to start MCP server:', error.message);
|
||||
console.error('If this is your first run, you may need to build the project first:');
|
||||
console.error(' npm run build');
|
||||
process.exit(1);
|
||||
}
|
||||
83
bin/npx-entry.cjs
Executable file
83
bin/npx-entry.cjs
Executable file
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { spawn } = require('child_process');
|
||||
|
||||
// Set environment variable - enable stdio transport and silence output
|
||||
process.env.USE_STDIO_TRANSPORT = 'true';
|
||||
process.env.LOG_LEVEL = 'silent';
|
||||
|
||||
// Ensure logs directory exists
|
||||
const logsDir = path.join(process.cwd(), 'logs');
|
||||
if (!fs.existsSync(logsDir)) {
|
||||
fs.mkdirSync(logsDir, { recursive: true });
|
||||
}
|
||||
|
||||
// Check if .env exists, create from example if not
|
||||
const envPath = path.join(process.cwd(), '.env');
|
||||
const envExamplePath = path.join(process.cwd(), '.env.example');
|
||||
|
||||
if (!fs.existsSync(envPath) && fs.existsSync(envExamplePath)) {
|
||||
fs.copyFileSync(envExamplePath, envPath);
|
||||
}
|
||||
|
||||
// Start the MCP server with redirected stderr
|
||||
try {
|
||||
// Use our silent-mcp.sh script if it exists, otherwise use mcp-stdio.cjs
|
||||
const silentScriptPath = path.join(process.cwd(), 'silent-mcp.sh');
|
||||
|
||||
if (fs.existsSync(silentScriptPath) && fs.statSync(silentScriptPath).isFile()) {
|
||||
// Execute the silent-mcp.sh script instead
|
||||
const childProcess = spawn('/bin/bash', [silentScriptPath], {
|
||||
stdio: ['inherit', 'inherit', 'ignore'], // Redirect stderr to /dev/null
|
||||
});
|
||||
|
||||
childProcess.on('error', (err) => {
|
||||
console.error('Failed to start server:', err.message);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
// Properly handle process termination
|
||||
process.on('SIGINT', () => {
|
||||
childProcess.kill('SIGINT');
|
||||
});
|
||||
|
||||
process.on('SIGTERM', () => {
|
||||
childProcess.kill('SIGTERM');
|
||||
});
|
||||
} else {
|
||||
// Fall back to original method if silent-mcp.sh doesn't exist
|
||||
const scriptPath = path.join(__dirname, 'mcp-stdio.cjs');
|
||||
|
||||
// Use 'pipe' for stdout and ignore (null) for stderr
|
||||
const childProcess = spawn('node', [scriptPath], {
|
||||
stdio: ['inherit', 'pipe', 'ignore'], // Redirect stderr to /dev/null
|
||||
env: {
|
||||
...process.env,
|
||||
USE_STDIO_TRANSPORT: 'true',
|
||||
LOG_LEVEL: 'silent'
|
||||
}
|
||||
});
|
||||
|
||||
// Pipe child's stdout to parent's stdout
|
||||
childProcess.stdout.pipe(process.stdout);
|
||||
|
||||
childProcess.on('error', (err) => {
|
||||
console.error('Failed to start server:', err.message);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
// Properly handle process termination
|
||||
process.on('SIGINT', () => {
|
||||
childProcess.kill('SIGINT');
|
||||
});
|
||||
|
||||
process.on('SIGTERM', () => {
|
||||
childProcess.kill('SIGTERM');
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error starting server:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
62
bin/test-stdio.js
Executable file
62
bin/test-stdio.js
Executable file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Test script for MCP stdio transport
|
||||
*
|
||||
* This script sends JSON-RPC 2.0 requests to the MCP server
|
||||
* running in stdio mode and displays the responses.
|
||||
*
|
||||
* Usage: node test-stdio.js | node bin/mcp-stdio.cjs
|
||||
*/
|
||||
|
||||
// Send a ping request
|
||||
const pingRequest = {
|
||||
jsonrpc: "2.0",
|
||||
id: 1,
|
||||
method: "ping"
|
||||
};
|
||||
|
||||
// Send an info request
|
||||
const infoRequest = {
|
||||
jsonrpc: "2.0",
|
||||
id: 2,
|
||||
method: "info"
|
||||
};
|
||||
|
||||
// Send an echo request
|
||||
const echoRequest = {
|
||||
jsonrpc: "2.0",
|
||||
id: 3,
|
||||
method: "echo",
|
||||
params: {
|
||||
message: "Hello, MCP!",
|
||||
timestamp: new Date().toISOString(),
|
||||
test: true,
|
||||
count: 42
|
||||
}
|
||||
};
|
||||
|
||||
// Send the requests with a delay between them
|
||||
setTimeout(() => {
|
||||
console.log(JSON.stringify(pingRequest));
|
||||
}, 500);
|
||||
|
||||
setTimeout(() => {
|
||||
console.log(JSON.stringify(infoRequest));
|
||||
}, 1000);
|
||||
|
||||
setTimeout(() => {
|
||||
console.log(JSON.stringify(echoRequest));
|
||||
}, 1500);
|
||||
|
||||
// Process responses
|
||||
process.stdin.on('data', (data) => {
|
||||
try {
|
||||
const response = JSON.parse(data.toString());
|
||||
console.error('Received response:');
|
||||
console.error(JSON.stringify(response, null, 2));
|
||||
} catch (error) {
|
||||
console.error('Error parsing response:', error);
|
||||
console.error('Raw data:', data.toString());
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user