diff --git a/servers/justizonline_gv_at_jop_api/.npmignore b/servers/justizonline_gv_at_jop_api/.npmignore
new file mode 100644
index 000000000..c4dd0ca3c
--- /dev/null
+++ b/servers/justizonline_gv_at_jop_api/.npmignore
@@ -0,0 +1,4 @@
+src/
+node_modules/
+.gitignore
+tsconfig.json
\ No newline at end of file
diff --git a/servers/justizonline_gv_at_jop_api/README.md b/servers/justizonline_gv_at_jop_api/README.md
new file mode 100644
index 000000000..787dd6296
--- /dev/null
+++ b/servers/justizonline_gv_at_jop_api/README.md
@@ -0,0 +1,120 @@
+# @open-mcp/justizonline_gv_at_jop_api
+
+## Using the remote server
+
+To use the hosted Streamable HTTP server, add the following to your client config:
+
+```json
+{
+ "mcpServers": {
+ "justizonline_gv_at_jop_api": {
+ "transport": "streamableHttp",
+ "url": "https://mcp.open-mcp.org/api/server/justizonline_gv_at_jop_api@latest/mcp"
+ }
+ }
+}
+```
+
+#### Forwarding variables
+
+You can forward "environment" variables to the remote server by including them in the request headers or URL query string (headers take precedence). Just prefix the variable name with `FORWARD_VAR_` like so:
+
+```ini
+https://mcp.open-mcp.org/api/server/justizonline_gv_at_jop_api@latest/mcp?FORWARD_VAR_OPEN_MCP_BASE_URL=https%3A%2F%2Fapi.example.com
+```
+
+
+ Sending authentication tokens as forwarded variables is not recommended
+
+
+## Installing locally
+
+If you want to run the server locally on your own machine instead of using the remote server, first set the environment variables as shell variables:
+
+```bash
+X_API_KEY='...'
+```
+
+Then use the OpenMCP config CLI to add the server to your MCP client:
+
+### Claude desktop
+
+```bash
+npx @open-mcp/config add justizonline_gv_at_jop_api \
+ ~/Library/Application\ Support/Claude/claude_desktop_config.json \
+ --X_API_KEY=$X_API_KEY
+```
+
+### Cursor
+
+Run this from the root of your project directory or, to add to all cursor projects, run it from your home directory `~`.
+
+```bash
+npx @open-mcp/config add justizonline_gv_at_jop_api \
+ .cursor/mcp.json \
+ --X_API_KEY=$X_API_KEY
+```
+
+### Other
+
+```bash
+npx @open-mcp/config add justizonline_gv_at_jop_api \
+ /path/to/client/config.json \
+ --X_API_KEY=$X_API_KEY
+```
+
+### Manually
+
+If you don't want to use the helper above, add the following to your MCP client config manually:
+
+```json
+{
+ "mcpServers": {
+ "justizonline_gv_at_jop_api": {
+ "command": "npx",
+ "args": ["-y", "@open-mcp/justizonline_gv_at_jop_api"],
+ "env": {"X_API_KEY":"..."}
+ }
+ }
+}
+```
+
+## Environment variables
+
+- `OPEN_MCP_BASE_URL` - overwrites the base URL of every tool's underlying API request
+- `X_API_KEY` - gets sent to the API provider
+
+## Tools
+
+### expandSchema
+
+Expand the input schema for a tool before calling the tool
+
+**Input schema**
+
+- `toolName` (string)
+- `jsonPointers` (array)
+
+### listexpertsv1
+
+**Environment variables**
+
+- `X_API_KEY`
+
+**Input schema**
+
+- `from` (string)
+- `until` (string)
+- `type` (string)
+- `pageNumber` (integer)
+- `pageSize` (integer)
+
+### getexpertbyaddresscodev1
+
+**Environment variables**
+
+- `X_API_KEY`
+
+**Input schema**
+
+- `addressCode` (string)
diff --git a/servers/justizonline_gv_at_jop_api/package.json b/servers/justizonline_gv_at_jop_api/package.json
new file mode 100644
index 000000000..eee198098
--- /dev/null
+++ b/servers/justizonline_gv_at_jop_api/package.json
@@ -0,0 +1,36 @@
+{
+ "name": "@open-mcp/justizonline_gv_at_jop_api",
+ "version": "0.0.1",
+ "main": "dist/index.js",
+ "type": "module",
+ "bin": {
+ "justizonline_gv_at_jop_api": "./dist/index.js"
+ },
+ "files": [
+ "dist"
+ ],
+ "scripts": {
+ "clean": "rm -rf dist",
+ "copy-json-schema": "mkdir -p dist/tools && find src/tools -type d -name 'schema-json' -exec sh -c 'mkdir -p dist/tools/$(dirname {} | sed \"s/src\\/tools\\///\") && cp -r {} dist/tools/$(dirname {} | sed \"s/src\\/tools\\///\")/' \\;",
+ "prebuild": "npm run clean && npm run copy-json-schema",
+ "build": "tsc && chmod 755 dist/index.js",
+ "test": "echo \"No test specified\"",
+ "prepublishOnly": "npm install && npm run build && npm run test"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "description": "",
+ "dependencies": {
+ "@modelcontextprotocol/sdk": "^1.9.0",
+ "@open-mcp/core": "latest",
+ "zod": "^3.24.2"
+ },
+ "devDependencies": {
+ "@types/node": "^22.14.1",
+ "typescript": "^5.8.3"
+ },
+ "publishConfig": {
+ "access": "public"
+ }
+}
diff --git a/servers/justizonline_gv_at_jop_api/src/constants.ts b/servers/justizonline_gv_at_jop_api/src/constants.ts
new file mode 100644
index 000000000..97cbc6332
--- /dev/null
+++ b/servers/justizonline_gv_at_jop_api/src/constants.ts
@@ -0,0 +1,7 @@
+export const OPENAPI_URL = "https://justizonline.gv.at/jop/web/assets/iwg/exp-extern-svdo.yaml"
+export const SERVER_NAME = "justizonline_gv_at_jop_api"
+export const SERVER_VERSION = "0.0.1"
+export const OPERATION_FILES_RELATIVE = [
+ "./tools/listexpertsv1/index.js",
+ "./tools/getexpertbyaddresscodev1/index.js"
+]
\ No newline at end of file
diff --git a/servers/justizonline_gv_at_jop_api/src/index.ts b/servers/justizonline_gv_at_jop_api/src/index.ts
new file mode 100644
index 000000000..8a9dfa101
--- /dev/null
+++ b/servers/justizonline_gv_at_jop_api/src/index.ts
@@ -0,0 +1,28 @@
+#!/usr/bin/env node
+
+const TOOLS_ARG_NAME = "--tools"
+
+function parseCSV(csv: string | undefined) {
+ if (!csv) {
+ return undefined
+ }
+ const arr = csv
+ .trim()
+ .split(",")
+ .filter((x) => x !== "")
+ return arr.length > 0 ? arr : undefined
+}
+
+import("./server.js").then((module) => {
+ const args = process.argv.slice(2)
+ const toolsCSV = args
+ .find((arg) => arg.startsWith(TOOLS_ARG_NAME))
+ ?.replace(TOOLS_ARG_NAME, "")
+
+ const toolNames = parseCSV(toolsCSV)
+
+ module.runServer({ toolNames }).catch((error) => {
+ console.error("Fatal error running server:", error)
+ process.exit(1)
+ })
+})
diff --git a/servers/justizonline_gv_at_jop_api/src/server.ts b/servers/justizonline_gv_at_jop_api/src/server.ts
new file mode 100644
index 000000000..027995685
--- /dev/null
+++ b/servers/justizonline_gv_at_jop_api/src/server.ts
@@ -0,0 +1,33 @@
+import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
+import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"
+import { registerTools } from "@open-mcp/core"
+import type { OpenMCPServerTool } from "@open-mcp/core"
+import {
+ SERVER_NAME,
+ SERVER_VERSION,
+ OPERATION_FILES_RELATIVE,
+} from "./constants.js"
+
+const server = new McpServer({
+ name: SERVER_NAME,
+ version: SERVER_VERSION,
+})
+
+export async function runServer({ toolNames }: { toolNames?: string[] }) {
+ try {
+ const tools: OpenMCPServerTool[] = []
+ for (const file of OPERATION_FILES_RELATIVE) {
+ const tool = (await import(file)).default as OpenMCPServerTool
+ if (!toolNames || toolNames.includes(tool.toolName)) {
+ tools.push(tool)
+ }
+ }
+ await registerTools(server, tools)
+ const transport = new StdioServerTransport()
+ await server.connect(transport)
+ console.error("MCP Server running on stdio")
+ } catch (error) {
+ console.error("Error during initialization:", error)
+ process.exit(1)
+ }
+}
diff --git a/servers/justizonline_gv_at_jop_api/src/tools/getexpertbyaddresscodev1/index.ts b/servers/justizonline_gv_at_jop_api/src/tools/getexpertbyaddresscodev1/index.ts
new file mode 100644
index 000000000..785b73800
--- /dev/null
+++ b/servers/justizonline_gv_at_jop_api/src/tools/getexpertbyaddresscodev1/index.ts
@@ -0,0 +1,26 @@
+import { inputParamsSchema } from "./schema/root.js"
+import type { OpenMCPServerTool } from "@open-mcp/core"
+
+const tool: OpenMCPServerTool = {
+ "toolName": "getexpertbyaddresscodev1",
+ "toolDescription": "Get expert by addressCode",
+ "baseUrl": "https://justizonline.gv.at/jop/api",
+ "path": "/v1/experts/{addressCode}",
+ "method": "get",
+ "security": [
+ {
+ "key": "X-Api-Key",
+ "value": "X_API_KEY",
+ "in": "header",
+ "envVarName": "X_API_KEY"
+ }
+ ],
+ "paramsMap": {
+ "path": {
+ "addressCode": "addressCode"
+ }
+ },
+ inputParamsSchema
+}
+
+export default tool
\ No newline at end of file
diff --git a/servers/justizonline_gv_at_jop_api/src/tools/getexpertbyaddresscodev1/schema-json/root.json b/servers/justizonline_gv_at_jop_api/src/tools/getexpertbyaddresscodev1/schema-json/root.json
new file mode 100644
index 000000000..cb5de0352
--- /dev/null
+++ b/servers/justizonline_gv_at_jop_api/src/tools/getexpertbyaddresscodev1/schema-json/root.json
@@ -0,0 +1,12 @@
+{
+ "type": "object",
+ "properties": {
+ "addressCode": {
+ "description": "Unique address code of an expert",
+ "type": "string"
+ }
+ },
+ "required": [
+ "addressCode"
+ ]
+}
\ No newline at end of file
diff --git a/servers/justizonline_gv_at_jop_api/src/tools/getexpertbyaddresscodev1/schema/root.ts b/servers/justizonline_gv_at_jop_api/src/tools/getexpertbyaddresscodev1/schema/root.ts
new file mode 100644
index 000000000..c23f6a0f0
--- /dev/null
+++ b/servers/justizonline_gv_at_jop_api/src/tools/getexpertbyaddresscodev1/schema/root.ts
@@ -0,0 +1,5 @@
+import { z } from "zod"
+
+export const inputParamsSchema = {
+ "addressCode": z.string().describe("Unique address code of an expert")
+}
\ No newline at end of file
diff --git a/servers/justizonline_gv_at_jop_api/src/tools/listexpertsv1/index.ts b/servers/justizonline_gv_at_jop_api/src/tools/listexpertsv1/index.ts
new file mode 100644
index 000000000..b6c4f0db4
--- /dev/null
+++ b/servers/justizonline_gv_at_jop_api/src/tools/listexpertsv1/index.ts
@@ -0,0 +1,30 @@
+import { inputParamsSchema } from "./schema/root.js"
+import type { OpenMCPServerTool } from "@open-mcp/core"
+
+const tool: OpenMCPServerTool = {
+ "toolName": "listexpertsv1",
+ "toolDescription": "List experts",
+ "baseUrl": "https://justizonline.gv.at/jop/api",
+ "path": "/v1/experts",
+ "method": "get",
+ "security": [
+ {
+ "key": "X-Api-Key",
+ "value": "X_API_KEY",
+ "in": "header",
+ "envVarName": "X_API_KEY"
+ }
+ ],
+ "paramsMap": {
+ "query": {
+ "from": "from",
+ "until": "until",
+ "type": "type",
+ "pageNumber": "pageNumber",
+ "pageSize": "pageSize"
+ }
+ },
+ inputParamsSchema
+}
+
+export default tool
\ No newline at end of file
diff --git a/servers/justizonline_gv_at_jop_api/src/tools/listexpertsv1/schema-json/root.json b/servers/justizonline_gv_at_jop_api/src/tools/listexpertsv1/schema-json/root.json
new file mode 100644
index 000000000..8b9679407
--- /dev/null
+++ b/servers/justizonline_gv_at_jop_api/src/tools/listexpertsv1/schema-json/root.json
@@ -0,0 +1,36 @@
+{
+ "type": "object",
+ "properties": {
+ "from": {
+ "description": "Filter to include changes from date",
+ "type": "string",
+ "format": "date"
+ },
+ "until": {
+ "description": "Filter to include changes until date",
+ "type": "string",
+ "format": "date"
+ },
+ "type": {
+ "description": "Filter to include specific types of experts",
+ "type": "string",
+ "enum": [
+ "SV",
+ "DO"
+ ]
+ },
+ "pageNumber": {
+ "description": "Page number",
+ "type": "integer",
+ "format": "int32",
+ "default": 1
+ },
+ "pageSize": {
+ "description": "Page size",
+ "type": "integer",
+ "format": "int32",
+ "default": 25
+ }
+ },
+ "required": []
+}
\ No newline at end of file
diff --git a/servers/justizonline_gv_at_jop_api/src/tools/listexpertsv1/schema/root.ts b/servers/justizonline_gv_at_jop_api/src/tools/listexpertsv1/schema/root.ts
new file mode 100644
index 000000000..537e7c0df
--- /dev/null
+++ b/servers/justizonline_gv_at_jop_api/src/tools/listexpertsv1/schema/root.ts
@@ -0,0 +1,9 @@
+import { z } from "zod"
+
+export const inputParamsSchema = {
+ "from": z.string().date().describe("Filter to include changes from date").optional(),
+ "until": z.string().date().describe("Filter to include changes until date").optional(),
+ "type": z.enum(["SV","DO"]).describe("Filter to include specific types of experts").optional(),
+ "pageNumber": z.number().int().describe("Page number").optional(),
+ "pageSize": z.number().int().describe("Page size").optional()
+}
\ No newline at end of file
diff --git a/servers/justizonline_gv_at_jop_api/tsconfig.json b/servers/justizonline_gv_at_jop_api/tsconfig.json
new file mode 100644
index 000000000..9d4d978a4
--- /dev/null
+++ b/servers/justizonline_gv_at_jop_api/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "compilerOptions": {
+ "target": "ES2022",
+ "module": "NodeNext",
+ "moduleResolution": "NodeNext",
+ "outDir": "./dist",
+ "rootDir": "./src",
+ "strict": true,
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ "forceConsistentCasingInFileNames": true,
+ "resolveJsonModule": true
+ },
+ "include": ["src/**/*"],
+ "exclude": ["node_modules"]
+}