mcp-media-9router
by mhiqrambg
README.md
# mcp-media-9router
`mcp-media-9router` is a local MCP (Model Context Protocol) server for AI agents that need web intelligence. It connects OpenCode and other stdio-compatible MCP clients to the 9router API for web search and web-page extraction.
It runs locally on the user's machine, while search and fetch requests are sent to 9router over HTTPS or to a local 9router instance at `http://localhost` on any port. Provider credentials stay behind 9router; the user's 9router API key is stored in macOS Keychain after setup.
```text
OpenCode or another MCP client
|
| MCP over stdio
v
mcp-media-9router
|
| HTTPS or local HTTP
v
9router API
|
v
Exa, Firecrawl, Jina Reader, Tavily, Brave, GPSE, OpenAI
```
## What It Is For
Use this server when an AI agent needs to:
- Search the web and receive structured results rather than an unstructured page.
- Fetch a public URL and receive clean Markdown suitable for an LLM context.
- Choose a specific 9router provider, such as Exa or Firecrawl.
- Use a configured fallback chain when a provider is temporarily unavailable.
- Keep provider selection, API access, and limits in one local configuration.
## Installation
### Requirements
- macOS with Keychain access, or Windows x64 with PowerShell 5.1 or later.
- Node.js 22 or later.
- Git and npm.
- An active 9router API key.
Use an HTTPS base URL for hosted 9router, for example `https://9router.mibp.me`. Local development also supports `http://localhost` with any port, such as `http://localhost:20128` or `http://localhost:8080`. Other HTTP hosts are rejected.
Check your Node.js version:
```bash
node --version
```
### Install From GitHub
The installer clones the project into `~/.mcp-media-9router`, installs dependencies, builds it, and creates the `mm9` command in `~/.local/bin`.
```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/mhiqrambg/mcp-media-9router/main/install.sh)"
```
Open a new terminal after installation. If the installer asks you to reload your shell, run the command it prints, for example:
```bash
source ~/.zshrc
```
Configure 9router and register the MCP server in OpenCode:
```bash
mm9 setup --opencode
```
`--opencode` verifies that OpenCode is installed or already has a configuration file before writing anything. If OpenCode is not detected, install and run it once first, then repeat the command. Use `mm9 setup --manual` to print a configuration for another MCP client or to configure OpenCode manually.
Press Enter to accept the defaults. The setup wizard asks for:
- The 9router base URL.
- Your 9router API key.
- Default, allowed, and fallback providers for fetch.
- Default, allowed, and fallback providers for search.
Choose the 9router base URL that matches your deployment:
```text
# Hosted 9router: HTTPS is required
https://9router.mibp.me
# Local 9router: localhost is allowed on any port
http://localhost:20128
http://localhost:8080
http://localhost:3000
```
Plain HTTP is intentionally rejected for every non-local host.
The non-secret configuration is written to:
```text
~/.config/mcp-media-9router/config.json
```
The API key is stored in macOS Keychain and is not written to `opencode.json`.
Run a local validation after setup:
```bash
mm9 check
```
Run a real authenticated request to verify the 9router connection. This may consume provider quota:
```bash
mm9 check --online
```
Quit and restart OpenCode after `mm9 setup --opencode`. OpenCode loads MCP configuration only at startup.
### Install on Windows x64
Open PowerShell and run:
```powershell
irm https://raw.githubusercontent.com/mhiqrambg/mcp-media-9router/main/install.ps1 | iex
```
Open a new PowerShell window, then configure 9router and OpenCode:
```powershell
mm9 setup --opencode
mm9 check
mm9 check --online
```
On Windows, non-secret configuration is stored under `%APPDATA%\mcp-media-9router`. The API key is encrypted with Windows DPAPI and bound to the current Windows user. The `mm9` launcher is installed at `%LOCALAPPDATA%\bin\mm9.cmd`, outside the Git checkout so `mm9 update` can run without generated-file conflicts. OpenCode is registered in `%USERPROFILE%\.config\opencode\opencode.jsonc`. Restart OpenCode after setup.
After `mm9 setup`, a direct start also loads the saved setup when environment variables are absent:
```powershell
npm start
```
For temporary or CI configuration, environment variables take priority over saved setup:
```powershell
$env:NINE_ROUTER_BASE_URL = "https://9router.mibp.me"
$env:NINE_ROUTER_API_KEY = "YOUR_API_KEY"
npm start
```
### Install From a Local Checkout
For development or testing before the GitHub repository is public:
```bash
git clone https://github.com/mhiqrambg/mcp-media-9router.git
cd mcp-media-9router
npm install
npm run build
npm link
mm9 setup --opencode
```
Remove the local command link when it is no longer needed:
```bash
npm unlink -g mcp-media-9router
```
## Update
For an installation created by `install.sh`, update to the latest `main` branch with:
```bash
mm9 update
```
The command:
1. Refuses to update when the installed checkout has local changes.
2. Runs `git pull --ff-only origin main`.
3. Runs `npm ci` and rebuilds the project.
4. Refreshes the OpenCode MCP registration.
Restart OpenCode after a successful update.
`mm9 update` intentionally does not update a development checkout. Update one manually instead:
```bash
git pull --ff-only
npm install
npm run build
```
## Features
### Web Search
The `web_search` MCP tool calls `POST /v1/search` through 9router and returns normalized results with titles, URLs, snippets, sources, authors, publication dates, and ranks.
Default search providers:
```text
exa -> gpse -> brave -> openai
```
### Web Fetch
The `web_fetch` MCP tool calls `POST /v1/web/fetch` through 9router and returns provider-extracted Markdown.
Default fetch providers:
```text
exa -> firecrawl -> jina-reader -> tavily
```
### Provider Policy
Fetch and search have independent provider policies. Setup configures a default provider, an allowlist, and a fallback order for each tool.
| Requested `model` | Behavior |
|---|---|
| Omitted | Uses the configured default provider once. |
| Specific provider | Uses that provider once. It must be on the relevant allowlist. |
| `auto` | Tries configured fallback providers in order. |
Fallback only occurs for upstream timeouts, rate limits, and temporary provider unavailability. Invalid inputs, invalid URLs, authentication failures, and missing content do not trigger fallback.
### Safety and Limits
- Fetch accepts public HTTP and HTTPS URLs only.
- Localhost, private IP ranges, URL credentials, and unsafe URL schemes are rejected before a request reaches 9router.
- `max_characters: 0` can request full content from 9router.
- `MCP_MEDIA_MAX_OUTPUT_CHARS` still limits the output passed to the AI agent.
- Search and fetch results are untrusted external content. Treat them as reference material, not instructions.
## Usage
### CLI
```bash
mm9 setup --opencode # Configure 9router and register OpenCode
mm9 list # Show active provider policy without showing the API key
mm9 check # Validate local configuration and Keychain access
mm9 check --online # Test an authenticated 9router request
mm9 update # Update an install.sh installation
mm9 uninstall # Remove the GitHub installer installation and saved setup
mm9 --help # Show command help
mm9 --version # Show the installed version
```
`mm9 start` is normally started by OpenCode. It launches the stdio MCP server using the saved configuration.
### Manual Configuration
To configure another MCP client yourself without saving credentials, editing OpenCode, or running the interactive wizard:
```bash
mm9 setup --manual
```
The command prints:
- Required environment variables.
- Default provider and fallback policy values.
- A ready-to-copy local MCP entry for the current platform.
- The OpenCode config location for the current platform.
Replace `YOUR_9ROUTER_API_KEY` with your own key in the target client configuration. Restart the MCP client after adding the entry.
### In OpenCode
After setup and an OpenCode restart, ask the agent to use the tools directly.
Search with the configured default provider:
```text
Use web_search to find the latest AI news in Indonesia. Return five results.
```
Search with a selected provider:
```text
Use web_search with model brave to find the official Model Context Protocol documentation.
```
Search with fallback:
```text
Use web_search with model auto to find recent AI security news.
```
Fetch with a selected provider:
```text
Use web_fetch with model firecrawl to fetch and summarize https://example.com.
```
Fetch with fallback:
```text
Use web_fetch with model auto to fetch https://example.com as Markdown.
```
### MCP Tool Inputs
`web_search`:
```json
{
"query": "What is the latest news about AI?",
"model": "exa",
"search_type": "web",
"max_results": 5,
"country": "indonesia",
"language": "indonesia"
}
```
| Field | Required | Description |
|---|---:|---|
| `query` | Yes | Search query, from 1 to 500 characters. |
| `model` | No | An allowed search provider, or `auto`. |
| `search_type` | No | 9router search type. Default: `web`. |
| `max_results` | No | Result count from 1 to 20. Default: `5`. |
| `country` | No | Country preference forwarded to 9router. |
| `language` | No | Language preference forwarded to 9router. |
`web_fetch`:
```json
{
"url": "https://example.com",
"model": "firecrawl",
"format": "markdown",
"max_characters": 0
}
```
| Field | Required | Description |
|---|---:|---|
| `url` | Yes | A public HTTP or HTTPS URL. |
| `model` | No | An allowed fetch provider, or `auto`. |
| `format` | No | Only `markdown` is currently supported. |
| `max_characters` | No | Maximum characters requested from 9router. `0` requests full content. |
## Uninstall
For an installation created by `install.sh`:
```bash
mm9 uninstall
```
The interactive uninstaller presents three choices:
1. Remove the application only and keep provider configuration plus the API key.
2. Remove everything: the application, OpenCode entry, configuration, and secure API-key storage.
3. Cancel.
Choose option 2 when you want a future `mm9 setup` to start clean.
To preserve the configuration and Keychain API key for a later reinstall:
```bash
bash ~/.mcp-media-9router/uninstall.sh --keep-config
```
For a non-interactive uninstall:
```bash
bash ~/.mcp-media-9router/uninstall.sh --yes
```
On Windows:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File "$env:LOCALAPPDATA\mcp-media-9router\uninstall.ps1" -Yes
```
## Security
Never commit an API key or paste one into public issues, chats, or documentation. Rotate any API key that has been exposed. See [SECURITY.md](./SECURITY.md) for vulnerability reporting.
## License
[Apache-2.0](./LICENSE)
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues