@ayga/mcp-client 2.0.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,189 +1,229 @@
1
- # Ayga MCP Client (Node.js)
2
-
3
- Modern, lightweight MCP client for Redis API with **40 AI parsers** across **9 categories**.
4
-
5
- ## 🚀 Quick Start
6
-
7
- ### Install via npx (recommended)
8
-
9
- ```bash
10
- npx @ayga/mcp-client
11
- ```
12
-
13
- ### VS Code Copilot Configuration
14
-
15
- Add to `%APPDATA%\Code\User\mcp.json`:
16
-
17
- ```json
18
- {
19
- "inputs": [
20
- {
21
- "id": "REDIS_API_KEY",
22
- "type": "promptString",
23
- "description": "ayga-mcp-client Redis API key",
24
- "password": true
25
- }
26
- ],
27
- "servers": {
28
- "ayga": {
29
- "type": "stdio",
30
- "command": "npx",
31
- "args": ["@ayga/mcp-client@latest"],
32
- "env": {
33
- "REDIS_API_KEY": "${input:REDIS_API_KEY}"
34
- }
35
- }
36
- }
37
- }
38
- ```
39
-
40
- ### Claude Desktop Configuration
41
-
42
- Add to `%APPDATA%\Claude\claude_desktop_config.json`:
43
-
44
- ```json
45
- {
46
- "mcpServers": {
47
- "ayga": {
48
- "command": "npx",
49
- "args": ["@ayga/mcp-client@latest"],
50
- "env": {
51
- "REDIS_API_KEY": "your-api-key-here"
52
- }
53
- }
54
- }
55
- }
56
- ```
57
-
58
- ## 📦 Available Parsers (40 total)
59
-
60
- ### AI Chat (8)
61
- - `search_perplexity` - Perplexity AI with sources
62
- - `search_chatgpt` - ChatGPT with web search
63
- - `search_claude` - Anthropic Claude
64
- - `search_gemini` - Google Gemini
65
- - `search_copilot` - Microsoft Copilot
66
- - `search_grok` - xAI Grok
67
- - `search_deepseek` - DeepSeek AI
68
- - `search_deepai` - DeepAI
69
-
70
- ### Search Engines (8)
71
- - `search_google_search` - Google Search
72
- - `search_bing_search` - Bing Search
73
- - `search_duckduckgo` - DuckDuckGo
74
- - `search_yahoo_search` - Yahoo Search
75
- - `search_yandex_search` - Yandex Search
76
- - `search_baidu_search` - Baidu Search
77
- - `search_rambler_search` - Rambler Search
78
- - `search_you_search` - You.com
79
-
80
- ### Instagram (4)
81
- - `search_instagram_profile` - User profiles
82
- - `search_instagram_post` - Individual posts
83
- - `search_instagram_tag` - Hashtag pages
84
- - `search_instagram_geo` - Location pages
85
-
86
- ### TikTok (1)
87
- - `search_tiktok_profile` - User profiles and videos
88
-
89
- ### YouTube (5)
90
- - `search_youtube_search` - Search videos
91
- - `search_youtube_video` - Video details
92
- - `search_youtube_comments` - Video comments
93
- - `search_youtube_channel_videos` - Channel videos
94
- - `search_youtube_channel_about` - Channel info
95
-
96
- ### Google Trends (1)
97
- - `search_google_trends` - Trends data
98
-
99
- ### Pinterest (1)
100
- - `search_pinterest_search` - Search pins
101
-
102
- ### Reddit (2)
103
- - `search_reddit_posts` - Search posts
104
- - `search_reddit_comments` - Post comments
105
-
106
- ### Translation (3)
107
- - `search_google_translate` - Google Translate
108
- - `search_bing_translate` - Bing Translator
109
- - `search_yandex_translate` - Yandex Translator
110
-
111
- ### HTML Content (3)
112
- - `search_link_extractor` - Extract links
113
- - `search_article_extractor` - Extract articles (Mozilla Readability)
114
- - `search_text_extractor` - Extract text content
115
-
116
- ## 💡 Usage Examples
117
-
118
- ### In Claude Desktop/VS Code
119
-
120
- ```
121
- @ayga list_parsers
122
- @ayga search_perplexity query="What is MCP protocol?"
123
- @ayga search_google_trends query="AI trends 2026"
124
- @ayga search_youtube_search query="Python tutorials" timeout=90
125
- @ayga search_google_translate query="Hello world"
126
- ```
127
-
128
- ### Command Line
129
-
130
- ```bash
131
- # Set API key
132
- export REDIS_API_KEY="your-api-key"
133
-
134
- # Run server
135
- npx @ayga/mcp-client
136
- ```
137
-
138
- ## 🏗️ Architecture
139
-
140
- ```
141
- ┌─────────────────────────────────────┐
142
- │ VS Code / Claude Desktop │
143
- └─────────────┬───────────────────────┘
144
- │ MCP stdio
145
- ┌─────────────▼───────────────────────┐
146
- │ @ayga/mcp-client (Node.js) │
147
- │ - 40 parsers │
148
- │ - MCP protocol │
149
- │ - JWT authentication │
150
- └─────────────┬───────────────────────┘
151
- │ HTTPS REST API
152
- ┌─────────────▼───────────────────────┐
153
- │ redis_wrapper (Python/FastAPI) │
154
- │ https://redis.ayga.tech │
155
- └─────────────┬───────────────────────┘
156
- Redis Queue
157
- ┌─────────────▼───────────────────────┐
158
- │ A-Parser (Windows) │
159
- └─────────────────────────────────────┘
160
- ```
161
-
162
- ## 🔑 Getting API Key
163
-
164
- 1. Visit https://redis.ayga.tech
165
- 2. Sign up or log in
166
- 3. Generate API key
167
- 4. Use in configuration
168
-
169
- ## 🆚 vs Python Version
170
-
171
- | Feature | Node.js (2.0.0) | Python (1.4.1) |
172
- | ---------------- | ---------------------- | ---------------------------- |
173
- | **Installation** | `npx @ayga/mcp-client` | `uvx ayga-mcp-client==1.4.1` |
174
- | **Startup** | ~50-100ms | ~716ms |
175
- | **Dependencies** | MCP SDK only | mcp, httpx, pydantic |
176
- | **Size** | ~500 lines | ~1200 lines |
177
- | **Runtime** | Node.js 18+ | Python 3.11+ |
178
- | **Parsers** | ✅ All 40 | ✅ All 40 |
179
-
180
- ## 📄 License
181
-
182
- MIT
183
-
184
- ## 🔗 Links
185
-
186
- - **API Backend**: https://redis.ayga.tech
187
- - **Python Version**: https://pypi.org/project/ayga-mcp-client/
188
- - **GitHub**: https://github.com/ozand/ayga-mcp-nodejs
189
- - **Issues**: https://github.com/ozand/ayga-mcp-nodejs/issues
1
+ # Ayga MCP Client (Node.js) v3.0.0
2
+
3
+ Modern, lightweight MCP client with **6 consolidated AI tools** - optimized for LLM context windows.
4
+
5
+ ## What's New in v3.0.0
6
+
7
+ **Context-Optimized Architecture**: Reduced from 40+ individual tools to 6 consolidated tools, saving ~80% context tokens while maintaining full functionality.
8
+
9
+ | Tool | Engines | Default |
10
+ |------|---------|---------|
11
+ | `ask_ai` | perplexity, chatgpt, claude, gemini, copilot, grok, deepseek, deepai | perplexity |
12
+ | `search_web` | google_search, bing_search, duckduckgo, yandex_search, yahoo_search, baidu_search, google_trends, rambler_search, you_search | google_search |
13
+ | `get_social` | instagram_profile, instagram_post, instagram_tag, instagram_geo, tiktok_profile, pinterest_search, reddit_posts, reddit_comments | instagram_profile |
14
+ | `get_video` | youtube_search, youtube_video, youtube_comments, youtube_channel_videos, youtube_channel_about | youtube_search |
15
+ | `translate` | google_translate, bing_translate, yandex_translate | google_translate |
16
+ | `extract` | text_extractor, article_extractor, link_extractor | text_extractor |
17
+
18
+ ## Quick Start
19
+
20
+ ### Install via npx (recommended)
21
+
22
+ ```bash
23
+ npx @ayga/mcp-client
24
+ ```
25
+
26
+ ### VS Code Copilot Configuration
27
+
28
+ Add to `%APPDATA%\Code\User\mcp.json`:
29
+
30
+ ```json
31
+ {
32
+ "inputs": [
33
+ {
34
+ "id": "REDIS_API_KEY",
35
+ "type": "promptString",
36
+ "description": "ayga-mcp-client Redis API key",
37
+ "password": true
38
+ }
39
+ ],
40
+ "servers": {
41
+ "ayga": {
42
+ "type": "stdio",
43
+ "command": "npx",
44
+ "args": ["@ayga/mcp-client@latest"],
45
+ "env": {
46
+ "REDIS_API_KEY": "${input:REDIS_API_KEY}"
47
+ }
48
+ }
49
+ }
50
+ }
51
+ ```
52
+
53
+ ### Claude Desktop Configuration
54
+
55
+ Add to `%APPDATA%\Claude\claude_desktop_config.json`:
56
+
57
+ ```json
58
+ {
59
+ "mcpServers": {
60
+ "ayga": {
61
+ "command": "npx",
62
+ "args": ["@ayga/mcp-client@latest"],
63
+ "env": {
64
+ "REDIS_API_KEY": "your-api-key-here"
65
+ }
66
+ }
67
+ }
68
+ }
69
+ ```
70
+
71
+ ## Usage Examples
72
+
73
+ ### Basic Usage (uses default engine)
74
+
75
+ ```
76
+ ask_ai query="What is quantum computing?"
77
+ search_web query="latest AI news"
78
+ get_video query="Python tutorials"
79
+ translate query="Hello world"
80
+ ```
81
+
82
+ ### With Specific Engine
83
+
84
+ ```
85
+ ask_ai query="Explain transformers" engine="claude"
86
+ search_web query="weather today" engine="duckduckgo"
87
+ get_social query="@openai" engine="instagram_profile"
88
+ get_video query="dQw4w9WgXcQ" engine="youtube_video"
89
+ ```
90
+
91
+ ### With Timeout
92
+
93
+ ```
94
+ ask_ai query="Complex analysis" engine="perplexity" timeout=120
95
+ ```
96
+
97
+ ## Environment Variables
98
+
99
+ | Variable | Description | Default |
100
+ |----------|-------------|---------|
101
+ | `REDIS_API_KEY` | API key for authentication | (required) |
102
+ | `API_URL` | Backend API URL | https://redis.ayga.tech |
103
+ | `DEFAULT_AI_ENGINE` | Default for ask_ai | perplexity |
104
+ | `DEFAULT_SEARCH_ENGINE` | Default for search_web | google_search |
105
+ | `DEFAULT_SOCIAL_ENGINE` | Default for get_social | instagram_profile |
106
+ | `DEFAULT_VIDEO_ENGINE` | Default for get_video | youtube_search |
107
+ | `DEFAULT_TRANSLATION_ENGINE` | Default for translate | google_translate |
108
+ | `DEFAULT_EXTRACTION_ENGINE` | Default for extract | text_extractor |
109
+ | `DYNAMIC_PARSERS` | Enable dynamic parser loading | true |
110
+
111
+ ## Architecture
112
+
113
+ ```
114
+ +-------------------------------------+
115
+ | VS Code / Claude Desktop |
116
+ +-----------------+-------------------+
117
+ | MCP stdio
118
+ +-----------------v-------------------+
119
+ | @ayga/mcp-client (Node.js) |
120
+ | - 6 consolidated tools |
121
+ | - 36 parser engines |
122
+ | - JWT authentication |
123
+ +-----------------+-------------------+
124
+ | HTTPS REST API
125
+ +-----------------v-------------------+
126
+ | redis_wrapper (Python/FastAPI) |
127
+ | https://redis.ayga.tech |
128
+ +-----------------+-------------------+
129
+ | Redis Queue
130
+ +-----------------v-------------------+
131
+ | A-Parser (Windows) |
132
+ +-------------------------------------+
133
+ ```
134
+
135
+ ## Tool Reference
136
+
137
+ ### ask_ai
138
+ Query AI models for answers, analysis, and research.
139
+
140
+ **Engines**: perplexity, chatgpt, claude, gemini, copilot, grok, deepseek, deepai
141
+
142
+ ```
143
+ ask_ai query="What are the benefits of Rust?" engine="claude"
144
+ ```
145
+
146
+ ### search_web
147
+ Search the web or get trends data.
148
+
149
+ **Engines**: google_search, bing_search, duckduckgo, yandex_search, yahoo_search, baidu_search, google_trends, rambler_search, you_search
150
+
151
+ ```
152
+ search_web query="best programming languages 2026"
153
+ search_web query="AI" engine="google_trends"
154
+ ```
155
+
156
+ ### get_social
157
+ Get data from social media platforms.
158
+
159
+ **Engines**: instagram_profile, instagram_post, instagram_tag, instagram_geo, tiktok_profile, pinterest_search, reddit_posts, reddit_comments
160
+
161
+ ```
162
+ get_social query="@openai" engine="instagram_profile"
163
+ get_social query="machine learning" engine="reddit_posts"
164
+ ```
165
+
166
+ ### get_video
167
+ Search and get YouTube content.
168
+
169
+ **Engines**: youtube_search, youtube_video, youtube_comments, youtube_channel_videos, youtube_channel_about
170
+
171
+ ```
172
+ get_video query="Python crash course"
173
+ get_video query="https://youtube.com/watch?v=..." engine="youtube_comments"
174
+ ```
175
+
176
+ ### translate
177
+ Translate text between languages.
178
+
179
+ **Engines**: google_translate, bing_translate, yandex_translate
180
+
181
+ ```
182
+ translate query="Hello, how are you?"
183
+ translate query="Bonjour" engine="yandex_translate"
184
+ ```
185
+
186
+ ### extract
187
+ Extract content from web pages.
188
+
189
+ **Engines**: text_extractor, article_extractor, link_extractor
190
+
191
+ ```
192
+ extract query="https://example.com/article" engine="article_extractor"
193
+ extract query="https://example.com" engine="link_extractor"
194
+ ```
195
+
196
+ ## Migration from v2.x
197
+
198
+ **v2.x (40+ tools)**:
199
+ ```
200
+ search_perplexity query="What is MCP?"
201
+ search_google_search query="latest news"
202
+ search_youtube_video query="..."
203
+ ```
204
+
205
+ **v3.x (6 consolidated tools)**:
206
+ ```
207
+ ask_ai query="What is MCP?" # uses default: perplexity
208
+ ask_ai query="What is MCP?" engine="perplexity" # explicit
209
+ search_web query="latest news" # uses default: google_search
210
+ get_video query="..." engine="youtube_video"
211
+ ```
212
+
213
+ ## Getting API Key
214
+
215
+ 1. Visit https://redis.ayga.tech
216
+ 2. Sign up or log in
217
+ 3. Generate API key
218
+ 4. Use in configuration
219
+
220
+ ## License
221
+
222
+ MIT
223
+
224
+ ## Links
225
+
226
+ - **API Backend**: https://redis.ayga.tech
227
+ - **Python Version**: https://pypi.org/project/ayga-mcp-client/
228
+ - **GitHub**: https://github.com/ozand/ayga-mcp-nodejs
229
+ - **Issues**: https://github.com/ozand/ayga-mcp-nodejs/issues
package/dist/index.js CHANGED
@@ -2,23 +2,32 @@
2
2
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
3
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
4
  import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
5
- import { PARSERS, getParserById } from "./parsers.js";
5
+ import { getRegistry } from "./parser-registry.js";
6
+ import { TOOL_CATEGORIES, getParsersForTool, getDefaultEngine, buildToolSchema } from "./tool-definitions.js";
6
7
  // Configuration
7
8
  const API_URL = process.env.API_URL || "https://redis.ayga.tech";
8
9
  const API_KEY = process.env.REDIS_API_KEY;
10
+ // Dynamic parser loading (set DYNAMIC_PARSERS=false to disable)
11
+ const ENABLE_DYNAMIC = process.env.DYNAMIC_PARSERS !== "false";
9
12
  class AygaMCPServer {
10
13
  server;
11
14
  jwtToken;
12
15
  tokenExpiry;
16
+ registry;
13
17
  constructor() {
14
18
  this.server = new Server({
15
19
  name: "ayga-mcp-client",
16
- version: "2.0.0",
20
+ version: "3.0.0",
17
21
  }, {
18
22
  capabilities: {
19
23
  tools: {},
20
24
  },
21
25
  });
26
+ this.registry = getRegistry({
27
+ apiUrl: API_URL,
28
+ apiKey: API_KEY,
29
+ enableDynamic: ENABLE_DYNAMIC,
30
+ });
22
31
  this.setupHandlers();
23
32
  this.setupErrorHandlers();
24
33
  }
@@ -60,7 +69,7 @@ class AygaMCPServer {
60
69
  }
61
70
  }
62
71
  async submitParserTask(parserId, query, timeout = 60) {
63
- const parser = getParserById(parserId);
72
+ const parser = await this.registry.getParserById(parserId);
64
73
  if (!parser) {
65
74
  throw new Error(`Unknown parser: ${parserId}`);
66
75
  }
@@ -135,61 +144,59 @@ class AygaMCPServer {
135
144
  throw new Error(`Timeout waiting for result after ${timeout}s (${attempts} attempts)`);
136
145
  }
137
146
  setupHandlers() {
138
- // List available tools
147
+ // List available tools - 6 consolidated tools instead of 40+
139
148
  this.server.setRequestHandler(ListToolsRequestSchema, async () => {
140
- const tools = PARSERS.map((parser) => ({
141
- name: `search_${parser.id}`,
142
- description: `${parser.description} (Category: ${parser.category})`,
143
- inputSchema: {
144
- type: "object",
145
- properties: {
146
- query: {
147
- type: "string",
148
- description: parser.category === "Translation"
149
- ? "Text to translate"
150
- : "Search query or URL",
151
- },
152
- timeout: {
153
- type: "number",
154
- description: "Timeout in seconds (default: 60)",
155
- default: 60,
156
- },
157
- },
158
- required: ["query"],
159
- },
160
- }));
161
- // Add list_parsers tool
149
+ const parsers = await this.registry.getParsers();
150
+ const tools = [];
151
+ // Build consolidated tools from categories
152
+ for (const toolCat of TOOL_CATEGORIES) {
153
+ const engines = getParsersForTool(toolCat.id, parsers).map(p => p.id);
154
+ if (engines.length > 0) {
155
+ tools.push(buildToolSchema(toolCat, engines));
156
+ }
157
+ }
158
+ // Add list_parsers utility tool
162
159
  tools.push({
163
160
  name: "list_parsers",
164
161
  description: "List all available parsers with their categories",
165
162
  inputSchema: {
166
163
  type: "object",
167
- properties: {},
164
+ properties: {
165
+ _placeholder: {
166
+ type: "boolean",
167
+ description: "Placeholder. Always pass true.",
168
+ },
169
+ },
170
+ required: ["_placeholder"],
168
171
  },
169
172
  });
173
+ this.log(`Registered ${tools.length} consolidated tools (${parsers.length} parsers available)`);
170
174
  return { tools };
171
175
  });
172
176
  // Call tool
173
177
  this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
174
178
  const { name, arguments: args } = request.params;
175
179
  try {
176
- // Handle list_parsers tool
180
+ // Handle list_parsers utility tool
177
181
  if (name === "list_parsers") {
178
- const category = args?.category;
179
- let parsers = PARSERS;
180
- if (category) {
181
- parsers = PARSERS.filter((p) => p.category === category);
182
+ const parsers = await this.registry.getParsers();
183
+ const categories = await this.registry.getCategories();
184
+ // Group parsers by consolidated tool
185
+ const toolMapping = {};
186
+ for (const toolCat of TOOL_CATEGORIES) {
187
+ const engines = getParsersForTool(toolCat.id, parsers);
188
+ if (engines.length > 0) {
189
+ toolMapping[toolCat.id] = {
190
+ tool: toolCat.name,
191
+ parsers: engines.map(e => e.id),
192
+ };
193
+ }
182
194
  }
183
- const categories = [...new Set(PARSERS.map((p) => p.category))];
184
195
  const result = {
185
196
  total: parsers.length,
197
+ consolidatedTools: TOOL_CATEGORIES.length,
186
198
  categories: categories,
187
- parsers: parsers.map((p) => ({
188
- id: p.id,
189
- name: p.name,
190
- category: p.category,
191
- description: p.description,
192
- })),
199
+ toolMapping: toolMapping,
193
200
  };
194
201
  return {
195
202
  content: [
@@ -200,16 +207,21 @@ class AygaMCPServer {
200
207
  ],
201
208
  };
202
209
  }
203
- // Handle parser tools
204
- if (name.startsWith("search_")) {
205
- const parserId = name.replace("search_", "");
210
+ // Handle consolidated tools (ask_ai, search_web, get_social, etc.)
211
+ const toolCat = TOOL_CATEGORIES.find(t => t.id === name);
212
+ if (toolCat) {
206
213
  const query = args?.query;
207
214
  const timeout = args?.timeout || 60;
215
+ // Get engine - use provided or default
216
+ let engine = args?.engine;
217
+ if (!engine) {
218
+ engine = getDefaultEngine(name);
219
+ }
208
220
  if (!query) {
209
221
  throw new Error("Query parameter is required");
210
222
  }
211
- this.log(`Executing ${name} with query: ${query.substring(0, 50)}...`);
212
- const result = await this.submitParserTask(parserId, query, timeout);
223
+ this.log(`Executing ${name} with engine=${engine}, query: ${query.substring(0, 50)}...`);
224
+ const result = await this.submitParserTask(engine, query, timeout);
213
225
  return {
214
226
  content: [
215
227
  {
@@ -219,7 +231,7 @@ class AygaMCPServer {
219
231
  ],
220
232
  };
221
233
  }
222
- throw new Error(`Unknown tool: ${name}`);
234
+ throw new Error(`Unknown tool: ${name}. Available: ${TOOL_CATEGORIES.map(t => t.id).join(", ")}, list_parsers`);
223
235
  }
224
236
  catch (error) {
225
237
  this.log(`Tool execution error: ${error}`, "error");
@@ -257,9 +269,12 @@ class AygaMCPServer {
257
269
  async run() {
258
270
  const transport = new StdioServerTransport();
259
271
  await this.server.connect(transport);
260
- this.log("Ayga MCP Server v2.0.0 started");
272
+ // Pre-fetch parsers
273
+ const parsers = await this.registry.getParsers();
274
+ this.log("Ayga MCP Server v3.0.0 started (consolidated tools)");
261
275
  this.log(`API URL: ${API_URL}`);
262
- this.log(`Total parsers: ${PARSERS.length}`);
276
+ this.log(`Dynamic loading: ${ENABLE_DYNAMIC ? "enabled" : "disabled"}`);
277
+ this.log(`Total parsers: ${parsers.length}`);
263
278
  this.log("Server ready on stdio transport");
264
279
  }
265
280
  }