Smart Data Models MCP Server

Public MCP service providing programmatic access to the Smart Data Models catalog — a multi-sector library of standardized IoT and data space schemas governed by FIWARE, TM Forum, IUDX, and ITU-T.

MCP Endpoint: https://opendatamodels.org/mcp/v1
Health: https://opendatamodels.org/mcp/v1/health
Docs: https://opendatamodels.org/mcp/v1/docs
Manifest: https://opendatamodels.org/mcp/v1/manifest.json


AI / LLM Application Builder

This section is first because AI agents are the primary consumers of this MCP. The server is designed so that a capable LLM can correctly use all 15 tools with zero human guidance, provided the following is understood.

Connect

Add this to your Claude Desktop, Cursor, or any MCP-compatible client config:

{
  "mcpServers": {
    "smartdatamodels": {
      "type": "http",
      "serverUrl": "https://opendatamodels.org/mcp/v1"
    }
  }
}

What the LLM receives on first connect

The server returns server_instructions in the initialize response. Every LLM client that implements the MCP spec will automatically receive a domain model explanation — what SDM is, the subject/model/attribute hierarchy, when to call which tool, and how NGSI-LD payloads work — before touching any tool. You do not need to add a system prompt explaining SDM.

Decision tree for tool selection

User wants to find a model
  ├─ Has a keyword ("air quality", "parking") → search_data_models
  ├─ Has a misspelled or partial name         → fuzzy_find_model
  ├─ Wants to browse a sector                 → list_domains → list_models_by_domain
  └─ Has entity type from a payload, no subj  → find_subject_by_model_name

User wants to understand a model
  ├─ Needs full JSON Schema                   → get_data_model
  ├─ Needs all fields with types/units        → get_attributes_for_model
  ├─ Needs one specific field in depth        → get_attribute_details
  ├─ Needs the GitHub source link             → get_model_repo_url
  └─ Needs @context for NGSI-LD payload       → get_model_context

User wants to build a valid NGSI-LD payload
  ├─ Step 1: get @context URL                 → get_model_context   ← always first
  ├─ Step 2: get field names and types        → get_attributes_for_model
  └─ Step 3: validate the constructed payload → validate_data

User wants to explore the catalog
  ├─ Full structured list for a domain        → get_full_catalog
  ├─ Models related to a known model          → get_related_models
  └─ Flat attribute export (CSV / DB mapping) → export_model_attributes

Error recovery pattern

Every tool that takes a model_name can return MODEL_NOT_FOUND. The structured error always includes a suggestion field. The correct LLM recovery sequence:

  1. Receive {"isError": true, "error": {"code": "MODEL_NOT_FOUND", ...}}
  2. Call fuzzy_find_model with the same name and threshold: 70
  3. Present ranked candidates to the user or pick the top match
  4. Retry the original tool with the corrected name

Building a valid NGSI-LD payload — correct tool sequence

# Step 1: get @context
curl -s -X POST https://opendatamodels.org/mcp/v1 \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
       "params":{"name":"get_model_context","arguments":{"model_name":"WeatherObserved"}}}'

# Step 2: get all attributes
curl -s -X POST https://opendatamodels.org/mcp/v1 \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call",
       "params":{"name":"get_attributes_for_model","arguments":{"model_name":"WeatherObserved"}}}'

# Step 3: validate the constructed payload
curl -s -X POST https://opendatamodels.org/mcp/v1 \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc":"2.0","id":3,"method":"tools/call",
    "params":{
      "name":"validate_data",
      "arguments":{
        "model_name":"WeatherObserved",
        "data":{
          "@context":"https://smart-data-models.github.io/dataModel.Weather/context.jsonld",
          "id":"urn:ngsi-ld:WeatherObserved:station-001",
          "type":"WeatherObserved",
          "temperature":{"type":"Property","value":22.5},
          "location":{"type":"GeoProperty","value":{"type":"Point","coordinates":[-3.7,40.4]}}
        }
      }
    }
  }'

Error response format (all tools)

Every error is structured — no bare strings, no silent failures:

{
  "isError": true,
  "error": {
    "code": "MODEL_NOT_FOUND",
    "message": "Data model 'WeatherObservd' was not found.",
    "suggestion": "Check the spelling — model names are CamelCase. Use fuzzy_find_model to find the correct name."
  }
}

Validation failures are not system errors. isError is false even when a payload fails validation:

{
  "isError": false,
  "model_name": "WeatherObserved",
  "valid": false,
  "errors": ["'temperature' is a required property"],
  "detail": { ... }
}

All 15 Tools — Reference

Tool Required params Optional params Description
search_data_models query domain, limit Search catalog by keyword
get_data_model model_name include_examples Full JSON Schema and metadata
list_domains All 13 domains with model counts
list_models_by_domain domain limit All model names in a domain
validate_data model_name, data strict Validate a JSON payload
get_related_models model_name relationship_type Semantically related models
get_attributes_for_model model_name All attributes with NGSI type and units
get_attribute_details model_name, attribute Full metadata for one attribute
find_subject_by_model_name model_name Resolve entity type → subject
fuzzy_find_model model_name threshold (0–100, default 70) Ranked candidates for misspelled names
get_subject_repo_url subject GitHub URL for a subject group
get_model_repo_url model_name GitHub URL(s) for a model
get_full_catalog domain Complete model list for one domain
export_model_attributes model_name separator, fields Flat delimited attribute export
get_model_context model_name NGSI-LD @context URL and content

