@@ -116,19 +116,22 @@ function matches(r: Resource, f: {
116116 compensationType ?: string ; category ?: string ; macroCategory ?: string ;
117117} ) : boolean {
118118 if ( f . query ) {
119- const tokens = f . query . toLowerCase ( ) . split ( / \s + / ) . filter ( Boolean ) ;
120- const syns : string [ ] = [ ] ;
121- if ( r . compensationType === "payment" ) syns . push ( "paid" , "money" , "cash" , "compensation" ) ;
122- if ( r . compensationType === "donation" ) syns . push ( "donate" , "volunteer" , "free" ) ;
123- if ( r . compensationType === "mixed" ) syns . push ( "paid" , "donate" , "compensation" ) ;
124-
125- const hay = [
126- r . title , r . description , ...( r . dataTypes ?? [ ] ) ,
127- ...( r . organizations ?. map ( ( o ) => o . name ) ?? [ ] ) , ...availableIn ( r ) , ...( r . macroCategories ?? [ ] ) ,
128- r . compensationType , r . entityCategory , r . entitySubType , ...syns
129- ] . filter ( Boolean ) . map ( String ) . map ( lc ) . join ( " " ) ;
130- for ( const t of tokens ) {
131- if ( ! hay . includes ( t ) ) return false ;
119+ const STOP = new Set ( [ "a" , "an" , "the" , "for" , "of" , "to" , "in" , "on" , "and" , "or" , "i" , "me" , "my" , "can" ,
120+ "do" , "find" , "want" , "need" , "where" , "study" , "studies" , "research" , "program" , "programs" ,
121+ "project" , "projects" , "opportunity" , "opportunities" , "participate" , "join" , "looking" , "near" ] ) ;
122+ const tokens = f . query . toLowerCase ( ) . split ( / \s + / ) . filter ( Boolean ) . filter ( ( t ) => ! STOP . has ( t ) ) ;
123+ if ( tokens . length ) {
124+ const syns : string [ ] = [ ] ;
125+ if ( r . compensationType === "payment" ) syns . push ( "paid" , "money" , "cash" , "compensation" ) ;
126+ if ( r . compensationType === "donation" ) syns . push ( "donate" , "volunteer" , "free" ) ;
127+ if ( r . compensationType === "mixed" ) syns . push ( "paid" , "donate" , "compensation" ) ;
128+
129+ const hay = [
130+ r . title , r . description , ...( r . dataTypes ?? [ ] ) ,
131+ ...( r . organizations ?. map ( ( o ) => o . name ) ?? [ ] ) , ...availableIn ( r ) , ...( r . macroCategories ?? [ ] ) ,
132+ r . compensationType , r . entityCategory , r . entitySubType , ...syns
133+ ] . filter ( Boolean ) . map ( String ) . map ( lc ) . join ( " " ) ;
134+ if ( ! tokens . some ( ( t ) => hay . includes ( t ) ) ) return false ;
132135 }
133136 }
134137 if ( f . dataType && ! ( r . dataTypes ?? [ ] ) . some ( ( d ) => lc ( d ) . includes ( lc ( f . dataType ) ) ) ) return false ;
@@ -158,6 +161,10 @@ function getScore(r: Resource, q?: string): number {
158161 if ( lc ( r . description ) . includes ( t ) ) score += 2 ;
159162 if ( ( r . dataTypes ?? [ ] ) . join ( " " ) . toLowerCase ( ) . includes ( t ) ) score += 5 ;
160163 if ( lc ( r . entityCategory ) . includes ( t ) ) score += 5 ;
164+ if ( [ "paid" , "money" , "cash" , "compensation" ] . includes ( t ) &&
165+ ( r . compensationType === "payment" || r . compensationType === "mixed" ) ) score += 6 ;
166+ if ( [ "donate" , "donation" , "volunteer" , "free" ] . includes ( t ) &&
167+ ( r . compensationType === "donation" || r . compensationType === "mixed" ) ) score += 6 ;
161168 }
162169 return score ;
163170}
@@ -216,6 +223,17 @@ export class YourselfToScienceMCP extends McpAgent {
216223 if ( args . query ) {
217224 hits = hits . sort ( ( a , b ) => getScore ( b , args . query ) - getScore ( a , args . query ) ) ;
218225 }
226+ if ( args . country ) {
227+ hits = hits . sort ( ( a , b ) => {
228+ const aAvail = availableIn ( a ) . map ( lc ) ;
229+ const bAvail = availableIn ( b ) . map ( lc ) ;
230+ const aExact = aAvail . some ( ( c ) => c . includes ( lc ( args . country ! ) ) ) ;
231+ const bExact = bAvail . some ( ( c ) => c . includes ( lc ( args . country ! ) ) ) ;
232+ if ( aExact && ! bExact ) return - 1 ;
233+ if ( ! aExact && bExact ) return 1 ;
234+ return 0 ;
235+ } ) ;
236+ }
219237 const offset = args . offset ?? 0 ;
220238 const limit = args . limit ?? 20 ;
221239 const paginated = hits . slice ( offset , offset + limit ) ;
0 commit comments