Search RedM/RDR3 docs by behavior, concept, OR exact token. Use when you don't have a specific native hash/name (use `lookup_native`) and the term isn't a known asset name in a large data table (use `grep_docs`). Hybrid mode (default) handles 'how do I X' queries ('teleport player', 'spawn vehicle', 'inventory add item') AND tokens ('addItem', 'weapon_pistol_volcanic', 'CPED_CONFIG_FLAG_') — fused via RRF over vector + BM25. Returns ranked snippets (path, breadcrumb, heading, snippet, score). Call `get_document({path, heading})` for full chunk content. `mode=semantic` for pure vector; `mode=lexical` for pure BM25. Filter via `category=vorp|rsgcore|oxmysql|natives|discoveries|jo_libs|learnings` or `namespace`. Community findings merged by default; `category=learnings` returns only findings. If you are retrying after a previous call returned no useful results, populate `prior_attempt` so the server can surface alternative wordings and learn what's missing from the docs.
Parameters (7)
querystringrequired
Natural language or token query
categorystring
Limit to one doc category
namespacestring
Limit to a native namespace, e.g. PLAYER, ENTITY
limitinteger
How many ranked snippets to return. Default 20 (Anthropic contextual-retrieval research: top-20 outperforms top-5/10 before reranking).
modestring
Retrieval mode. Default hybrid (recommended).
responseFormatstring
`concise` (default): 400-char snippet per hit — cheap, browse-style. `detailed`: full chunk content — use when you need an answer in one round-trip and want to skip the `get_document` follow-up.
prior_attemptobject
Populate ONLY when retrying after a previous semantic_search call returned no useful results. Skip on first attempts.
list_namespaces
Orient yourself: list available doc categories and their namespaces. Use once at session start (or when unsure) before applying a `category=` / `namespace=` filter to `browse` / `semantic_search`. NOT a content search. Categories: `natives` (PLAYER, ENTITY, VEHICLE, …), `vorp`, `rsgcore`, `oxmysql`, `discoveries` (AI, weapons, peds, animations, clothes, objects, …), `jo_libs` (menu, notification, callback, framework-bridge, …, dev_resources, redm_scripts), `guides`, `learnings`.
Parameters (1)
categorystring
browse
Enumerate doc paths in a category/namespace. Use to discover what exists before calling `get_document` or a targeted `grep_docs`. NOT a content search — use `semantic_search` for behavior/concept lookups or `grep_docs` for token lookups. Returns `{path, title, chunks}[]`.
Parameters (2)
categorystring
namespacestring
get_document
Fetch full markdown of a doc by `path` (as returned by `browse`, `semantic_search`, or `grep_docs`). Use to retrieve full content after a search snippet looks promising. Pass `heading` (full breadcrumb like `Character Management > Inventory Management`, or just the leaf — case-insensitive, fuzzy) to fetch only that section. Deep-heading matches auto-prepend the H2 parent's intro for context. For individual script natives prefer `lookup_native`. The largest rdr3_discoveries lua data tables are keyed catalogs: call with no `heading` to list their top-level keys, then pass a key as `heading` to fetch that one entry; use `grep_docs` to search values inside. For code symbols (`addItem`) use `grep_docs`. Community findings use `learning:N` paths, not `learnings/<slug>.md`. On 404 returns available headings + cross-file hints.
Parameters (2)
pathstringrequired
Doc path. Two valid shapes: (a) `<category>/<file>.md` for docs, e.g. `vorp/vorp_core_docs.md`; (b) `learning:<id>` for community findings, e.g. `learning:11`. Use the path returned by `browse`/`semantic_search`/`grep_docs` verbatim — do not invent `learnings/<slug>.md`.
headingstring
Optional prose heading from the doc, e.g. `Add Item to User` or `Character Management > Inventory Management`. Case-insensitive, fuzzy match on the leaf (text after the final `>`). NOT for code symbols — `addItem`, `getPlayerPed` etc. won't match; use `grep_docs` for those.
read_lines
Read an exact line range from a raw doc file by absolute line number — the windowed-read companion to `grep_docs`. When `grep_docs` returns a hit at `path:line` inside a large file, call `read_lines({ path, start, end })` to pull the surrounding block. This is the ONLY way to read around a hit in the largest rdr3_discoveries data tables (audio_banks, ingameanims_list, ptfx, soundsets, imaps_with_coords, megadictanims, etc.): their full bodies are NOT in the vector/heading index (only an ~80-line preview is), so `semantic_search` can't reach them and `get_document` resolves real section headings only — NOT synthetic `lines N-M` offsets. `start`/`end` are 1-based and inclusive; omit `end` for a 50-line window; one call returns at most 400 lines (narrow the range for more). For prose `.md` docs prefer `get_document` with a `heading`; to search values use `grep_docs`; for individual script natives use `lookup_native`.
Parameters (3)
pathstringrequired
Doc path exactly as returned by `grep_docs` / `browse` / `semantic_search`, e.g. `discoveries/audio/audio_banks/audio_banks.lua`. Do not invent paths.
startintegerrequired
First line to return (1-based, inclusive). Use the line number from a `grep_docs` hit.
endinteger
Last line to return (1-based, inclusive). Omit for a 50-line window from `start`. Spans over 400 lines are capped.
grep_docs
Find an EXACT literal token in raw doc files (markdown + lua). Use for specific weapon/ped/animation/prop/interior/zone names (`weapon_pistol_volcanic`, `a_c_bear_01`, `p_campfire01x`), known hashes (`0x020D13FF`), walkstyles/clipsets (`MP_Style_Casual`, `mech_loco_m@`), or any string you'd `grep` for. NOT for behavior/concept queries (use `semantic_search`) or script-native hash/name lookup (use `lookup_native`). REQUIRED for tokens inside the largest rdr3_discoveries data tables (audio_banks, ingameanims_list, cloth_drawable, cloth_hash_names, object_list, megadictanims, entity_extensions, imaps_with_coords, propsets_list, vehicle_bones) — only preview-indexed for embeddings, so `semantic_search` will NOT find tokens in them. Optional: `contextBefore`/`contextAfter` for ±N surrounding lines (saves a follow-up `get_document` call); `filesOnly: true` to get paths only (cheap exploration); `multiline: true` for cross-line patterns (`(?s)foo.*bar`). Pattern uses Rust regex syntax (rg engine). PREFER one targeted call over giant `a|b|c|d|e` alternations — split into separate calls; alternations rarely improve recall and bloat the regex automaton. Returns matched lines with path + line number. Long matched lines are windowed ±60 chars around the match (…); to read around a hit, use `read_lines({path, start})` for the preview-only mega-tables listed above (get_document holds only their ~80-line head), or `get_document({path})` for ordinary docs. If you are retrying after a previous pattern returned no matches, populate `prior_attempt` so the server can record what didn't work and steer alternative spellings.
Parameters (10)
patternstringrequired
Rust regex pattern (ripgrep engine). Case-insensitive by default. Prefer narrow, single-token patterns over kitchen-sink alternations.
caseInsensitiveboolean
Default true. Set false for case-sensitive match.
categorystring
Limit to a doc category (e.g. discoveries, natives).
pathSubstringstring
Substring filter on relative doc path, e.g. 'weapons' or 'clothes/cloth_hash_names'.
limitinteger
contextBeforeinteger
Include N lines before each match (rg -B). Saves follow-up get_document calls when you need surrounding context.
contextAfterinteger
Include N lines after each match (rg -A).
filesOnlyboolean
Return only the list of matching paths (no per-line matches). Cheap for exploration before zoom-in.
multilineboolean
Allow `.` to match newlines and patterns to span lines (rg -U --multiline-dotall). Use for `(?s)foo.*bar` style.
prior_attemptobject
Populate ONLY when retrying after a previous grep_docs call returned no matches. Skip on first attempts.
lookup_native
Resolve a RedM/RDR3 SCRIPT native by hash or name — O(1), exact. Use whenever you see `Citizen.InvokeNative(0x...)`, `Citizen.invokeNative('0x...')`, `GetHashKey('NAME')`, or a SCREAMING_SNAKE_CASE native name (e.g. `SET_ENTITY_COORDS`, `GetPedHealth`) in Lua/JS/TS. NOT for game-data hashes (weapon/ped/animation names) — use `grep_docs`. Pass `hash` (0x… optional, case-insensitive) or `name` (exact first, ILIKE substring fallback). Returns name, hash, namespace, return type, params, description, full content, plus `findings[]` — community gotchas linked to that native. Inspect `findings[].id` and call `get_document({path: 'learning:<id>'})` for full body. Also returns `refDocs[]` — enum/flag value tables for that native (the constants to pass for params like flagId/attributeIndex/eventType). When `refDocs[].content` is set, it's the inline enum table — use those values directly. When `content` is null but `refDocs[].fetch` is present, the table was too large to inline — run that exact call (e.g. `get_document({ path: "refdoc:eEventType" })`) to get the full table; `refDocs[].preview` shows the first lines. github entries (no `fetch`) are url-only.
Parameters (4)
hashstring
Native hash, e.g. 0x09C28F828EE674FA (case-insensitive, 0x optional)
namestring
Native name, e.g. CAN_PLAYER_START_MISSION. Substring match if no exact hit.
namespacestring
Restrict to a namespace, e.g. PLAYER, ENTITY. Only used with `name`.
limitinteger
asset_lookup
Resolve a RedM game-data asset (ped model, weapon, object, door, vehicle) by exact name, 32-bit hash, or partial-name search. O(1) structured lookup against pre-parsed discoveries tables — replaces the common workflow of grepping `a_c_bear_01` in peds_list.lua, then cross-referencing RELATIONSHIP/README.md for its relationship group. Returns: type, name, normalized hash (`0x` + 8 uppercase hex), source file + line, plus type-specific metadata (peds get `variants` + `relationship`, weapons get `group`, doors get `coords` + `model_hash`, objects get `category`/`subcategory`). Catalog ~22,500 entries (mostly objects). Typical latency p50 ~15ms, p95 ~65ms.
NOT for:
- **Script natives** like `SET_ENTITY_COORDS`, `GetPedHealth`, or hashes from `Citizen.InvokeNative(0x...)` — use `lookup_native`. Native hashes are 64-bit (`0x06843DA7060A026B`); asset hashes are 32-bit (`0xBCFD0E7F`). Different namespaces, never collide.
- **Flag enums, settings, clipsets, scenario keys** like `CPED_CONFIG_FLAGS`, `MP_Style_Casual`, `mech_loco_m@`, `MAGGIE_SEAT_CHAIR_DESK_WRITING`. Those live as tokens in lua source but not in this catalog. Use `grep_docs`.
- **Behavior queries** ("which animal is the bear", "weapons in the lemat family") — use `semantic_search`.
Pass exactly ONE of `name` / `hash` / `search`. Optional `type` narrows to a category (useful when a fragment like "horse" hits both peds and vehicles). Note: `type` reflects the SOURCE FILE — the same asset name can exist under multiple `type`s. e.g. `mp006_p_mshine_int_door01x` appears as `type=object` (1 row from object_list.lua) AND `type=door` (2 rows from doorhashes.lua, different door hashes for distinct in-world instances with `coords`). Pick `type=door` when you want lockable in-world doors with positions; `type=object` for the model itself.
Examples:
- `{name: "a_c_bear_01"}` → exact ped lookup, returns variants=11 + relationship=REL_WILD_ANIMAL_PREDATOR.
- `{hash: "0xBCFD0E7F"}` → resolves to ped `a_c_bear_01` (omit `0x` ok).
- `{search: "lemat", type: "weapon"}` → substring match → `weapon_revolver_lemat`.
- `{search: "moonshine", type: "door"}` → exact substring misses (no door name contains "moonshine"), fuzzy trigram fallback fires → `mp006_p_mshine_int_door01x`. Fuzzy mainly fires when `type` narrows out the exact-substring matches; without `type`, common terms find substring hits first and never reach fuzzy.
Parameters (5)
namestring
Exact asset name, case-insensitive. Examples: `a_c_bear_01`, `weapon_pistol_volcanic`, `p_safe01`, `armysupplywagon`. Use when you know the precise name.
hashstring
Asset hash (32-bit jenkins) in HEX format, case-insensitive, `0x` prefix optional. Examples: `0xBCFD0E7F`, `bcfd0e7f`. Use when you have a hash from decompiled code or another table and need the canonical name + metadata. Decimal-formatted hashes (e.g. `1946191463`) are NOT accepted — convert to hex first (`(1946191463).toString(16)`).
searchstring
Substring fragment within asset name, case-insensitive. Examples: `lemat`, `norfolk`, `volcanic`. Use when you remember part of the name. Algorithm: exact substring (ILIKE) first; if zero hits, falls back to pg_trgm `strict_word_similarity` ≥0.4 — catches abbreviation gaps like `moonshine`↔`_mshine_` when narrowed by `type` (without `type`, common terms find substring matches first and fuzzy never fires). `matchType` in the response tells you which path hit: `search` = exact substring, `fuzzy` = trigram.
typestring
Filter results to one category. Useful when a name fragment matches multiple types (e.g. `horse` hits peds + vehicles).
limitinteger
Max matches to return. Default 5, max 50. Only applies to `search` — exact `name`/`hash` always return 0 or 1.
share_finding
Share a verified finding back to the docs corpus so the next agent can find it. Use AFTER solving a non-trivial problem to record what would have saved you time: a gotcha, a working parameter combo, an undocumented constraint, a relationship between two natives that isn't obvious. Other agents will find this via `semantic_search` (findings are merged into default results; `category: 'learnings'` returns only findings).
WHEN to use:
- You burned multiple iterations on something not in the docs.
- You discovered an undocumented quirk (param order, hash collision, framework export that isn't in `vorp`/`rsgcore`).
- You verified that a specific combination works (e.g. native A + flag B for behavior C).
WHEN NOT to use:
- The information is already in the docs (verify with `semantic_search`/`grep_docs` first).
- You're guessing — only contribute verified findings.
- It's project-specific (your repo's auth flow, your DB schema). Keep it general to RedM/RDR3.
Keep `title` short and searchable. `body` should explain WHY, not just WHAT — context, the trap, the fix.
Parameters (5)
titlestringrequired
Short, searchable summary of the finding.
bodystringrequired
Markdown explaining WHY: context, the trap, the fix, verified behavior.
tagsarray
Up to 8 lowercase tags, e.g. ['weapons', 'damage'].
categorystring
Optional doc category this relates to.
sourcestring
Optional short identifier of the contributing agent.
get_invoke_guide
Load the calling-convention reference for RedM/RDR3 natives in `js` or `lua`. Call ONCE per session before writing native-calling code — every native doc page only shows Lua examples, so JS/TS authors need this to translate correctly. Covers result modifiers (`Citizen.resultAsInteger/Float/String/Vector`), `Citizen.invokeNative` vs `invokeNativeByHash`, type mapping, pointer-arg gotchas, worked examples. Cheap, no embedding.
Model Context Protocol (MCP) server for RedM / RDR3: native lookups (hash ↔ name), semantic search, framework docs (VORP, RSGCore, oxmysql), and the rdr3_discoveries community data (peds, weapons, animations, AI flags, props, audio banks). Gives AI coding agents (Claude Code, Cursor, Claude Desktop, VS Code Copilot, Zed, …) exact answers instead of guesses.
Runs as a hosted HTTP-transport MCP at https://redm-mcp.fivem.no/mcp — no local install, no auth, just point your client at it.
This repository contains only installation/usage docs and serves as the issue tracker. The server source code is proprietary and not distributed. The hosted endpoint is free to use.
Why
When an agent reads RedM code it typically encounters:
The server advertises its own usage via MCP instructions — no skill or extra client config needed.
Tools
Tool
Use
lookup_native
Exact lookup by hash or name. O(1). Use for Citizen.InvokeNative(0x...) or SCREAMING_SNAKE_CASE names.
semantic_search
Search by behavior/concept ("teleport player", "spawn horse").
grep_docs
Regex/literal grep across raw doc files. Required for the large rdr3_discoveries data tables (audio_banks, ingameanims, …) which are only preview-indexed in embeddings.
list_namespaces
List categories and namespaces.
browse
List document paths under a category/namespace.
get_document
Fetch full markdown for a doc path.
Client setup
All clients connect to https://redm-mcp.fivem.no/mcp. No authentication required.
VS Code and Cursor users: click an install badge above for one-click setup. For everything else, copy-paste the config below — also available as ready-made files in examples/.
Claude Code
bash
claude mcp add --transport http redm-mcp https://redm-mcp.fivem.no/mcp
Restart Cursor. Check Settings → MCP for green status.
Claude Desktop
Claude Desktop doesn't support HTTP MCP directly — use mcp-remote as a proxy. Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):