filter_{EntitySet}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 returnsimplementation_hintswith 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 —
--universalreplaces the per-entity tools with a single tool takingaction,targetandparams, 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;--enableand--disabletake 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-postfixand--no-postfixdecide what the generated names look like --claude-code-friendly(-c) — strips the$from OData parameter names ($filterbecomesfilter,$selectbecomesselect) 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(default100, validated up to10,000),--max-response-size(default5MB),--pagination-hints,--response-metadata,--convert-dates-from-sap - Inspection before you connect a client —
--traceprints the generated tool list and exits,--trace-mcpwrites a protocol log to the temp directory,--verbose-errorsreturns detailed error context - A hints file —
hints.jsonbeside the binary, or--hints-file, or--hinton 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
USE CASES
Querying an OData service nobody wrote a client for
The entity sets arrive as tools with the OData query options attached, so a question turns into a filtered read instead of a ticket. --trace shows you the generated list before any client connects.
Pointing an assistant at production without letting it write
--read-only leaves create, update, delete and function imports out of tool generation entirely; --read-only-but-functions keeps the function imports. Pair either one with a read-only service account so the boundary holds on the service side too.
Writing records back, not only reading them
Create, update and delete tools are generated for the entity sets whose metadata declares them creatable, updatable or deletable, and every function import becomes a tool of its own. CSRF tokens for SAP services are handled by the bridge.
Getting a large SAP service to work at all
--entities and --functions narrow the generated set with wildcards, and --universal collapses the whole service into one tool taking action, target and params — on Northwind v2 that is 157 tools / ~37,260 tokens down to 1 tool / ~912 tokens.
Serving one bridge to clients that each carry their own token
--transport streamable-http serves POST /mcp with GET /health beside it, and --forward-mcp-headers passes each client's HTTP headers through to the OData service so credentials arrive per request rather than at startup. Off localhost this transport needs --mcp-token plus TLS.
9 tools
Listed in project docs. Your client may show a different list.
count_{EntitySet}search_{EntitySet}get_{EntitySet}create_{EntitySet}update_{EntitySet}delete_{EntitySet}odata_service_infoodataBEFORE YOU INSTALL
What to know first
Tools you get
9 tools named in the project's documentation.
Where it runs
All 3 documented clients run the server on your machine.
INSTALLATION
Connect your client
Server setup
git clone https://github.com/oisee/odata_mcp_go.git && cd odata_mcp_go && go build -o odata-mcp cmd/odata-mcp/main.goMCP Clients
Claude Desktop
{
"mcpServers": {
"my-secure-service": {
"command": "<YOUR_PATH_TO_ODATA_MCP>",
"args": [
"--service",
"https://my-service.com/odata/",
"--tool-shrink"
],
"env": {
"ODATA_USERNAME": "myusername",
"ODATA_PASSWORD": "mypassword"
}
}
}
}Claude Code
{
"mcpServers": {
"northwind-claude-code": {
"command": "<YOUR_PATH_TO_ODATA_MCP>",
"args": [
"--service",
"https://services.odata.org/V2/Northwind/Northwind.svc/",
"--claude-code-friendly"
]
}
}
}AI Foundry
{
"mcpServers": {
"odata-for-ai-foundry": {
"command": "<YOUR_PATH_TO_ODATA_MCP>",
"args": [
"--service",
"<YOUR_ODATA_SERVICE_URL>/",
"--protocol-version",
"2025-06-18",
"--user",
"<YOUR_USERNAME>",
"--password",
"<YOUR_PASSWORD>"
]
}
}
}