Valid domain values

SmartCities · SmartAgrifood · SmartWater · SmartEnergy · SmartEnvironment · SmartRobotics · SmartSensoring · CrossSector · SmartAeronautics · SmartDestinations · SmartHealth · SmartManufacturing · SmartLogistics

export_model_attributes — valid fields

property · type · dataModel · repoName · description · typeNGSI · modelTags · format · units · model


Rate Limits

60 requests / 60 seconds per IP. Every response includes:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57
X-RateLimit-Reset: 43
X-RateLimit-Window: 60s

When exceeded: HTTP 429. The X-RateLimit-Reset header tells you how many seconds until the window resets. Configurable server-side via RATE_LIMIT_REQUESTS and RATE_LIMIT_WINDOW_S environment variables.


Health & SLA

curl https://opendatamodels.org/mcp/v1/health
{
  "status": "healthy",
  "service": "smartdatamodels-mcp",
  "version": "1.0.0",
  "uptime_human": "3d 4h 12m",
  "adapter_status": "reachable",
  "timestamp": "2025-03-08T14:23:01Z",
  "sla": {
    "target_availability": "99.5%",
    "max_response_ms": 2000,
    "retry_after_503_seconds": [5, 15, 60]
  }
}
HTTP status Meaning
200 healthy Adapter reachable, serving requests
503 degraded Adapter initialising (server starting up)
503 unhealthy Adapter unreachable — back off and retry

On 503: retry with delays of 5 s → 15 s → 60 s.


Versioning & Deprecation

URL Status
https://opendatamodels.org/mcp/v1 Current — use this
https://opendatamodels.org/mcp Deprecated — Sunset: 2026-12-31

Legacy /mcp calls still work but receive Deprecation: true and Sunset: 2026-12-31 response headers.


Key Concepts (NGSI-LD / SDM)

Domain — top-level industry sector (e.g., SmartCities, SmartEnergy). 13 domains total.

Subject — a repository group within a domain, always prefixed dataModel. (e.g., dataModel.Weather). One domain contains many subjects.

Model — a specific entity schema within a subject (e.g., WeatherObserved). The unit you validate against, retrieve schemas for, and build payloads from.

Attribute — a field inside a model. Every attribute has:

  • NGSI type: Property, GeoProperty, or Relationship
  • Data type: Number, Text, DateTime, etc.
  • Units: recommended measurement units where applicable
  • Reference model URL: link to the external ontology or standard the attribute is drawn from

@context — the JSON-LD context document that makes NGSI-LD payloads valid linked data. Required in every normalized NGSI-LD payload. Retrieve it with get_model_context before constructing a payload — this is the single most common mistake when building NGSI-LD payloads from scratch.

Payload formatsvalidate_data accepts both:

  • NGSI-LD normalized: {"temperature": {"type": "Property", "value": 22}}
  • Key-values: {"temperature": 22}

Other Audiences

IoT Application Developer

# Find the right model
curl -s -X POST https://opendatamodels.org/mcp/v1 -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
       "params":{"name":"search_data_models",
                 "arguments":{"query":"temperature sensor","domain":"SmartSensoring"}}}'

# Get its fields and units
curl -s -X POST https://opendatamodels.org/mcp/v1 -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call",
       "params":{"name":"get_attributes_for_model","arguments":{"model_name":"WeatherObserved"}}}'

# Validate your device payload before publishing
curl -s -X POST https://opendatamodels.org/mcp/v1 -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call",
       "params":{"name":"validate_data","arguments":{"model_name":"WeatherObserved",
         "data":{"id":"urn:ngsi-ld:WeatherObserved:001","type":"WeatherObserved",
                 "temperature":{"type":"Property","value":22.5}}}}}'

Data Engineer / Architect

# Export attributes as CSV for DB column mapping
curl -s -X POST https://opendatamodels.org/mcp/v1 -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
       "params":{"name":"export_model_attributes","arguments":{
         "model_name":"AirQualityObserved","separator":",",
         "fields":["property","type","typeNGSI","units","description"]}}}'

# Get GitHub source for schema citation
curl -s -X POST https://opendatamodels.org/mcp/v1 -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call",
       "params":{"name":"get_model_repo_url","arguments":{"model_name":"AirQualityObserved"}}}'

# Get full domain catalog for bulk analysis
curl -s -X POST https://opendatamodels.org/mcp/v1 -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call",
       "params":{"name":"get_full_catalog","arguments":{"domain":"SmartEnvironment"}}}'

Smart City / Urban Planner

# Browse all available domains
curl -s -X POST https://opendatamodels.org/mcp/v1 -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_domains","arguments":{}}}'

# List all models in Smart Cities
curl -s -X POST https://opendatamodels.org/mcp/v1 -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call",
       "params":{"name":"list_models_by_domain","arguments":{"domain":"SmartCities"}}}'

# Find related models to a parking model
curl -s -X POST https://opendatamodels.org/mcp/v1 -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call",
       "params":{"name":"get_related_models","arguments":{"model_name":"OffStreetParking"}}}'

Support