debank-mcp-proxy
Version:
Secure proxy client for DeBank MCP Server - connects Claude Desktop to remote DeBank MCP server
160 lines • 5.82 kB
JavaScript
/**
* DeBank MCP Proxy - Secure bridge between Claude Desktop and remote DeBank MCP server
* This proxy handles authentication and forwards requests to the remote DeBank server
*/
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { ListToolsRequestSchema, CallToolRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, ListResourceTemplatesRequestSchema, CompleteRequestSchema, InitializeRequestSchema, PingRequestSchema } from "@modelcontextprotocol/sdk/types.js";
import { config } from './config.js';
import { MCPHttpClient } from './http-client.js';
import { validateApiKey } from './auth.js';
async function startProxy() {
// Validate API key
const apiKey = process.env.DEBANK_API_KEY;
if (!apiKey) {
console.error('Error: DEBANK_API_KEY environment variable is required');
console.error('Get your API key from: https://debank-mcp-server.fly.dev/get-key');
process.exit(1);
}
// Validate the API key format (not the actual key value)
if (!validateApiKey(apiKey)) {
console.error('Error: Invalid API key format');
process.exit(1);
}
// Create a single HTTP client instance that maintains session state
// This is crucial - we need one client per STDIO session
const httpClient = new MCPHttpClient(config.remoteServerUrl, apiKey);
// Create local stdio server for Claude Desktop
const server = new Server({
name: "debank-mcp-proxy",
version: "1.0.0"
}, {
capabilities: {
tools: {},
resources: {},
prompts: {},
completion: {}
}
});
// Proxy initialize request - properly return the result structure
server.setRequestHandler(InitializeRequestSchema, async (request) => {
try {
const response = await httpClient.initialize(request.params);
return {
protocolVersion: response.protocolVersion,
capabilities: response.capabilities,
serverInfo: response.serverInfo
};
}
catch (error) {
console.error('Initialize error:', error);
throw error;
}
});
// Proxy ping requests
server.setRequestHandler(PingRequestSchema, async () => {
try {
await httpClient.ping();
return {};
}
catch (error) {
console.error('Ping error:', error);
throw error;
}
});
// Proxy list tools request
server.setRequestHandler(ListToolsRequestSchema, async (request) => {
try {
const response = await httpClient.listTools(request.params);
return response;
}
catch (error) {
console.error('List tools error:', error);
throw error;
}
});
// Proxy call tool request
server.setRequestHandler(CallToolRequestSchema, async (request) => {
try {
const response = await httpClient.callTool(request.params);
return response;
}
catch (error) {
console.error('Call tool error:', error);
throw error;
}
});
// Proxy list resources request
server.setRequestHandler(ListResourcesRequestSchema, async (request) => {
try {
const response = await httpClient.listResources(request.params);
return response;
}
catch (error) {
console.error('List resources error:', error);
throw error;
}
});
// Proxy read resource request
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
try {
const response = await httpClient.readResource(request.params);
return response;
}
catch (error) {
console.error('Read resource error:', error);
throw error;
}
});
// Proxy list prompts request
server.setRequestHandler(ListPromptsRequestSchema, async (request) => {
try {
const response = await httpClient.listPrompts(request.params);
return response;
}
catch (error) {
console.error('List prompts error:', error);
throw error;
}
});
// Proxy get prompt request
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
try {
const response = await httpClient.getPrompt(request.params);
return response;
}
catch (error) {
console.error('Get prompt error:', error);
throw error;
}
});
// Proxy list resource templates request
server.setRequestHandler(ListResourceTemplatesRequestSchema, async (request) => {
try {
const response = await httpClient.listResourceTemplates(request.params);
return response;
}
catch (error) {
console.error('List resource templates error:', error);
throw error;
}
});
// Proxy completion request
server.setRequestHandler(CompleteRequestSchema, async (request) => {
try {
const response = await httpClient.complete(request.params);
return response;
}
catch (error) {
console.error('Complete error:', error);
throw error;
}
});
// Connect to stdio transport
const transport = new StdioServerTransport();
await server.connect(transport);
}
// Start the server immediately, following MCP best practices
startProxy().catch(console.error);
//# sourceMappingURL=index.js.map