mirror of
https://github.com/run-llama/mcp-server-llamacloud.git
synced 2026-06-30 20:47:54 -04:00
add lint and prettier
This commit is contained in:
@@ -0,0 +1,6 @@
|
|||||||
|
node_modules/
|
||||||
|
build/
|
||||||
|
lib/
|
||||||
|
dist/
|
||||||
|
pnpm-lock.yaml
|
||||||
|
package-lock.json
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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/**"],
|
||||||
|
},
|
||||||
|
);
|
||||||
Generated
+1622
-4
File diff suppressed because it is too large
Load Diff
+12
-2
@@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export default {
|
||||||
|
plugins: ["prettier-plugin-organize-imports"],
|
||||||
|
};
|
||||||
+45
-23
@@ -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}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user