LabscoMCP early access ↗
oiseeMCP SERVER

OData MCP Bridge (Go)

Point one Go binary at an OData v2 or v4 service — SAP services included — and its entity sets and function imports arrive as MCP tools, with flags to decide how many of them the model sees and whether any of them can write.

by oisee ↗API Specifications & HTTP ToolingCommunity

LABSCO SUMMARY

The service's own metadata decides what the model can do

It reads $metadata and hands the model whatever the service declares — the entity sets, the function imports, and which operations each entity set admits to supporting — so an OData v2 or v4 endpoint becomes usable without anyone writing a tool for it. The choice worth making before you start is how many tools that produces: one user's pair of services came to 485 tools and the model reported no API available, which is the case --universal exists for, trading the self-documenting per-entity names for a single call that names its target in a parameter.

What it is

A single Go binary that takes one OData service URL, reads that service's $metadata, and generates MCP tools from what it finds there. It handles OData v2 and v4, and it understands SAP's dialect — the sap:creatable-style annotations that mark which operations an entity set allows, and the CSRF tokens SAP expects on writes. One process fronts one service; run several processes if you have several services. The default transport is stdio, which is what Claude Desktop uses, and --transport http or --transport streamable-http serve HTTP clients instead. It is a Go port of an earlier Python bridge, distributed as a compiled binary with no runtime to install, under the MIT License.

What you get

  • Per-entity-set tools generated from metadata — filter_{EntitySet}, count_{EntitySet}, search_{EntitySet}, get_{EntitySet}, create_{EntitySet}, update_{EntitySet}, delete_{EntitySet}; each one appears only if the entity set declares it supports that operation
  • Function imports as tools — each import in the service becomes an individual tool carrying the function's own name
  • odata_service_info — metadata and capabilities of the service; when a hints entry matches the service URL it also returns implementation_hints with the known issues, workarounds and field formats recorded for that service
  • OData query options on the read tools — $filter, $select, $expand, $orderby, $top, $skip, $count
  • One-tool mode for services too large to fit — --universal replaces the per-entity tools with a single tool taking action, target and params, where action is one of list, get, create, update, delete, count and call. Measured 2026-01-31: SAP GWSAMPLE_BASIC went from 68 tools / ~16,287 tokens to 1 tool / ~765 tokens, Northwind v2 from 157 tools / ~37,260 tokens to 1 tool / ~912 tokens
  • Write operations you can switch off at generation time — --read-only (-ro) hides create, update, delete and function imports; --read-only-but-functions (-robf) hides create, update and delete but keeps functions; --enable and --disable take operation letters (C create, S search, F filter, G get, U update, D delete, A actions, R read)
  • Surface control — --entities "Products,Categories,Order*" and --functions "Get*,Create*" accept wildcards, and --tool-shrink, --tool-prefix, --tool-postfix and --no-postfix decide what the generated names look like
  • --claude-code-friendly (-c) — strips the $ from OData parameter names ($filter becomes filter, $select becomes select) so Claude Code CLI's stricter property-name validation accepts the schema; the server maps them back before it calls the service
  • Response shaping — --max-items (default 100, validated up to 10,000), --max-response-size (default 5MB), --pagination-hints, --response-metadata, --convert-dates-from-sap
  • Inspection before you connect a client — --trace prints the generated tool list and exits, --trace-mcp writes a protocol log to the temp directory, --verbose-errors returns detailed error context
  • A hints file — hints.json beside the binary, or --hints-file, or --hint on the command line; entries match service URLs by wildcard pattern and merge by priority, and ship with defaults for SAP OData services, SAP PO tracking and the public Northwind demo

Requirements

One binary and one service URL. Pre-built binaries cover Linux (amd64), Windows (amd64) and macOS on both Intel and Apple Silicon; from source it is go build -o odata-mcp cmd/odata-mcp/main.go, and there is a Makefile and a Dockerfile (docker build -t odata-mcp .). The service URL goes in as a positional argument, as --service, or as ODATA_SERVICE_URL / ODATA_URL. Credentials depend on what the service wants: basic auth through --user and --password or through ODATA_USERNAME / ODATA_PASSWORD, cookies through --cookie-file (Netscape format) or --cookie-string, and anonymous services need neither; a .env file in the working directory is read as well. Under Claude Desktop the credentials belong in the config's env block — Claude Desktop does not read your system environment, and MCP servers there run locally with the same permissions Claude Desktop itself has. The HTTP transports require an authentication token in every case: --mcp-token (or --mcp-token-file) on localhost, that token plus --tls, --tls-cert and --tls-key anywhere else, and binding to 0.0.0.0 or :: additionally requires --allow-all-interfaces. Stdio, the default, requires none of this.

Setup effort

Build from source — clone the repository and build it, then follow the project's own run instructions