Skip to content

Commit 91a7806

Browse files
committed
feat(rss): Enhance category matching in getAllFeedItems
- Implemented more flexible category matching in `getAllFeedItems` - Added `getCategoryByKeyword` to map keywords to categories - Improved handling of multi-word queries
1 parent 4dbc423 commit 91a7806

File tree

2 files changed

+155
-6
lines changed

2 files changed

+155
-6
lines changed

README.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,97 @@ You can also interact with the MCP using natural language. Claude will interpret
187187
- "Fetch the latest articles from my programming feeds"
188188
- "List all my RSS feeds"
189189

190+
## Extended Usage Examples
191+
192+
### Daily News Briefing
193+
194+
Get your news briefing from all your sources:
195+
196+
```
197+
rss latest --25
198+
```
199+
200+
This will fetch the 25 most recent articles across all your feeds, giving you a quick overview of the latest news.
201+
202+
### Exploring Top Content
203+
204+
Find the most important or popular articles:
205+
206+
```
207+
rss top --20
208+
```
209+
210+
### Category-Based Reading
211+
212+
Focus on specific content categories:
213+
214+
```
215+
rss "Tech News" --30
216+
rss "Politics" --15
217+
rss "Science" --10
218+
```
219+
220+
### Source-Specific Updates
221+
222+
Read updates from specific sources you follow:
223+
224+
```
225+
rss --hackernews --20
226+
rss --nytimes
227+
rss --techcrunch --15
228+
```
229+
230+
### Discover Your Available Feeds
231+
232+
Find out what feeds you have configured:
233+
234+
```
235+
rss list
236+
```
237+
238+
### Combining Multiple Requests
239+
240+
You can make multiple sequential requests to build a comprehensive view:
241+
242+
```
243+
rss "Tech News" --10
244+
rss "Finance" --10
245+
rss top --5
246+
```
247+
248+
### Practical Workflows
249+
250+
1. **Morning Routine**:
251+
```
252+
rss top --10
253+
rss "News" --5
254+
```
255+
256+
2. **Industry Research**:
257+
```
258+
rss "Industry News" --15
259+
rss --bloomberg --5
260+
```
261+
262+
3. **Tech Updates**:
263+
```
264+
rss --hackernews --10
265+
rss --techcrunch --5
266+
```
267+
268+
### Working with Claude
269+
270+
You can ask Claude to analyze or summarize the articles:
271+
272+
1. After running: `rss latest --10`
273+
Ask: "Can you summarize these articles?"
274+
275+
2. After running: `rss "Tech News" --15`
276+
Ask: "What are the key trends in these tech articles?"
277+
278+
3. After running: `rss --nytimes --washingtonpost --10`
279+
Ask: "Compare how these sources cover current events"
280+
190281
## Troubleshooting
191282

192283
### "Server disconnected" error

src/index.ts

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,10 @@ class RSSAggregator {
242242
const itemsPerFeed = Math.ceil(limit / this.feeds.size);
243243

244244
this.feeds.forEach((feed, id) => {
245-
if (!category || feed.category === category) {
245+
if (!category ||
246+
(feed.category && feed.category.toLowerCase() === category.toLowerCase()) ||
247+
(feed.category && feed.category.toLowerCase().includes(category.toLowerCase())) ||
248+
(feed.title && feed.title.toLowerCase().includes(category.toLowerCase()))) {
246249
feedPromises.push(this.getFeedItems(id, itemsPerFeed));
247250
}
248251
});
@@ -314,6 +317,39 @@ class RSSAggregator {
314317

315318
return Array.from(categories).sort();
316319
}
320+
321+
getCategoryByKeyword(keyword: string): string | null {
322+
const categories = this.getCategories();
323+
const lowercaseKeyword = keyword.toLowerCase();
324+
325+
const exactMatch = categories.find(c => c.toLowerCase() === lowercaseKeyword);
326+
if (exactMatch) return exactMatch;
327+
328+
const partialMatch = categories.find(c =>
329+
c.toLowerCase().includes(lowercaseKeyword) ||
330+
lowercaseKeyword.includes(c.toLowerCase().split(' ')[0]));
331+
if (partialMatch) return partialMatch;
332+
333+
const keywordMap: Record<string, string[]> = {
334+
'tech': ['tech', 'technology', 'programming', 'software', 'developer', 'ai'],
335+
'news': ['news', 'headlines', 'current'],
336+
'business': ['business', 'finance', 'economy', 'market'],
337+
'health': ['health', 'medical', 'wellness', 'fitness'],
338+
'science': ['science', 'research', 'study', 'discovery'],
339+
'sports': ['sports', 'game', 'team', 'player']
340+
};
341+
342+
for (const [category, keywords] of Object.entries(keywordMap)) {
343+
if (keywords.some(k => lowercaseKeyword.includes(k))) {
344+
const categoryMatch = categories.find(c =>
345+
c.toLowerCase().includes(category) ||
346+
c.toLowerCase() === category);
347+
if (categoryMatch) return categoryMatch;
348+
}
349+
}
350+
351+
return null;
352+
}
317353
}
318354

319355
const rssAggregator = new RSSAggregator();
@@ -462,12 +498,34 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
462498
}
463499
}
464500
else {
465-
const categories = rssAggregator.getCategories();
501+
const matchedCategory = rssAggregator.getCategoryByKeyword(command);
502+
503+
if (matchedCategory) {
504+
console.error(`Matched category "${matchedCategory}" from query "${command}"`);
505+
const items = await rssAggregator.getAllFeedItems(matchedCategory, limit);
506+
return formatItemsResponse(items, `Latest ${limit} articles in ${matchedCategory}`);
507+
}
466508

467-
if (categories.some(c => c.toLowerCase() === command.toLowerCase())) {
468-
const categoryName = categories.find(c => c.toLowerCase() === command.toLowerCase());
469-
const items = await rssAggregator.getAllFeedItems(categoryName, limit);
470-
return formatItemsResponse(items, `Latest ${limit} articles in ${categoryName}`);
509+
if (command.includes('news') || command.includes('tech') ||
510+
command.includes('sport') || command.includes('science') ||
511+
command.includes('business') || command.includes('health')) {
512+
console.error(`Using keyword query for "${command}"`);
513+
const items = await rssAggregator.getAllFeedItems(command, limit);
514+
return formatItemsResponse(items, `Latest ${limit} articles matching '${command}'`);
515+
}
516+
517+
const words = command.split(/\s+/);
518+
if (words.length > 1) {
519+
for (const word of words) {
520+
if (word.length < 3) continue;
521+
522+
const matchedKeywordCategory = rssAggregator.getCategoryByKeyword(word);
523+
if (matchedKeywordCategory) {
524+
console.error(`Matched category "${matchedKeywordCategory}" from partial keyword "${word}" in query "${command}"`);
525+
const items = await rssAggregator.getAllFeedItems(matchedKeywordCategory, limit);
526+
return formatItemsResponse(items, `Latest ${limit} articles in ${matchedKeywordCategory} matching '${command}'`);
527+
}
528+
}
471529
}
472530

473531
return {

0 commit comments

Comments
 (0)