Jan Linketscher

Profile and essays of Jan Linketscher (i22, Bonn), full-text search, and booking a call.

Should I use this

Quality & Safety

A
Description quality
90%
Schema completeness
87%
Naming quality
97%
Poisoning risk
100%
Permission match
100%
Protocol compliance
100%

Findings (1)

  • LOWTool 'get_profile' description lacks action verbin get_profile

Based on automated analysis of tool definitions and protocol compliance.

Context Cost

~2,106Tokens (tool definitions)
~2.4 KBTypical response size
Moderate attention impact (1.65% of 128k context)

This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.

Install

One-Click Install

Add this to your `claude_desktop_config.json` file:

{
  "mcpServers": {
    "site": {
      "url": "https://janlinketscher.com/api/mcp"
    }
  }
}

Remote endpoints

https://janlinketscher.com/api/mcpstreamable-http

What it can do

Tool inventory

Tools (7)

🟢 Read-only🟡 Write🔴 Delete⚪ Unknown
🟢get_profile(section)

Who Jan Linketscher is: managing director and shareholder of the digital agency i22 (Bonn), his background, how his texts are written, and how to contact him. Content is in German.

Input Schema

{
  "type": "object",
  "properties": {
    "section": {
      "type": "string",
      "enum": [
        "all",
        "role",
        "background",
        "writing",
        "contact"
      ],
      "description": "Limit the text answer to one section (default: all). Structured output is always complete."
    }
  },
  "additionalProperties": false
}

Output Schema

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "role": {
      "type": "string"
    },
    "employer": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "url": {
          "type": "string"
        }
      },
      "required": [
        "name",
        "url"
      ]
    },
    "locations": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "summary": {
      "type": "string"
    },
    "background": {
      "type": "string"
    },
    "writing": {
      "type": "string",
      "description": "How the texts are produced (AI-assisted, human-reviewed)."
    },
    "contact": {
      "type": "object",
      "properties": {
        "email": {
          "type": "string"
        },
        "linkedin": {
          "type": "string"
        },
        "website": {
          "type": "string"
        }
      },
      "required": [
        "email",
        "website"
      ]
    },
    "image": {
      "type": "string"
    },
    "about": {
      "type": "string"
    }
  },
  "required": [
    "name",
    "role",
    "employer",
    "summary",
    "contact"
  ]
}
🟢list_essays(topic, limit)

List the essays, newest first: title, date, one-sentence summary, topics, URL and slug. Optionally filter by topic slug. Also returns the available topics.

Input Schema

{
  "type": "object",
  "properties": {
    "topic": {
      "type": "string",
      "description": "Topic slug, e.g. \"transformation\" or \"agentic-visibility\". Omit for all essays."
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 50,
      "description": "Maximum number of essays (default 20)."
    }
  },
  "additionalProperties": false
}

Output Schema

{
  "type": "object",
  "properties": {
    "count": {
      "type": "integer"
    },
    "essays": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "format": "date"
          },
          "topics": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "url": {
            "type": "string"
          },
          "markdownUrl": {
            "type": "string"
          }
        },
        "required": [
          "slug",
          "title",
          "date",
          "url"
        ]
      }
    },
    "topics": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "count": {
            "type": "integer"
          }
        },
        "required": [
          "slug",
          "name",
          "count"
        ]
      }
    },
    "series": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "url": {
          "type": "string"
        }
      },
      "required": [
        "name",
        "url"
      ]
    }
  },
  "required": [
    "count",
    "essays",
    "topics",
    "series"
  ]
}
🟢get_essay(slug)

Full text of one essay as Markdown (with front matter). Use the slug from list_essays or search.

Input Schema

{
  "type": "object",
  "properties": {
    "slug": {
      "type": "string",
      "description": "Essay slug, e.g. \"mein-essay\" (the last part of /essays/<slug>)."
    }
  },
  "required": [
    "slug"
  ],
  "additionalProperties": false
}

Output Schema

{
  "type": "object",
  "properties": {
    "slug": {
      "type": "string"
    },
    "title": {
      "type": "string"
    },
    "date": {
      "type": "string",
      "format": "date"
    },
    "url": {
      "type": "string"
    },
    "topics": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "markdown": {
      "type": "string"
    }
  },
  "required": [
    "slug",
    "title",
    "date",
    "url",
    "markdown"
  ]
}
🟢search(query, limit)

Full-text search across all essays and pages (about, context). Returns the best matches with title, URL and a short snippet. German queries work best.

Input Schema

{
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "minLength": 2,
      "description": "Search terms."
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 20,
      "description": "Maximum number of results (default 5)."
    }
  },
  "required": [
    "query"
  ],
  "additionalProperties": false
}

Output Schema

{
  "type": "object",
  "properties": {
    "query": {
      "type": "string"
    },
    "results": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "essay",
              "page"
            ]
          },
          "title": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "snippet": {
            "type": "string"
          },
          "score": {
            "type": "number"
          }
        },
        "required": [
          "kind",
          "title",
          "url",
          "snippet"
        ]
      }
    }
  },
  "required": [
    "query",
    "results"
  ]
}
🟢list_meeting_types

