Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
This MCP server provides 3 tools for fetching curriculum data from the Udir API. Tool naming follows verb_noun conventions (fetch_, get_, search_) which is good, but parameter descriptions are minimal and many lack type clarity. All tools have descriptions (10-80 chars), meeting the baseline, but descriptions are vague about WHAT the tools return and lack guidance on WHEN to use each. Input schemas are present but use all string types even for numeric parameters (limit, offset), violating the typed-parameters baseline. Output is returned as unstructured text strings rather than structured JSON, making it difficult for LLMs to extract and chain data. Error handling provides basic HTTP status codes but lacks recovery guidance or actionable next steps. No input validation is visible, the tools accept arbitrary strings without constraint validation.
Tools (3)
fetch_resourceread onlysource verified52/100
Fetch resources from a given endpoint with optional query, limit, and offset
get_by_idread onlysource verified52/100
Fetch a single resource by ID at the given endpoint
search_resourcesread onlysource verified54/100
Keyword search across resources - searches through available curriculum data
All numeric parameters (limit, offset) defined as string type instead of integer. This violates JSON Schema best practices and forces LLMs to convert strings to integers, increasing error likelihood.
Output returned as unstructured plaintext strings (e.g., '✅ Success...') rather than structured JSON objects. LLMs cannot parse field values, extract IDs for chaining, or validate completeness. Breaks tool composition.
Tool descriptions are too short (40-80 chars) and lack actionable guidance. 'Fetch resources from a given endpoint...' does not explain WHAT data is returned, WHEN to use this vs search_resources, or what the endpoint parameter should contain.
fetch_resourceget_by_idsearch_resources
Recommendations
Change limit and offset parameters from string type to integer type with min/max constraints (e.g., limit: integer, minimum: 1, maximum: 100, default: 20). This matches JSON Schema best practices and removes string-to-int conversion burden on LLMs.
Return structured JSON objects instead of plaintext strings. Example: {"success": true, "endpoint": "...", "count": 5, "items": [{"kode": "...", "tittel": "...", "type": "..."}, ...], "next_offset": 25} instead of '✅ Success: ...'. This enables data extraction and tool chaining.
Expand tool descriptions to 80-150 characters explaining: WHAT data is returned, WHEN to use this tool vs alternatives, and what the primary parameter (endpoint, id, query) should contain. Example: 'Fetch a single curriculum resource by its code (e.g., NOR01-06). Returns the full resource object with title, type, and status. Use this after search_resources returns a code you need details on.'
Constrain the 'query' parameter: either split into separate 'search_term' (string) and 'filter' (enum: subject|grade|status) parameters, or clearly document the expected format in the description ('Raw query string as key1=value1&key2=value2' or 'Single search term').
Add explicit limit constraints to parameter descriptions. Example: 'limit: Maximum number of items to return. Must be 1-100, default 20. Higher values may cause timeouts.' Also add a note in tool description about enforced caps.
Implement actionable error messages. Instead of '❌ API Error: 404 at https://...', return '❌ Endpoint not found: /invalid-endpoint. Valid endpoints: /laereplaner-lk20, /fagkoder, /kompetansemaal-lk20. Did you mean: /laereplaner-lk10?' This guides LLM self-correction.
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
Parameter 'query' in fetch_resource accepts raw query strings ('key=value&k2=v2') or search terms interchangeably, with conditional logic in the tool. This is ambiguous, the tool should either accept a structured object or clear enum of query types.
No constraints on limit parameter. Unspecified upper bound allows LLMs to request thousands of items, potentially causing API timeouts or context window exhaustion. Should enforce limit to 20-100 range.
Error responses return HTTP status codes and error strings but do not provide recovery guidance. Example: '❌ API Error: 404 at https://...' tells the LLM nothing about what to do next (retry, check endpoint, ask user).
No input validation visible. Tools accept any string for 'endpoint' and 'id' without checking format, length, or allowed characters. LLMs can pass invalid values and get cryptic API errors with no self-correction path.
fetch_resource and get_by_id both retrieve data from the API but differ in whether they accept query parameters and pagination. The distinction is not clear in tool descriptions, forcing LLMs to guess which tool to use.
fetch_resourceget_by_id
Add basic input validation inside each tool. Check that endpoint is non-empty, id contains only alphanumeric/dash characters, and limit/offset are valid integers. Return clear validation error messages like 'Invalid limit: got "500", must be 1-100.'
Clarify tool selection: in fetch_resource description, note that this tool is for collections with optional filtering; in get_by_id description, note this is for exact ID lookup. Example: 'fetch_resource: Query collections. Use when you need to find items matching criteria. search_resources: Search across multiple endpoints. Use when you don't know which endpoint contains the item.'
Add a sample output schema to each tool description showing the structure of returned data. Example: 'Returns: {"success": bool, "endpoint": string, "items": [{"kode": string, "tittel": string, "grep-type": string, "status": string}], "count": int}'
Implement pagination guidance. Document that limit+offset are supported and recommend fetching in chunks of 20 to avoid timeouts. Provide example: 'To get all items, start with offset=0, then offset=20, offset=40, until count < limit.'
Add parameter descriptions for 'endpoint' explaining valid paths: 'API endpoint path (e.g., /laereplaner-lk20, /fagkoder, /kompetansemaal-lk20, /grunnleggende-ferdigheter) or full absolute URL (https://...). Check documentation for available endpoints.'
Consider adding a 'list_endpoints' discovery tool that returns available endpoints. This removes the need for LLMs to hardcode endpoint names and enables dynamic exploration.