# How to Add Custom File Extensions for Unsupported Types in codebase-memory-mcp

> Easily add custom file extensions for unsupported types in codebase-memory-mcp by updating your config.json or .codebase-memory.json file. Map any unknown extension to a supported language.

- Repository: [Martin Vogel/codebase-memory-mcp](https://github.com/DeusData/codebase-memory-mcp)
- Tags: how-to-guide
- Published: 2026-07-06

---

**Map any unknown file extension to a supported language by adding an `extra_extensions` object to your global [`config.json`](https://github.com/DeusData/codebase-memory-mcp/blob/main/config.json) or per-project [`.codebase-memory.json`](https://github.com/DeusData/codebase-memory-mcp/blob/main/.codebase-memory.json) file.**

The `codebase-memory-mcp` engine natively recognizes 158 programming languages, silently ignoring files with unrecognized extensions during the discovery phase. To include these files in the knowledge graph and enable tools like `search_graph` and `trace_path` to operate on them, you must explicitly declare how custom extensions map to known language IDs.

## Why Custom File Extensions Are Ignored

During the discover phase, the engine scans the filesystem and queries the language resolver for a `CBMLanguage` ID. If the extension is absent from the built-in table, the resolver cannot determine which Tree-sitter grammar to apply, causing the file to be skipped entirely. This prevents binary or irrelevant files from entering the index, but it also blocks legitimate source files using non-standard or template-specific extensions.

## Configuration File Locations and Precedence

The engine loads extension mappings from JSON files in two distinct scopes. Project-level settings always override global settings for the same extension key.

### Global Configuration (All Projects)

Create or edit the file at:

```bash
$XDG_CONFIG_HOME/codebase-memory-mcp/config.json

```

If `XDG_CONFIG_HOME` is unset, the engine falls back to:

```bash
~/.config/codebase-memory-mcp/config.json

```

### Per-Project Configuration

Create a file named [`.codebase-memory.json`](https://github.com/DeusData/codebase-memory-mcp/blob/main/.codebase-memory.json) in your repository root. This file takes precedence over the global configuration for that specific project.

### Configuration Merging Logic

In [`src/discover/userconfig.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/discover/userconfig.c), the function `cbm_userconfig_load()` orchestrates the loading sequence. It first calls `load_config_file()` on the global path, then on the project path. After both files are parsed, a deduplication pass removes any global entry that shares the same extension key as a project entry, ensuring local settings always win.

## The extra_extensions Schema

The parsing routine `parse_extra_extensions()` (lines 166-176 in [`src/discover/userconfig.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/discover/userconfig.c)) validates entries with strict rules:

- The root JSON must be an object.
- The key `"extra_extensions"` must contain an object value.
- Each extension key must start with a dot (`.`).
- The language value is matched case-insensitively via `lang_from_string()`; unknown languages trigger a warning and are ignored.
- Valid mappings are stored in a dynamically-grown `cbm_userext_t` array.

## Practical Configuration Examples

### Global Mapping for Common Template Extensions

Add mappings that apply to every repository on your system:

```json
// ~/.config/codebase-memory-mcp/config.json
{
  "extra_extensions": {
    ".blade.php": "php",
    ".mjs": "javascript",
    ".twig": "html"
  }
}

```

### Per-Project Overrides

Create a [`.codebase-memory.json`](https://github.com/DeusData/codebase-memory-mcp/blob/main/.codebase-memory.json) in your repository root to override global settings or define project-specific extensions:

```json
// .codebase-memory.json
{
  "extra_extensions": {
    ".mytmpl": "html",
    ".xyz": "python"
  }
}

```

Only this repository will recognize `.mytmpl` and `.xyz` files; other projects continue to use the global configuration.

### Verify Your Configuration

After saving the configuration file, restart the MCP server or run any MCP command to trigger a reload. Confirm the extensions are recognized by examining the graph schema:

```bash
codebase-memory-mcp cli get_graph_schema

```

Alternatively, search for symbols residing within custom extension files:

```bash
codebase-memory-mcp cli search_graph '{"label":"Function","name_pattern":"MyFunc"}'

```

## How the Engine Processes Your Mappings

Before indexing begins, the discover pipeline consults the `extra_extensions` table populated by the user-config loader. When encountering a file with a custom extension, the resolver checks this table after failing the built-in lookup. If a match exists, the file is parsed with the corresponding Tree-sitter grammar and participates in Hybrid-LSP type resolution, making it fully available to all subsequent MCP tooling.

The validation logic implemented in [`src/discover/userconfig.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/discover/userconfig.c) appears as follows:

```c
/* Simplified excerpt from src/discover/userconfig.c */
static int parse_extra_extensions(yyjson_val *root,
                                   cbm_userext_t **entries, int *count,
                                   const char *source_label) {
    yyjson_val *extra = yyjson_obj_get(root, "extra_extensions");
    if (!extra || !yyjson_is_obj(extra)) return 0;

    yyjson_obj_iter iter;
    yyjson_obj_iter_init(extra, &iter);
    yyjson_val *key;
    while ((key = yyjson_obj_iter_next(&iter)) != NULL) {
        const char *ext = yyjson_get_str(key);
        const char *lang = yyjson_get_str(yyjson_obj_iter_get_val(key));

        if (!ext || !lang || ext[0] != '.') continue;
        CBMLanguage l = lang_from_string(lang);
        if (l == CBM_LANG_COUNT) continue;

        // store the mapping …
    }
    return 0;
}

```

## Summary

- `codebase-memory-mcp` supports 158 built-in languages; unrecognized extensions are ignored by default.
- Add custom mappings via the `extra_extensions` object in `~/.config/codebase-memory-mcp/config.json` (global) or [`.codebase-memory.json`](https://github.com/DeusData/codebase-memory-mcp/blob/main/.codebase-memory.json) (project-level).
- Project settings override global settings for identical extensions as implemented in `cbm_userconfig_load()`.
- Extensions must start with a dot and map to valid language names recognized by `lang_from_string()`.
- Changes take effect immediately after restarting the MCP server; no recompilation is required.

## Frequently Asked Questions

### Can I map a custom extension to any language name?

The language value must correspond to a supported language identifier in the engine. The parser uses `lang_from_string()` to validate the mapping case-insensitively. If you provide an unknown language string, the entry is skipped and a warning is logged to stderr.

### Do I need to rebuild the MCP server after editing the configuration?

No. The configuration is read at runtime by `cbm_userconfig_load()` in [`src/discover/userconfig.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/discover/userconfig.c). Simply restart the MCP server or trigger any MCP command to reload the configuration and apply your new mappings.

### What happens if I define the same extension in both global and project files?

The per-project [`.codebase-memory.json`](https://github.com/DeusData/codebase-memory-mcp/blob/main/.codebase-memory.json) takes precedence. The deduplication logic in `cbm_userconfig_load()` removes conflicting global entries after both files are parsed, ensuring repository-specific settings always win.

### Where can I find the list of supported language names?

Refer to the [`docs/CONFIGURATION.md`](https://github.com/DeusData/codebase-memory-mcp/blob/main/docs/CONFIGURATION.md) file in the repository or examine the `lang_from_string()` implementation in the source code to see the valid identifiers for the 158 supported languages.