add lint and prettier

This commit is contained in:
Marcus Schiesser
2025-03-23 17:40:32 +02:00
parent 127e82c918
commit 4f58a95cbb
7 changed files with 1741 additions and 45 deletions
+6
View File
@@ -0,0 +1,6 @@
node_modules/
build/
lib/
dist/
pnpm-lock.yaml
package-lock.json
+13 -2
View File
@@ -9,6 +9,7 @@ This is a TypeScript-based MCP server that creates multiple tools, each connecte
## Features ## Features
### Tools ### Tools
- Creates a separate tool for each index you define - Creates a separate tool for each index you define
- Each tool provides a `query` parameter to search its specific index - Each tool provides a `query` parameter to search its specific index
- Auto-generates tool names like `get_information_index_name` based on index names - Auto-generates tool names like `get_information_index_name` based on index names
@@ -16,16 +17,19 @@ This is a TypeScript-based MCP server that creates multiple tools, each connecte
## Development ## Development
Install dependencies: Install dependencies:
```bash ```bash
npm install npm install
``` ```
Build the server: Build the server:
```bash ```bash
npm run build npm run build
``` ```
For development with auto-rebuild: For development with auto-rebuild:
```bash ```bash
npm run watch npm run watch
``` ```
@@ -44,8 +48,14 @@ On Windows: `%APPDATA%/Claude/claude_desktop_config.json`
"command": "node", "command": "node",
"args": [ "args": [
"/path/to/llamacloud/build/index.js", "/path/to/llamacloud/build/index.js",
"--index", "10k-SEC-Tesla", "--description", "10k SEC documents from 2023 for Tesla", "--index",
"--index", "10k-SEC-Apple", "--description", "10k SEC documents from 2023 for Apple" "10k-SEC-Tesla",
"--description",
"10k SEC documents from 2023 for Tesla",
"--index",
"10k-SEC-Apple",
"--description",
"10k SEC documents from 2023 for Apple"
], ],
"env": { "env": {
"LLAMA_CLOUD_PROJECT_NAME": "<YOUR_PROJECT_NAME>", "LLAMA_CLOUD_PROJECT_NAME": "<YOUR_PROJECT_NAME>",
@@ -71,6 +81,7 @@ node build/index.js --index "10k-SEC-Tesla" --description "10k SEC documents fro
``` ```
This will create two tools: This will create two tools:
1. `get_information_10k_sec_tesla` - For querying the 10k-SEC-Tesla index 1. `get_information_10k_sec_tesla` - For querying the 10k-SEC-Tesla index
2. `get_information_10k_sec_apple` - For querying the 10k-SEC-Apple index 2. `get_information_10k_sec_apple` - For querying the 10k-SEC-Apple index
+26
View File
@@ -0,0 +1,26 @@
// @ts-check
import eslint from "@eslint/js";
import eslintConfigPrettier from "eslint-config-prettier";
import globals from "globals";
import tseslint from "typescript-eslint";
export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.recommended,
eslintConfigPrettier,
{
// Node.js specific language options
languageOptions: {
ecmaVersion: 2022,
sourceType: "module",
globals: {
...globals.node,
},
},
},
{
// Files to ignore
ignores: ["**/build/**", "**/node_modules/**"],
},
);
+1622 -4
View File
File diff suppressed because it is too large Load Diff
+12 -2
View File
@@ -16,14 +16,24 @@
"build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"", "build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"",
"prepare": "npm run build", "prepare": "npm run build",
"watch": "tsc --watch", "watch": "tsc --watch",
"inspector": "npx @modelcontextprotocol/inspector build/index.js" "inspector": "npx @modelcontextprotocol/inspector build/index.js",
"format": "prettier --ignore-unknown --cache --check .",
"format:write": "prettier --ignore-unknown --write .",
"lint": "eslint . --ext .ts,.js,.mjs --fix"
}, },
"dependencies": { "dependencies": {
"@modelcontextprotocol/sdk": "^1.7.0", "@modelcontextprotocol/sdk": "^1.7.0",
"llamaindex": "^0.9.11" "llamaindex": "^0.9.11"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.22.0",
"@types/node": "^22.9.3", "@types/node": "^22.9.3",
"typescript": "^5.6.2" "eslint": "^9.22.0",
"eslint-config-prettier": "^9.1.0",
"globals": "^15.12.0",
"prettier": "^3.4.2",
"prettier-plugin-organize-imports": "^4.1.0",
"typescript": "^5.6.2",
"typescript-eslint": "^8.18.0"
} }
} }
+3
View File
@@ -0,0 +1,3 @@
export default {
plugins: ["prettier-plugin-organize-imports"],
};
+45 -23
View File
@@ -7,11 +7,11 @@
import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { LlamaCloudIndex, MetadataMode } from 'llamaindex';
import { import {
CallToolRequestSchema, CallToolRequestSchema,
ListToolsRequestSchema, ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js"; } from "@modelcontextprotocol/sdk/types.js";
import { LlamaCloudIndex, MetadataMode } from "llamaindex";
// Define the tool definition interface // Define the tool definition interface
interface ToolDefinition { interface ToolDefinition {
@@ -24,7 +24,9 @@ interface ToolDefinition {
function parseToolDefinitions(): ToolDefinition[] { function parseToolDefinitions(): ToolDefinition[] {
const args = process.argv.slice(2); const args = process.argv.slice(2);
if (args.length === 0) { if (args.length === 0) {
console.error('No tool definitions provided. Use format: --index "IndexName" --description "Description"'); console.error(
'No tool definitions provided. Use format: --index "IndexName" --description "Description"',
);
process.exit(1); process.exit(1);
} }
@@ -32,19 +34,23 @@ function parseToolDefinitions(): ToolDefinition[] {
let currentIndexName: string | null = null; let currentIndexName: string | null = null;
for (let i = 0; i < args.length; i++) { for (let i = 0; i < args.length; i++) {
if (args[i] === '--index' && i + 1 < args.length) { if (args[i] === "--index" && i + 1 < args.length) {
// Save the current index name. We'll wait for the description to complete the definition // Save the current index name. We'll wait for the description to complete the definition
currentIndexName = args[i + 1].trim(); currentIndexName = args[i + 1].trim();
i++; // Skip the next argument since we consumed it i++; // Skip the next argument since we consumed it
} else if (args[i] === '--description' && i + 1 < args.length && currentIndexName) { } else if (
args[i] === "--description" &&
i + 1 < args.length &&
currentIndexName
) {
// We have both an index name and a description, so we can create a tool definition // We have both an index name and a description, so we can create a tool definition
const description = args[i + 1].trim(); const description = args[i + 1].trim();
const toolName = `get_information_${currentIndexName.toLowerCase().replace(/[^a-z0-9]/g, '_')}`; const toolName = `get_information_${currentIndexName.toLowerCase().replace(/[^a-z0-9]/g, "_")}`;
toolDefinitions.push({ toolDefinitions.push({
indexName: currentIndexName, indexName: currentIndexName,
description, description,
toolName toolName,
}); });
// Reset for the next pair // Reset for the next pair
@@ -55,11 +61,15 @@ function parseToolDefinitions(): ToolDefinition[] {
// Check if we have an index without a description at the end // Check if we have an index without a description at the end
if (currentIndexName) { if (currentIndexName) {
console.warn(`Warning: Index '${currentIndexName}' was specified without a description.`); console.warn(
`Warning: Index '${currentIndexName}' was specified without a description.`,
);
} }
if (toolDefinitions.length === 0) { if (toolDefinitions.length === 0) {
console.error('No valid tool definitions found. Use format: --index "IndexName" --description "Description"'); console.error(
'No valid tool definitions found. Use format: --index "IndexName" --description "Description"',
);
process.exit(1); process.exit(1);
} }
@@ -78,12 +88,20 @@ const server = new Server(
capabilities: { capabilities: {
tools: {}, tools: {},
}, },
} },
); );
// Get the project name and API key from environment variables // Get the project name and API key from environment variables
const projectName = process.env.LLAMA_CLOUD_PROJECT_NAME || (() => { throw new Error('LLAMA_CLOUD_PROJECT_NAME is not set') })(); const projectName =
const apiKey = process.env.LLAMA_CLOUD_API_KEY || (() => { throw new Error('LLAMA_CLOUD_API_KEY is not set') })(); process.env.LLAMA_CLOUD_PROJECT_NAME ||
(() => {
throw new Error("LLAMA_CLOUD_PROJECT_NAME is not set");
})();
const apiKey =
process.env.LLAMA_CLOUD_API_KEY ||
(() => {
throw new Error("LLAMA_CLOUD_API_KEY is not set");
})();
// Parse tool definitions from command line arguments // Parse tool definitions from command line arguments
const toolDefinitions = parseToolDefinitions(); const toolDefinitions = parseToolDefinitions();
@@ -99,7 +117,9 @@ for (const definition of toolDefinitions) {
}); });
indexes.set(definition.toolName!, index); indexes.set(definition.toolName!, index);
console.log(`Created index for tool ${definition.toolName}: ${definition.indexName} - ${definition.description}`); console.log(
`Created index for tool ${definition.toolName}: ${definition.indexName} - ${definition.description}`,
);
} }
/** /**
@@ -108,7 +128,7 @@ for (const definition of toolDefinitions) {
*/ */
server.setRequestHandler(ListToolsRequestSchema, async () => { server.setRequestHandler(ListToolsRequestSchema, async () => {
return { return {
tools: toolDefinitions.map(definition => ({ tools: toolDefinitions.map((definition) => ({
name: definition.toolName!, name: definition.toolName!,
description: `Get information from the ${definition.indexName} index. The index contains ${definition.description}`, description: `Get information from the ${definition.indexName} index. The index contains ${definition.description}`,
inputSchema: { inputSchema: {
@@ -116,12 +136,12 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
properties: { properties: {
query: { query: {
type: "string", type: "string",
description: `The query used to get information from the ${definition.indexName} index.` description: `The query used to get information from the ${definition.indexName} index.`,
}, },
}, },
required: ["query"] required: ["query"],
} },
})) })),
}; };
}); });
@@ -146,25 +166,27 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
const nodesWithScore = await retriever.retrieve({ query }); const nodesWithScore = await retriever.retrieve({ query });
const nodes = nodesWithScore.map((node) => node.node); const nodes = nodesWithScore.map((node) => node.node);
const context = nodes.map((r) => r.getContent(MetadataMode.NONE)).join("\n\n"); const context = nodes
.map((r) => r.getContent(MetadataMode.NONE))
.join("\n\n");
return { return {
content: [{ content: [
{
type: "text", type: "text",
text: context, text: context,
}] },
],
}; };
}); });
/** /**
* Start the server using stdio transport. * Start the server using stdio transport.
* This allows the server to communicate via standard input/output streams. * This allows the server to communicate via standard input/output streams.
*/ */
async function main() { async function main() {
console.log(`Starting MCP server with ${toolDefinitions.length} tools:`); console.log(`Starting MCP server with ${toolDefinitions.length} tools:`);
toolDefinitions.forEach(def => { toolDefinitions.forEach((def) => {
console.log(`- ${def.toolName}: ${def.indexName} - ${def.description}`); console.log(`- ${def.toolName}: ${def.indexName} - ${def.description}`);
}); });