Targetprocess MCP Server
by aaronsb
Verified
- src
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ErrorCode,
ListToolsRequestSchema,
McpError,
} from '@modelcontextprotocol/sdk/types.js';
import fs from 'fs';
import path from 'path';
import { TPService, TPServiceConfig } from './api/client/tp.service.js';
import { SearchTool } from './tools/search/search.tool.js';
import { GetEntityTool } from './tools/entity/get.tool.js';
import { CreateEntityTool } from './tools/entity/create.tool.js';
import { UpdateEntityTool } from './tools/update/update.tool.js';
import { InspectObjectTool } from './tools/inspect/inspect.tool.js';
function loadConfig(): TPServiceConfig {
// Try environment variables first
if (process.env.TP_DOMAIN && process.env.TP_USERNAME && process.env.TP_PASSWORD) {
return {
domain: process.env.TP_DOMAIN,
credentials: {
username: process.env.TP_USERNAME,
password: process.env.TP_PASSWORD
}
};
}
// Fall back to config file
const configPath = path.join(process.cwd(), 'config', 'targetprocess.json');
if (!fs.existsSync(configPath)) {
console.error('No configuration found. Please set environment variables (TP_DOMAIN, TP_USERNAME, TP_PASSWORD) or create config/targetprocess.json');
throw new McpError(
ErrorCode.InternalError,
'No configuration found. Please set environment variables (TP_DOMAIN, TP_USERNAME, TP_PASSWORD) or create config/targetprocess.json'
);
}
try {
return JSON.parse(fs.readFileSync(configPath, 'utf8'));
} catch (error) {
console.error(`Error parsing config file: ${error instanceof Error ? error.message : String(error)}`);
throw new McpError(
ErrorCode.InternalError,
`Error parsing config file: ${error instanceof Error ? error.message : String(error)}`
);
}
}
export class TargetProcessServer {
private server: Server;
private service: TPService;
private tools: {
search: SearchTool;
get: GetEntityTool;
create: CreateEntityTool;
update: UpdateEntityTool;
inspect: InspectObjectTool;
};
constructor() {
// Initialize service
const config = loadConfig();
this.service = new TPService(config);
// Initialize tools
this.tools = {
search: new SearchTool(this.service),
get: new GetEntityTool(this.service),
create: new CreateEntityTool(this.service),
update: new UpdateEntityTool(this.service),
inspect: new InspectObjectTool(this.service)
};
// Initialize server
this.server = new Server(
{
name: 'target-process-server',
version: '0.1.0',
},
{
capabilities: {
tools: {
search_entities: true,
get_entity: true,
create_entity: true,
update_entity: true,
inspect_object: true
},
},
}
);
this.setupHandlers();
// Error handling
this.server.onerror = (error) => console.error('[MCP Error]', error);
process.on('SIGINT', async () => {
await this.server.close();
process.exit(0);
});
// Initialize entity type cache in the background
this.initializeCache();
}
/**
* Initialize caches in the background to improve first-request performance
*/
private async initializeCache(): Promise<void> {
try {
// Initialize entity type cache
await this.service.initializeEntityTypeCache();
} catch (error) {
console.error('Cache initialization error:', error);
// Non-fatal error, server can still function
}
}
private setupHandlers() {
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
SearchTool.getDefinition(),
GetEntityTool.getDefinition(),
CreateEntityTool.getDefinition(),
UpdateEntityTool.getDefinition(),
InspectObjectTool.getDefinition(),
],
}));
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
try {
switch (request.params.name) {
case 'search_entities':
return await this.tools.search.execute(request.params.arguments);
case 'get_entity':
return await this.tools.get.execute(request.params.arguments);
case 'create_entity':
return await this.tools.create.execute(request.params.arguments);
case 'update_entity':
return await this.tools.update.execute(request.params.arguments);
case 'inspect_object':
return await this.tools.inspect.execute(request.params.arguments);
default:
throw new McpError(
ErrorCode.MethodNotFound,
`Unknown tool: ${request.params.name}`
);
}
} catch (error) {
if (error instanceof McpError) {
throw error;
}
return {
content: [
{
type: 'text',
text: `Target Process API error: ${error instanceof Error ? error.message : String(error)}`,
},
],
isError: true,
};
}
});
}
async run() {
const transport = new StdioServerTransport();
await this.server.connect(transport);
const timestamp = new Date().toISOString();
console.error(`Target Process MCP server running on stdio (started at ${timestamp})`);
}
}