B RU 2GIS (Habr)·Practitioner post·

2GIS MCP server: stopping the LLM from inventing addresses

MCP-сервер 2ГИС: как мы учили LLM не выдумывать адреса

B · Useful, limited Engineering case study on Habr from the 2GIS team describing a production MCP server and reproduced failure cases with concrete parameters; credible practice from a large mapping company, but anecdotal and without an evaluation set.

Summary based on the full text·Original: about 16 minutes to read

In short

A Habr article (October 2026) by an engineer at 2GIS, the Russian mapping and directory company, on its MCP server that gives AI agents access to 2GIS geo APIs. Without tools, assistants invent addresses outright. With tools, they invent differently: they pass made-up coordinates or accept the wrong geocoder candidate, and the calls succeed. The team's answer is a stricter tool contract (validation, closed lists, typed multi-step scenarios) instead of instructions in the system prompt. The saved copy was cut off mid-article; the rest was read on the live page.

Key numbers

  • 6tools in the 2GIS MCP server: place search, geocoding, reverse geocoding, routing, isochrones, static maps
  • 5 of 44coffee shops returned for 'nearest coffee shop' with no point given, all in Vorkuta (latitude about 67.5)
  • ~150 kmdistance south of the airport for the second geocoder candidate for 'Sheremetyevo'

As reported by the source.

Read the original on habr.com

Russian·Web page·opens habr.com

What it reports

  • Architecture: tools are thin adapters; a shared core handles one HTTP pool per process, API key injection, logging, tracing and error mapping.
  • Two error contracts: key or access problems return a machine-readable result the agent can reason about (codes such as MCP_API_KEY_INVALID); network failures and timeouts stay protocol errors to retry. Returning "Error: 403" as text made the model call the tool again.
  • Unknown parameter values (for example an undocumented sort value) are rejected before the API call using closed lists.
  • Failure 1: a route query naming Novosibirsk returned a Moscow address, because the geocoder anchors on region_id or a point, not on a city name in the text.
  • Failure 2: a route from Sheremetyevo to "22nd km Metrogorodok, building 5" geocoded the destination to an observation deck in Yekaterinburg (56.83 / 60.63); the route tool would build that route without complaint.
  • Failure 3: "find the nearest coffee shop" with sort=distance and no point returned 5 of 44 results, all in Vorkuta. With a point at a Moscow hotel and an 800 m radius, results were correct.
  • Fixes: require a point before distance sorting; latitude and longitude only as a pair; radius (up to 40,000 m) only with a point; geocoder returns up to five candidates with city and region fields.
  • A typed scenario, route_to_nearest_place, fixes seven steps, a closed list of eight transport modes and a radius of 1-2,000 m.

How they got it

Lessons from building and running the server in production, with failures reproduced on real calls and logged through one trace span per tool plus started/success/error metrics.

Limits

  • No error rates or before/after measurements; evidence is individual cases.
  • Vendor writing about its own product.

Why it matters for companies

Connecting an AI assistant to internal systems does not stop it inventing data; it moves the invention into tool arguments, where the result looks valid. Any company wiring agents to HR, finance or customer systems faces the same issue with employee IDs, dates or account numbers. Required anchors, closed value lists and fixed step sequences in the tool contract catch errors that prompt wording does not.

Key passages in translation

Russian original

"На практике выяснилось, что доступа мало: получив инструменты, модель начинает врать иначе — и это куда труднее заметить."

English translation

"In practice, access turned out not to be enough: once given tools, the model starts lying differently, and that is much harder to notice."

Russian original

"Вызов при этом корректный, ошибки на уровне API нет — поэтому ответ выглядит обычным, просто про другую точку на карте."

English translation

"The call is valid, there is no error at the API level, so the answer looks normal; it is simply about a different point on the map."

Russian original

"модели нечем сказать «мне не дали данных», её банально научили, что говорить «не знаю» — это плохо, и она заполняет «пробелы» придуманными значениями."

English translation

"The model has no way to say 'I was not given the data'; it was simply trained that saying 'I don't know' is bad, so it fills the gaps with invented values."

Russian original

"Ответ приходит валидный по форме и бессмысленный по содержанию — и это сильно хуже, чем если бы ответа не было совсем, потому что клиент не видит ошибки."

English translation

"The answer arrives valid in form and meaningless in content, which is much worse than no answer at all, because the client does not see an error."

Russian original

"Формально ошибки не было ни в одном из вызовов."

English translation

"Formally, there was no error in any of the calls."

Summary based on the full text. Read the original for the full argument and data.Read the original on habr.com

Same week

All of Week 41