Skip to main content
Glama
infinitnet

ConceptNet MCP Server

by infinitnet

concept_lookup

Query ConceptNet's knowledge graph to discover relationships, properties, and semantic information about any concept, with language filtering and complete results.

Instructions

Look up information about a specific concept in ConceptNet.

This tool queries ConceptNet's knowledge graph to find all relationships
and properties associated with a given concept. By default, it returns
ALL results (not limited to 20) to provide complete information.

Features:
- Complete relationship discovery for any concept
- Language filtering and cross-language exploration
- Summaries and statistics
- Performance optimized with automatic pagination
- Format control: minimal (~96% smaller) vs verbose (full metadata)

Format Options:
- verbose=false (default): Returns minimal format optimized for LLM consumption
- verbose=true: Returns comprehensive format with full ConceptNet metadata
- Backward compatibility maintained with existing tools

Use this when you need to:
- Understand what ConceptNet knows about a concept
- Explore all relationships for a term
- Get semantic information
- Find related concepts and properties

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
termYes
languageNoen
limit_resultsNo
target_languageNo
verboseNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • Core handler function implementing the concept_lookup tool logic: validates parameters, normalizes term, queries ConceptNet API, processes response into minimal or verbose format, handles errors.
    async def concept_lookup(
        term: str,
        ctx: Context,
        language: str = "en",
        limit_results: bool = False,
        target_language: Optional[str] = None,
        verbose: bool = False
    ) -> Dict[str, Any]:
        """
        Look up all edges for a specific concept in ConceptNet.
        
        This tool queries ConceptNet's knowledge graph to find all relationships
        and properties associated with a given concept. By default, it returns
        a minimal format optimized for LLM consumption.
        
        Args:
            term: The concept term to look up (e.g., "dog", "artificial intelligence")
            language: Language code for the concept (default: "en" for English)
            limit_results: If True, limits to first 20 results for quick queries (default: False)
            target_language: If specified, filters results to edges involving this language
            verbose: If True, returns detailed format with full metadata (default: False)
            
        Returns:
            Concept data with relationships grouped by type (minimal format) or
            comprehensive data with full metadata (verbose format).
            
        Examples:
            - concept_lookup("dog") -> Minimal format with grouped relationships
            - concept_lookup("dog", verbose=True) -> Full detailed format with metadata
            - concept_lookup("perro", "es") -> Spanish concept relationships in minimal format
        """
        start_time = datetime.now(timezone.utc)
        
        try:
            # Log the incoming request
            await ctx.info(f"Looking up concept: '{term}' (language: {language})")
            
            # 1. Parameter validation
            await _validate_parameters(term, language, target_language, ctx)
            
            # 2. Normalize the input term
            normalized_term = normalize_concept_text(term, language)
            if normalized_term != term:
                await ctx.debug(f"Normalized term: '{term}' -> '{normalized_term}'")
            
            # 3. Query ConceptNet API
            await ctx.info(f"Querying ConceptNet API for concept '{normalized_term}'...")
            
            async with ConceptNetClient() as client:
                try:
                    response = await client.get_concept(
                        term=normalized_term,
                        language=language,
                        get_all_pages=not limit_results,
                        target_language=target_language
                    )
                except ConceptNotFoundError:
                    return _create_not_found_response(term, language, normalized_term)
                except ConceptNetAPIError as e:
                    return _create_api_error_response(term, language, str(e))
            
            # 4. Apply default language filtering if target_language not specified
            effective_target_language = target_language if target_language is not None else language
            
            # 5. Process and normalize the response
            processor = ResponseProcessor(default_language=language)
            processed_response = processor.process_concept_response(
                response, target_language=effective_target_language
            )
            
            # 6. Return appropriate format based on verbose parameter
            if verbose:
                # Return detailed format with full metadata (existing behavior)
                enhanced_response = await _create_enhanced_response(
                    processed_response, term, normalized_term, language,
                    effective_target_language, limit_results, start_time, ctx
                )
                
                total_edges = enhanced_response.get("summary", {}).get("total_edges", 0)
                await ctx.info(f"Successfully retrieved {total_edges} edges for concept '{term}' (verbose format)")
                
                return enhanced_response
            else:
                # Return minimal format optimized for LLMs
                minimal_response = processor.create_minimal_concept_response(
                    processed_response, term
                )
                
                total_relationships = minimal_response.get("summary", {}).get("total_relationships", 0)
                await ctx.info(f"Successfully retrieved {total_relationships} relationships for concept '{term}' (minimal format)")
                
                return minimal_response
            
        except MCPValidationError as e:
            # Handle validation errors specifically
            return {
                "error": "validation_error",
                "message": f"Validation error for field '{e.field}': {e.value} (expected: {e.expected})",
                "field": e.field,
                "value": e.value,
                "expected": e.expected,
                "term": term,
                "language": language,
                "query_time": start_time.isoformat() + "Z"
            }
            
        except ConceptNotFoundError:
            return _create_not_found_response(term, language, term)
            
        except ConceptNetAPIError as e:
            return _create_api_error_response(term, language, str(e))
            
        except Exception as e:
            logger.error(f"Unexpected error in concept_lookup: {e}")
            return {
                "error": "unexpected_error",
                "message": f"An unexpected error occurred: {str(e)}",
                "term": term,
                "language": language,
                "query_time": start_time.isoformat() + "Z"
            }
  • FastMCP tool registration for 'concept_lookup' with description and tags. Wraps the core implementation with error handling.
    @mcp.tool(
        name="concept_lookup",
        description="""
        Look up information about a specific concept in ConceptNet.
        
        This tool queries ConceptNet's knowledge graph to find all relationships
        and properties associated with a given concept. By default, it returns
        ALL results (not limited to 20) to provide complete information.
        
        Features:
        - Complete relationship discovery for any concept
        - Language filtering and cross-language exploration
        - Summaries and statistics
        - Performance optimized with automatic pagination
        - Format control: minimal (~96% smaller) vs verbose (full metadata)
        
        Format Options:
        - verbose=false (default): Returns minimal format optimized for LLM consumption
        - verbose=true: Returns comprehensive format with full ConceptNet metadata
        - Backward compatibility maintained with existing tools
        
        Use this when you need to:
        - Understand what ConceptNet knows about a concept
        - Explore all relationships for a term
        - Get semantic information
        - Find related concepts and properties
        """,
        tags={"conceptnet", "knowledge", "lookup"}
    )
    async def concept_lookup_tool(
        term: str,
        ctx: Context,
        language: str = "en",
        limit_results: bool = False,
        target_language: Optional[str] = None,
        verbose: bool = False
    ) -> Dict[str, Any]:
        """
        MCP tool wrapper for concept lookup functionality.
        
        Args:
            term: The concept term to look up (e.g., "dog", "artificial intelligence")
            language: Language code for the concept (default: "en" for English)
            limit_results: If True, limits to first 20 results for quick queries (default: False)
            target_language: If specified, filters results to edges involving this language
            verbose: If True, returns detailed format with full metadata (default: False)
            
        Returns:
            Concept relationships grouped by type (minimal format) or comprehensive data with full metadata (verbose format)
        """
        try:
            return await concept_lookup(
                term=term,
                ctx=ctx,
                language=language,
                limit_results=limit_results,
                target_language=target_language,
                verbose=verbose
            )
        except Exception as e:
            return await handle_server_error(e, "concept_lookup")
  • Pydantic schema/model defining input parameters and validation for concept_lookup queries, used by the client.
    class ConceptLookupQuery(BaseModel):
        """
        Query model for looking up a specific concept.
        
        This model defines parameters for retrieving information
        about a specific concept from the ConceptNet API.
        """
        
        term: str = Field(
            description="The concept term to look up"
        )
        language: str = Field(
            default="en",
            description="Language code for the concept (e.g., 'en', 'es', 'fr')"
        )
        limit_results: bool = Field(
            default=False,
            description="Whether to limit results to first page (20 items)"
        )
        target_language: Optional[str] = Field(
            default=None,
            description="Filter results to specific language"
        )
        
        @field_validator('language', 'target_language')
        @classmethod
        def validate_language_codes(cls, v: Optional[str]) -> Optional[str]:
            """Validate language codes are reasonable."""
            if v is not None and (len(v) < 2 or len(v) > 3 or not v.isalpha()):
                raise ValueError("Language code must be 2-3 alphabetic characters")
            return v.lower() if v else v
        
        def to_concept_uri(self) -> str:
            """Convert term and language to ConceptNet URI format."""
            # Replace spaces with underscores and construct URI
            normalized_term = self.term.replace(' ', '_').lower()
            return f"/c/{self.language}/{normalized_term}"
        
        def __str__(self) -> str:
            """Return a human-readable string representation."""
            return f"ConceptLookup('{self.term}' in {self.language})"
  • Simplified handler for concept_lookup in Cloudflare Workers deployment, directly queries ConceptNet API.
    async def _concept_lookup(self, term: str, language: str = "en",
                            limit_results: bool = False,
                            target_language: Optional[str] = None,
                            verbose: bool = False) -> Dict[str, Any]:
        """Implement concept lookup tool."""
        endpoint = f"/c/{language}/{normalize_concept_text(term, language)}"
        params = {}
        if target_language:
            params['filter'] = f'/c/{target_language}/'
        if limit_results:
            params['limit'] = '20'
        
        response_data = await self.http_client.request("GET", endpoint, params=params)
        
        # Add Workers-specific metadata
        response_data['deployment'] = {
            'platform': 'cloudflare-workers-python',
            'transport': 'dual-http-sse',
            'edge_location': 'global'
        }
        
        return response_data
  • Tool registration and explicit JSON schema definition for concept_lookup in Cloudflare Workers MCP protocol implementation.
    "concept_lookup": {
        "name": "concept_lookup",
        "description": "Look up information about a specific concept in ConceptNet. Returns minimal format (~96% smaller) by default or verbose format with full metadata when verbose=true.",
        "inputSchema": {
            "type": "object",
            "properties": {
                "term": {"type": "string", "description": "The concept term to look up"},
                "language": {"type": "string", "default": "en", "description": "Language code"},
                "limit_results": {"type": "boolean", "default": False, "description": "Limit to first page of results"},
                "target_language": {"type": "string", "description": "Filter to specific target language"},
                "verbose": {"type": "boolean", "default": False, "description": "Return detailed format with full metadata (default: false for minimal format)"}
            },
            "required": ["term"]
        }
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It effectively describes key traits: it's a read-only lookup tool (implied by 'queries'), returns all results by default (not limited), supports language filtering and cross-language exploration, includes performance optimization with automatic pagination, and offers format control (minimal vs. verbose). However, it lacks details on rate limits, error handling, or authentication needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections (purpose, features, format options, usage guidelines) and front-loaded key information. Most sentences earn their place by adding value, though some phrasing (e.g., 'Performance optimized with automatic pagination') could be more concise. Overall, it's appropriately sized for a tool with 5 parameters and no annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (5 parameters, no annotations, but with an output schema), the description is largely complete. It covers purpose, usage, behavioral traits, and parameter semantics adequately. The output schema exists, so the description needn't explain return values. However, it could improve by explicitly linking parameters to features (e.g., naming 'limit_results') and addressing potential constraints like rate limits.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It adds significant meaning beyond the schema: it explains the 'verbose' parameter with two format options (minimal vs. comprehensive), mentions language filtering and cross-language exploration (hinting at 'language' and 'target_language'), and implies 'limit_results' controls whether to return all results. However, it doesn't explicitly define all five parameters (e.g., 'term' is only implied).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Look up information about a specific concept in ConceptNet' and 'queries ConceptNet's knowledge graph to find all relationships and properties associated with a given concept.' It distinguishes from siblings by specifying it returns 'ALL results (not limited to 20)' and mentions 'Backward compatibility maintained with existing tools,' implying differentiation from concept_query.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly provides usage guidance with a 'Use this when you need to:' section listing four specific scenarios (e.g., 'Understand what ConceptNet knows about a concept,' 'Explore all relationships for a term'). It implicitly distinguishes from siblings by mentioning 'complete information' and 'ALL results,' suggesting alternatives might be limited or partial.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/infinitnet/conceptnet-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server