auto-prompt-mcp-server
Version:
MCP server that automatically adds prompts to file submissions when no user prompt is provided
361 lines (360 loc) • 18.6 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AutoPromptServer = void 0;
var index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
var stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
var types_js_1 = require("@modelcontextprotocol/sdk/types.js");
var AutoPromptServer = /** @class */ (function () {
function AutoPromptServer() {
this.IMAGE_EXTENSIONS = new Set([
'jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg', 'webp'
]);
this.CODE_EXTENSIONS = new Set([
'js', 'ts', 'jsx', 'tsx', 'py', 'java', 'cpp', 'c', 'cs', 'php', 'rb', 'go',
'rs', 'swift', 'kt', 'scala', 'html', 'css', 'scss', 'sass', 'vue', 'svelte'
]);
this.DATA_EXTENSIONS = new Set([
'csv', 'json', 'xml', 'xlsx', 'xls', 'sql'
]);
this.server = new index_js_1.Server({
name: 'auto-prompt-server',
version: '1.0.0',
capabilities: {
tools: {},
},
});
// Default configuration - can be overridden via environment variables
this.config = {
defaultPrompt: process.env.AUTO_PROMPT_DEFAULT || 'Please analyze this file and provide insights.',
filePrompt: process.env.AUTO_PROMPT_FILE || 'What can you tell me about this file?',
imagePrompt: process.env.AUTO_PROMPT_IMAGE || 'Describe this image and its contents.',
codePrompt: process.env.AUTO_PROMPT_CODE || 'Review this code and explain what it does.',
dataPrompt: process.env.AUTO_PROMPT_DATA || 'Analyze this data and summarize key findings.',
};
this.setupHandlers();
}
AutoPromptServer.prototype.validateProcessFileSubmissionArgs = function (args) {
if (typeof args !== 'object' || args === null) {
throw new Error('Invalid arguments: expected object');
}
var obj = args;
if (!Array.isArray(obj.files)) {
throw new Error('Invalid arguments: files must be an array');
}
// Validate each file in the array
for (var _i = 0, _a = obj.files; _i < _a.length; _i++) {
var file = _a[_i];
if (typeof file !== 'object' || file === null) {
throw new Error('Invalid file: each file must be an object');
}
var fileObj = file;
if (typeof fileObj.name !== 'string' || typeof fileObj.content !== 'string') {
throw new Error('Invalid file: name and content must be strings');
}
}
return {
files: obj.files,
userPrompt: typeof obj.userPrompt === 'string' ? obj.userPrompt : undefined,
promptType: typeof obj.promptType === 'string' ? obj.promptType : undefined,
};
};
AutoPromptServer.prototype.validateConfigurePromptsArgs = function (args) {
if (typeof args !== 'object' || args === null) {
throw new Error('Invalid arguments: expected object');
}
return args;
};
AutoPromptServer.prototype.setupHandlers = function () {
var _this = this;
this.server.setRequestHandler(types_js_1.ListToolsRequestSchema, function () { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2 /*return*/, ({
tools: [
{
name: 'process_file_submission',
description: 'Processes file submissions and adds appropriate prompts when none are provided',
inputSchema: {
type: 'object',
properties: {
files: {
type: 'array',
items: {
type: 'object',
properties: {
name: { type: 'string' },
content: { type: 'string' },
mimeType: { type: 'string' },
size: { type: 'number' }
},
required: ['name', 'content']
}
},
userPrompt: {
type: 'string',
description: 'Optional user prompt - if provided, no auto-prompt will be added'
},
promptType: {
type: 'string',
enum: ['default', 'file', 'image', 'code', 'data'],
description: 'Type of auto-prompt to use if no user prompt provided'
}
},
required: ['files']
}
},
{
name: 'configure_prompts',
description: 'Configure the default prompts used for different file types',
inputSchema: {
type: 'object',
properties: {
defaultPrompt: { type: 'string' },
filePrompt: { type: 'string' },
imagePrompt: { type: 'string' },
codePrompt: { type: 'string' },
dataPrompt: { type: 'string' }
}
}
},
{
name: 'get_configuration',
description: 'Get current prompt configuration',
inputSchema: {
type: 'object',
properties: {}
}
}
],
})];
});
}); });
this.server.setRequestHandler(types_js_1.CallToolRequestSchema, function (request) { return __awaiter(_this, void 0, void 0, function () {
var _a, name, args, _b, error_1, errorMessage;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
_a = request.params, name = _a.name, args = _a.arguments;
_c.label = 1;
case 1:
_c.trys.push([1, 10, , 11]);
_b = name;
switch (_b) {
case 'process_file_submission': return [3 /*break*/, 2];
case 'configure_prompts': return [3 /*break*/, 4];
case 'get_configuration': return [3 /*break*/, 6];
}
return [3 /*break*/, 8];
case 2: return [4 /*yield*/, this.processFileSubmission(this.validateProcessFileSubmissionArgs(args))];
case 3: return [2 /*return*/, _c.sent()];
case 4: return [4 /*yield*/, this.configurePrompts(this.validateConfigurePromptsArgs(args))];
case 5: return [2 /*return*/, _c.sent()];
case 6: return [4 /*yield*/, this.getConfiguration()];
case 7: return [2 /*return*/, _c.sent()];
case 8: throw new Error("Unknown tool: ".concat(name));
case 9: return [3 /*break*/, 11];
case 10:
error_1 = _c.sent();
errorMessage = error_1 instanceof Error ? error_1.message : 'Unknown error occurred';
return [2 /*return*/, {
content: [
{
type: 'text',
text: "Error: ".concat(errorMessage),
},
],
isError: true,
}];
case 11: return [2 /*return*/];
}
});
}); });
};
AutoPromptServer.prototype.processFileSubmission = function (args) {
return __awaiter(this, void 0, void 0, function () {
var files, userPrompt, _a, promptType, autoPrompt, filesList;
return __generator(this, function (_b) {
files = args.files, userPrompt = args.userPrompt, _a = args.promptType, promptType = _a === void 0 ? 'default' : _a;
if (!files || !Array.isArray(files) || files.length === 0) {
throw new Error('No files provided');
}
// If user provided a prompt, don't add auto-prompt
if (userPrompt && userPrompt.trim()) {
return [2 /*return*/, {
content: [
{
type: 'text',
text: "User prompt detected: \"".concat(userPrompt, "\"\nNo auto-prompt added. Processing ").concat(files.length, " file(s) with user's prompt."),
},
],
}];
}
autoPrompt = this.selectAutoPrompt(files, promptType);
filesList = files.map(function (file) { return "- ".concat(file.name, " (").concat(file.mimeType || 'unknown type', ")"); }).join('\n');
return [2 /*return*/, {
content: [
{
type: 'text',
text: "No user prompt detected. Auto-prompt added: \"".concat(autoPrompt, "\"\n\nFiles submitted:\n").concat(filesList, "\n\nProcessing with auto-prompt..."),
},
],
}];
});
});
};
AutoPromptServer.prototype.selectAutoPrompt = function (files, promptType) {
// If specific prompt type requested, use it
if (promptType !== 'default') {
var promptKey = "".concat(promptType, "Prompt");
return this.config[promptKey] || this.config.defaultPrompt;
}
// Auto-detect based on file types
var fileExtensions = files.map(function (file) {
var ext = file.name.toLowerCase().split('.').pop();
return ext || '';
});
var mimeTypes = files.map(function (file) { return file.mimeType || ''; }).filter(Boolean);
// Check for images
if (this.hasImageFiles(mimeTypes, fileExtensions)) {
return this.config.imagePrompt;
}
// Check for code files
if (this.hasCodeFiles(fileExtensions)) {
return this.config.codePrompt;
}
// Check for data files
if (this.hasDataFiles(fileExtensions, mimeTypes)) {
return this.config.dataPrompt;
}
// Default for other file types
return this.config.filePrompt;
};
AutoPromptServer.prototype.hasImageFiles = function (mimeTypes, extensions) {
var _this = this;
return mimeTypes.some(function (type) { return type.startsWith('image/'); }) ||
extensions.some(function (ext) { return _this.IMAGE_EXTENSIONS.has(ext); });
};
AutoPromptServer.prototype.hasCodeFiles = function (extensions) {
var _this = this;
return extensions.some(function (ext) { return _this.CODE_EXTENSIONS.has(ext); });
};
AutoPromptServer.prototype.hasDataFiles = function (extensions, mimeTypes) {
var _this = this;
return extensions.some(function (ext) { return _this.DATA_EXTENSIONS.has(ext); }) ||
mimeTypes.some(function (type) {
return type.includes('spreadsheet') ||
type.includes('json') ||
type.includes('xml');
});
};
AutoPromptServer.prototype.configurePrompts = function (args) {
return __awaiter(this, void 0, void 0, function () {
var validKeys, updates, _i, _a, _b, key, value, configKey;
return __generator(this, function (_c) {
validKeys = ['defaultPrompt', 'filePrompt', 'imagePrompt', 'codePrompt', 'dataPrompt'];
updates = [];
for (_i = 0, _a = Object.entries(args); _i < _a.length; _i++) {
_b = _a[_i], key = _b[0], value = _b[1];
if (validKeys.includes(key) && typeof value === 'string' && value.trim()) {
configKey = key;
this.config[configKey] = value.trim();
updates.push("".concat(key, ": \"").concat(value.trim(), "\""));
}
}
if (updates.length === 0) {
throw new Error('No valid prompt configurations provided');
}
return [2 /*return*/, {
content: [
{
type: 'text',
text: "Prompt configuration updated:\n".concat(updates.join('\n')),
},
],
}];
});
});
};
AutoPromptServer.prototype.getConfiguration = function () {
return __awaiter(this, void 0, void 0, function () {
var configText;
return __generator(this, function (_a) {
configText = Object.entries(this.config)
.map(function (_a) {
var key = _a[0], value = _a[1];
return "".concat(key, ": \"").concat(value, "\"");
})
.join('\n');
return [2 /*return*/, {
content: [
{
type: 'text',
text: "Current prompt configuration:\n".concat(configText),
},
],
}];
});
});
};
AutoPromptServer.prototype.run = function () {
return __awaiter(this, void 0, void 0, function () {
var transport;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
transport = new stdio_js_1.StdioServerTransport();
return [4 /*yield*/, this.server.connect(transport)];
case 1:
_a.sent();
console.error('Auto-Prompt MCP server running on stdio');
return [2 /*return*/];
}
});
});
};
return AutoPromptServer;
}());
exports.AutoPromptServer = AutoPromptServer;
// Run the server
var isMainModule = process.argv[1] && process.argv[1].endsWith('server.js');
if (isMainModule) {
var server = new AutoPromptServer();
server.run().catch(console.error);
}
exports.default = AutoPromptServer;