Skip to main content
Glama
README.md
# FM8 MCP Server

AI-controlled Native Instruments FM8 synthesizer via MIDI and Model Context Protocol.

## What This Does

Lets Claude Desktop (or other MCP clients) control your FM8 synthesizer by sending MIDI CC messages through a virtual MIDI port.

## Requirements

- Node.js 18+
- Native Instruments FM8
- Virtual MIDI port software:
  - **Windows**: [loopMIDI](https://www.tobias-erichsen.de/software/loopmidi.html)
  - **macOS**: IAC Driver (built-in)

## Quick Start

git clone https://github.com/thesigma1receptor/fm8MCP.git
cd fm8MCP
npm install
npm run build


## Setup Virtual MIDI

### Windows
1. Install and run loopMIDI
   https://www.tobias-erichsen.de/software/loopmidi.html
2. Remove any existing ports
3. Create port named `fm8`

### macOS
1. Open Audio MIDI Setup
2. Window → Show MIDI Studio
3. Double-click IAC Driver
4. Enable "Device is online"
5. Create port named `fm8`

### Configure FM8
1. Set MIDI input to `fm8` port by clicking off/on, change to on
2. Go to Master tab and load included MCP.f8c file
3. Right click any operators that are off to enable them

## Claude Desktop Setup

Edit your Claude config file:

**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`  
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`

Included in repo, or amend yours with:

{
  "mcpServers": {
    "fm8": {
      "command": "node",
      "args": [
        "C:/path/to/fm8-mcp-server/dist/server.js",
        "--transport=stdio",
        "--midi-port-name=fm8",
        "--channel=1"
      ]
    }
  }
}

Restart Claude Desktop and you're ready!

## AnythingLLM Setup

**Requirements**: Ollama with `llama3.1` or `qwen2.5:4b` minimum

Edit: `%APPDATA%\anythingllm-desktop\storage\plugins\anythingllm_mcp_servers.json`

Included in repo, or amend yours with:

{
  "fm8": {
    "name": "FM8 Control",
    "command": "node C:/path/to/fm8-mcp-server/dist/server.js",
    "args": ["--transport=stdio", "--midi-port-name=fm8", "--channel=1"],
    "env": {},
    "cwd": "C:/path/to/fm8-mcp-server"
  }
}

1. Restart AnythingLLM
2. Enable MCP server in workspace settings
3. Use `@agent` in chat to access tools

## What You Can Control

### FM8 Matrix (CC 0-62)
All operator-to-operator modulation routes (A→B, B→C, etc.)

### Operator Outputs (CC 63-70)
Operator-to-Output levels (A→Out, B→Out, etc.)

### Frequency Ratios (CC 72-77)
Harmonic/inharmonic relationships for each operator

See `mappings.json` for complete CC reference.

## Example Claude Prompts

- "Create an FM bell sound"
- "Set operator A to modulate B at 75%"
- "Make a pure sine wave"
- "Route operator C to output at full volume"
- "Show all available FM8 controls"

If you want to give Claude free reign to try things: 

-"Ratios are from 0 - 64:1, 127 being 64, feel free to look up fm synthesis techniques. There 8 operators, A-F are pure sine waves, X is a noise oscillator and Z is a filter. Let's see what you can come up with!" 

## Make it your own! 

If you want to add any functionality, ie, more midi cc, use the standalone fm8, turn on midi learn and I used touchosc to make ~80 controls and map things. Look at mappings.json and add start with cc #78. 

There are also ways with mcp to give claude memory and better instructions. So he could potentially learn how to make complex sounds. 

## Tip

This also works from VSCode with copilot. 

Start server: `node C:\fm8MCP\dist\server.js --transport=stdio --midi-port-name=fm8 --channel=1`

Example command for agent: 

`node -e "const easymidi = require('easymidi'); const out = new easymidi.Output('fm8'); console.log('⚡ Creating neuro bass...'); out.send('cc', {controller: 0, value: 95, channel: 0}); setTimeout(() => out.send('cc', {controller: 1, value: 110, channel: 0}), 20); setTimeout(() => out.send('cc', {controller: 8, value: 105, channel: 0}), 40); setTimeout(() => out.send('cc', {controller: 9, value: 90, channel: 0}), 60); setTimeout(() => out.send('cc', {controller: 17, value: 100, channel: 0}), 80); setTimeout(() => out.send('cc', {controller: 63, value: 127, channel: 0}), 100); setTimeout(() => out.send('cc', {controller: 64, value: 110, channel: 0}), 120); setTimeout(() => { console.log('🎵 Neuro bass loaded! Play low notes (C1-C2)'); process.exit(0); }, 400);"`

## Troubleshooting

**No MIDI signal**
- loopMIDI/IAC running?
- FM8 input set to `fm8` port?
- MIDI channel matches (default: 1)?

**Server won't start**
- Run `npm run build` first
- Check Node version: `node --version`

**Claude can't find it**
- Use absolute paths in config
- Forward slashes even on Windows
- Restart Claude after config changes

## License

MIT