The kinds of calls that can be booked with Jan Linketscher ("kennenlernen" (Kennenlernen, 30 min), "sparring" (Sparring, 60 min)), with duration, purpose and a booking link for humans.

Input Schema

{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}

Output Schema

{
  "type": "object",
  "properties": {
    "timeZone": {
      "type": "string"
    },
    "meetingTypes": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "minutes": {
            "type": "integer"
          },
          "description": {
            "type": "string"
          },
          "bookingUrl": {
            "type": "string"
          }
        },
        "required": [
          "slug",
          "title",
          "minutes",
          "bookingUrl"
        ]
      }
    }
  },
  "required": [
    "timeZone",
    "meetingTypes"
  ]
}
🟢get_availability(meeting_type, from, to)

Free time slots for a call with Jan Linketscher. meeting_type: "kennenlernen" (Kennenlernen, 30 min), "sparring" (Sparring, 60 min). Optional date range (YYYY-MM-DD, default: the next 14 days, at most 90 days ahead). Times are ISO 8601 with offset; the text answer lists them in Europe/Berlin.

Input Schema

{
  "type": "object",
  "properties": {
    "meeting_type": {
      "type": "string",
      "enum": [
        "kennenlernen",
        "sparring"
      ],
      "description": "Kind of call."
    },
    "from": {
      "type": "string",
      "format": "date",
      "description": "First day (YYYY-MM-DD). Default: today."
    },
    "to": {
      "type": "string",
      "format": "date",
      "description": "Last day (YYYY-MM-DD), inclusive. Default: from + 13 days."
    }
  },
  "required": [
    "meeting_type"
  ],
  "additionalProperties": false
}

Output Schema

{
  "type": "object",
  "properties": {
    "meetingType": {
      "type": "string"
    },
    "minutes": {
      "type": "integer"
    },
    "timeZone": {
      "type": "string"
    },
    "from": {
      "type": "string"
    },
    "to": {
      "type": "string"
    },
    "slots": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "start": {
            "type": "string",
            "format": "date-time"
          },
          "end": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "start",
          "end"
        ]
      }
    },
    "bookingUrl": {
      "type": "string"
    }
  },
  "required": [
    "meetingType",
    "minutes",
    "timeZone",
    "from",
    "to",
    "slots",
    "bookingUrl"
  ]
}
🔴book_meeting(meeting_type, start, name, email, notes, ...)

Book a call with Jan Linketscher on behalf of your user. The start must be a slot returned by get_availability. If your client supports elicitation (form mode, MCP 2026-07-28), the server itself asks the user to confirm time, name and email – name and email are then prefilled from your arguments and can be corrected by the user. Otherwise: show the user meeting type, date and time (with time zone), name and email, get their explicit approval, then pass name, email and confirmed: true. Use the user's real name and email; never invent them. Cal.com sends the confirmation with a calendar invite and links to reschedule or cancel to that email address.

Input Schema

{
  "type": "object",
  "properties": {
    "meeting_type": {
      "type": "string",
      "enum": [
        "kennenlernen",
        "sparring"
      ]
    },
    "start": {
      "type": "string",
      "format": "date-time",
      "description": "Slot start from get_availability (ISO 8601)."
    },
    "name": {
      "type": "string",
      "minLength": 2,
      "maxLength": 100,
      "description": "Full name of the person attending."
    },
    "email": {
      "type": "string",
      "format": "email",
      "description": "Email of the person attending; the confirmation goes there."
    },
    "notes": {
      "type": "string",
      "maxLength": 1000,
      "description": "Optional: what the call is about, in one or two sentences."
    },
    "time_zone": {
      "type": "string",
      "description": "IANA time zone of the attendee, e.g. \"Europe/Berlin\" (default Europe/Berlin)."
    },
    "confirmed": {
      "type": "boolean",
      "description": "Only for clients without elicitation: true = the user has explicitly approved this booking."
    }
  },
  "required": [
    "meeting_type",
    "start"
  ],
  "additionalProperties": false
}

Output Schema

{
  "type": "object",
  "properties": {
    "status": {
      "type": "string",
      "enum": [
        "accepted",
        "pending",
        "not_booked"
      ],
      "description": "pending: Jan confirms the request by email. not_booked: the user declined."
    },
    "meetingType": {
      "type": "string"
    },
    "start": {
      "type": "string",
      "format": "date-time"
    },
    "end": {
      "type": "string",
      "format": "date-time"
    },
    "attendee": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "email": {
          "type": "string"
        }
      },
      "required": [
        "name",
        "email"
      ]
    },
    "message": {
      "type": "string"
    }
  },
  "required": [
    "status",
    "meetingType",
    "start",
    "end",
    "attendee",
    "message"
  ]
}

Community

Rate this Server

Evidence

Recent observations

verifiedversion not recorded7 tools