@@ -345,37 +345,45 @@ def signal_handler(signum, frame):
345345
346346@mcp_app .tool (
347347 name = "Get_Information_Schema" ,
348- description = "Get the information schema of the OMOP database." ,
348+ description = "Get the database schema name and type. Returns the schema prefix to use for table references (e.g., 'gold') and the database type (e.g., 'databricks') ." ,
349349)
350350@capture_context (tool_name = "Get_Information_Schema" )
351351def get_information_schema () -> mcp .types .CallToolResult :
352- """Get the information schema of the OMOP database.
352+ """Get the database schema name and type.
353+
354+ This function returns only the essential schema information needed for SQL generation:
355+ - schema_name: The schema/database prefix to use (e.g., 'gold', 'omop', 'public')
356+ - database_type: The SQL dialect to use (e.g., 'databricks', 'postgres', 'duckdb')
353357
354- This function retrieves information from the information schema of the OMOP database.
355- Information is restricted to only tables and columns allowed by the users configuration.
356358 Args:
357359 None
358360 Returns:
359- List of schemas, tables, columns and data types formatted as a CSV string.
361+ Simple text with schema name and database type
360362 """
361363 try :
362- logger .debug ("Getting information schema..." )
363- # Note: @capture_context decorator already handles Langfuse tracing
364- result = db .get_information_schema ()
365- logger .debug ("Information schema retrieved successfully" )
364+ logger .debug ("Getting schema information..." )
365+
366+ # Return only the essential information
367+ schema_name = db .cdm_schema
368+ database_type = db .target_dialect
369+
370+ result = f"Schema: { schema_name } \n Database Type: { database_type } "
371+
372+ logger .debug (f"Schema info: { result } " )
366373 return mcp .types .CallToolResult (
367374 content = [
368375 mcp .types .TextContent (type = "text" , text = result ),
369- ]
376+ ],
377+ _meta = {"database_type" : database_type , "schema_name" : schema_name },
370378 )
371379 except Exception as e :
372- logger .error (f"Failed to retrieve information schema: { e } " )
380+ logger .error (f"Failed to retrieve schema information : { e } " )
373381 return mcp .types .CallToolResult (
374382 isError = True ,
375383 content = [
376384 mcp .types .TextContent (
377385 type = "text" ,
378- text = f"Failed to retrieve information schema: { str (e )} " ,
386+ text = f"Failed to retrieve schema information : { str (e )} " ,
379387 )
380388 ],
381389 )
@@ -431,6 +439,104 @@ def read_query(query: str) -> mcp.types.CallToolResult:
431439 )
432440
433441
442+ @mcp_app .tool (
443+ name = "Lookup_Drug" ,
444+ description = "Look up drug concepts by name in the OMOP concept table. Returns standardized drug concepts with concept_id, concept_name, concept_code, vocabulary_id, and domain_id." ,
445+ )
446+ @capture_context (tool_name = "Lookup_Drug" )
447+ def lookup_drug (term : str , limit : int = 10 ) -> mcp .types .CallToolResult :
448+ """Look up drug concepts by name.
449+
450+ This function searches for drug concepts in the OMOP concept table by partial name match.
451+ Only returns standard, valid drug concepts ordered by name length (shortest first).
452+
453+ Args:
454+ term: Drug name to search for (case-insensitive partial match)
455+ limit: Maximum number of results to return (default: 10)
456+
457+ Returns:
458+ CSV formatted results with: concept_id, concept_name, concept_code, vocabulary_id, domain_id
459+ """
460+ try :
461+ schema = db .cdm_schema
462+ # Use parameterized query pattern with LIKE
463+ query = f"""
464+ SELECT concept_id, concept_name, concept_code, vocabulary_id, domain_id
465+ FROM { schema } .concept
466+ WHERE LOWER(concept_name) LIKE LOWER('%{ term } %')
467+ AND domain_id = 'Drug'
468+ AND standard_concept = 'S'
469+ AND invalid_reason IS NULL
470+ ORDER BY LENGTH(concept_name), concept_name
471+ LIMIT { limit }
472+ """
473+ logger .info (f"Looking up drug: { term } " )
474+ result = db .read_query (query )
475+ logger .info (f"Drug lookup completed for: { term } " )
476+ return mcp .types .CallToolResult (
477+ content = [mcp .types .TextContent (type = "text" , text = result )]
478+ )
479+ except Exception as e :
480+ logger .error (f"Failed to lookup drug '{ term } ': { e } " )
481+ return mcp .types .CallToolResult (
482+ isError = True ,
483+ content = [
484+ mcp .types .TextContent (
485+ type = "text" , text = f"Failed to lookup drug: { str (e )} "
486+ )
487+ ],
488+ )
489+
490+
491+ @mcp_app .tool (
492+ name = "Lookup_Condition" ,
493+ description = "Look up condition concepts by name in the OMOP concept table. Returns standardized condition concepts with concept_id, concept_name, concept_code, vocabulary_id, and domain_id." ,
494+ )
495+ @capture_context (tool_name = "Lookup_Condition" )
496+ def lookup_condition (term : str , limit : int = 10 ) -> mcp .types .CallToolResult :
497+ """Look up condition concepts by name.
498+
499+ This function searches for condition concepts in the OMOP concept table by partial name match.
500+ Only returns standard, valid condition concepts ordered by name length (shortest first).
501+
502+ Args:
503+ term: Condition name to search for (case-insensitive partial match)
504+ limit: Maximum number of results to return (default: 10)
505+
506+ Returns:
507+ CSV formatted results with: concept_id, concept_name, concept_code, vocabulary_id, domain_id
508+ """
509+ try :
510+ schema = db .cdm_schema
511+ # Use parameterized query pattern with LIKE
512+ query = f"""
513+ SELECT concept_id, concept_name, concept_code, vocabulary_id, domain_id
514+ FROM { schema } .concept
515+ WHERE LOWER(concept_name) LIKE LOWER('%{ term } %')
516+ AND domain_id = 'Condition'
517+ AND standard_concept = 'S'
518+ AND invalid_reason IS NULL
519+ ORDER BY LENGTH(concept_name), concept_name
520+ LIMIT { limit }
521+ """
522+ logger .info (f"Looking up condition: { term } " )
523+ result = db .read_query (query )
524+ logger .info (f"Condition lookup completed for: { term } " )
525+ return mcp .types .CallToolResult (
526+ content = [mcp .types .TextContent (type = "text" , text = result )]
527+ )
528+ except Exception as e :
529+ logger .error (f"Failed to lookup condition '{ term } ': { e } " )
530+ return mcp .types .CallToolResult (
531+ isError = True ,
532+ content = [
533+ mcp .types .TextContent (
534+ type = "text" , text = f"Failed to lookup condition: { str (e )} "
535+ )
536+ ],
537+ )
538+
539+
434540def main ():
435541 """Main function to run the MCP server."""
436542 logger .info (f"Starting OMOP MCP Server with { transport_type .upper ()} transport..." )
0 commit comments