Skip to main content
Glama
README.md
# LLM Subagent MCP

English | [繁體中文](README_zhtw.md)

A FastMCP server that wraps OpenAI-compatible Chat Completions APIs, with TAIWAN AI RAP as the initial provider. ChatGPT or Claude Code acts as the parent assistant, delegates text tasks such as summarization, translation, or code review to a third-party LLM, and incorporates the result.

This is a **text task subagent**. Each call is independent and has no conversation memory. The subagent receives only the explicitly supplied `task`, `context`, and `instructions`. It has no access to the parent assistant's files, terminal, or tools, and cannot execute tool calls requested by the model.

## Installation and quick start

### Windows PowerShell

Install uv first, then run the following from the project root. These commands use uv from PATH when available, falling back to its default location in the user directory:

```powershell
$uv = if (Get-Command uv -ErrorAction SilentlyContinue) { 'uv' } else { Join-Path $env:USERPROFILE '.local\bin\uv.exe' }
$env:UV_PYTHON_INSTALL_DIR = Join-Path (Get-Location) '.uv-python'
& $uv --cache-dir .uv-cache sync --locked
Copy-Item .env.example .env
```

Set `LLM_API_KEY` in `.env`. Use the MCP `list_models` tool to find an available **chat model**, then set `LLM_MODEL` or pass `model` to `delegate_task`. The model list may also contain embedding or audio models that cannot be used with Chat Completions.

```powershell
& $uv --cache-dir .uv-cache run --locked llm-subagent-mcp --config providers.toml
```

The stdio server waits for MCP client input. Clients such as Claude Code normally start it automatically. To check the installation:

```powershell
.\.venv\Scripts\llm-subagent-mcp.exe --help
```

### Linux / macOS (Bash / Zsh)

Install uv using the [official installation instructions](https://docs.astral.sh/uv/getting-started/installation/). Skip this step if uv is already installed:

```sh
curl -LsSf https://astral.sh/uv/install.sh | sh
```

Open a new terminal afterward. If your current shell cannot find uv, run `export PATH="$HOME/.local/bin:$PATH"`. macOS users with Homebrew can also use `brew install uv`.

From the project root, create the environment and install dependencies. uv uses `.python-version` and downloads Python 3.12 if needed:

```sh
export UV_PYTHON_INSTALL_DIR="$PWD/.uv-python"
uv --cache-dir .uv-cache sync --locked
if [ ! -f .env ]; then
  cp .env.example .env
fi
chmod 600 .env
```

Edit `.env` and set `LLM_API_KEY`. Use `list_models` to find an available chat model, then set `LLM_MODEL` or specify `model` when calling the tool.

```sh
# Check the installed entry point
./.venv/bin/llm-subagent-mcp --help

# Start the stdio MCP server and wait for client input
uv --cache-dir .uv-cache run --locked llm-subagent-mcp --config providers.toml
```

These commands use the virtual environment directly; activation with `source .venv/bin/activate` is optional.

## Configuration

| Setting | Location | Behavior |
| --- | --- | --- |
| Base URL | `providers.toml`, optionally overridden through `base_url_env` | API root, including `/api/v1` or `/v1`, without `/chat/completions` |
| API key | Environment variable or `.env` beside the configuration file | TOML stores the variable name in `api_key_env`, not the secret |
| Model | Tool argument, `model_env`, or `default_model` | Priority: tool argument → environment variable → TOML default |
| Model restrictions | `allowed_models` | An empty list allows any explicitly selected model; a nonempty list restricts selection |
| MCP access token | `MCP_ACCESS_TOKEN` | A separate credential protecting the HTTP MCP endpoint |

Existing process environment variables take precedence over `.env`. The server loads `.env` relative to the file passed to `--config`, so launching from a different working directory still finds the correct settings.

The default variable names are provider-neutral: `LLM_BASE_URL`, `LLM_API_KEY`, and `LLM_MODEL`. For multiple providers, assign separate variable names through each provider's `base_url_env`, `api_key_env`, and `model_env`, such as `OTHER_LLM_API_KEY`.

Restart the MCP server after changing configuration. Add a provider by creating a `[providers.NAME]` section. Authentication defaults to `Authorization: Bearer`; the RAP profile uses `x-api-key`.

Tool callers cannot supply a base URL or API key directly. Those settings stay on the server, preventing individual tasks from redirecting credentials to arbitrary endpoints.

RAP's documentation describes authentication differently across pages: the API reference specifies Bearer authentication, while most usage-guide examples use `x-api-key`. Both are supported through `auth_mode = "x-api-key"` or `"bearer"`. The RAP profile follows the usage guide. Both methods have not been verified with live account credentials, and the server does not automatically retry with a different authentication method.

## MCP tools

- `list_providers()`: Returns configuration status, default models, and limits without exposing API keys.
- `list_models(provider?)`: Calls the provider's `/models` endpoint and applies the model allowlist.
- `delegate_task(task, context?, instructions?, provider?, model?, max_tokens?, temperature?)`: Calls `/chat/completions` and returns text, model, finish reason, a truncation flag, and token usage when supplied by the provider.

Defaults are four concurrent upstream requests, 100,000 input characters per task, and 4,096 output tokens per request. These limits are configurable in TOML.

The server omits `temperature` unless explicitly requested to improve compatibility across models. When supplied, it must be between 0 and 1, matching the RAP documentation.

Each task makes one non-streaming HTTP request with no automatic retries, avoiding hidden repeated billable requests. Limits apply per request and to concurrency; they are not daily spending limits or per-user quotas. HTTPX sends OpenAI-compatible JSON directly.

Cancellation propagates to the pending HTTP request. Whether the provider stops generation or billing depends on its implementation.

Example tool arguments:

```json
{
  "task": "Review this function for bugs and suggest improvements.",
  "context": "<code read and supplied by the parent assistant>",
  "instructions": "Distinguish confirmed bugs from issues requiring further investigation.",
  "provider": "rap",
  "max_tokens": 2048
}
```

## Claude Code: local stdio

Run the following from the project root. After installation, the client starts the virtual environment's executable directly without downloading packages at startup.

Windows PowerShell:

```powershell
$projectRoot = (Get-Location).Path
$serverPath = Join-Path $projectRoot '.venv\Scripts\llm-subagent-mcp.exe'
$configPath = Join-Path $projectRoot 'providers.toml'
claude mcp add --transport stdio rap-subagent -- $serverPath --config $configPath
```

Linux / macOS:

```sh
project_root="$(pwd -P)"
claude mcp add --transport stdio rap-subagent -- \
  "$project_root/.venv/bin/llm-subagent-mcp" \
  --config "$project_root/providers.toml"
```

Alternatively, see [examples/claude.mcp.json](examples/claude.mcp.json). This is a Windows example: replace `C:\path\to\llm-subagent-mcp` with the project's actual absolute path. On Linux / macOS, use `.venv/bin/llm-subagent-mcp`. Update the configuration if the project moves.

Example prompt:

> Use rap-subagent's list_models tool to find an available chat model. Send the following content to delegate_task for summarization, then incorporate the result: …

This provides task delegation through MCP tools. It does not automatically change the model used by Claude Code's native subagents.

## ChatGPT desktop: local stdio

According to the [official OpenAI MCP documentation](https://learn.chatgpt.com/docs/extend/mcp), supported ChatGPT desktop versions can add local stdio servers and share MCP configuration with Codex CLI on the same host.

Complete installation and set `LLM_API_KEY` in `.env` beside `providers.toml`. The desktop app starts the stdio process; no separate HTTP server is needed.

1. Open **Settings → MCP servers → Add server**.
2. Enter `llm-subagent` as the name and select **STDIO**.
3. Enter the command and arguments below, replacing placeholder paths with the project's actual absolute path.
4. Save, select **Restart**, and enter `/mcp` in the conversation to check server and tool status.

| Platform | Command | Arguments (two separate arguments) |
| --- | --- | --- |
| Windows | `C:\path\to\llm-subagent-mcp\.venv\Scripts\llm-subagent-mcp.exe` | `--config`, `C:\path\to\llm-subagent-mcp\providers.toml` |
| Linux / macOS | `/path/to/llm-subagent-mcp/.venv/bin/llm-subagent-mcp` | `--config`, `/path/to/llm-subagent-mcp/providers.toml` |

For file-based configuration, add this section to `~/.codex/config.toml` on Windows:

```toml
[mcp_servers.llm-subagent]
command = 'C:\path\to\llm-subagent-mcp\.venv\Scripts\llm-subagent-mcp.exe'
args = ['--config', 'C:\path\to\llm-subagent-mcp\providers.toml']
tool_timeout_sec = 180
```

On Linux / macOS, use:

```toml
[mcp_servers.llm-subagent]
command = '/path/to/llm-subagent-mcp/.venv/bin/llm-subagent-mcp'
args = ['--config', '/path/to/llm-subagent-mcp/providers.toml']
tool_timeout_sec = 180
```

The client tool timeout is set to 180 seconds, exceeding the project's default 120-second upstream timeout. Use only one example; do not add the same TOML section twice. Keep API keys in the project's `.env`.

Example prompt after connecting:

> Use llm-subagent. First call list_providers and list_models to select an available chat model. Then use delegate_task to summarize the following content, and organize the subagent's response: …

You can save the selected model ID as `LLM_MODEL` in `.env` and restart the MCP server to make it the default.

If startup fails, run the same executable with `--help` in a terminal and verify the `--config` path. If tools appear but requests fail, check `LLM_API_KEY`, the selected model, and provider settings. If the desktop settings entry is unavailable, check whether your app version and workspace support it. Cloud connections are described below.

## ChatGPT cloud / remote clients: Streamable HTTP

For local development, start the HTTP server from the project root.

Windows PowerShell:

```powershell
.\.venv\Scripts\llm-subagent-mcp.exe --config providers.toml --transport http
```

Linux / macOS:

```sh
./.venv/bin/llm-subagent-mcp --config providers.toml --transport http
```

The endpoint is `http://127.0.0.1:8000/mcp`. For network access, set a separate `MCP_ACCESS_TOKEN` in `.env`, start with `--host 0.0.0.0`, and place an HTTPS reverse proxy or protected tunnel in front of the service.

Token-based clients send `Authorization: Bearer <MCP_ACCESS_TOKEN>`. This is separate from `LLM_API_KEY`.

ChatGPT cloud connections depend on account and workspace capabilities and supported authentication flows. They require a reachable server URL or Secure MCP Tunnel for private services; they cannot directly use your computer's loopback URL. See the [official custom MCP connection guide](https://developers.openai.com/api/docs/guides/custom-mcp-server). For local desktop stdio, use the preceding section.

This version supports HTTP transport and fixed Bearer token verification, but **does not implement OAuth login, token issuance, or discovery**. Fixed tokens suit clients that can configure an Authorization header. If the ChatGPT connection requires OAuth, configure an OAuth gateway or FastMCP OAuth provider first. This project has not been deployed or registered with a ChatGPT account.

## Validation

Windows PowerShell:

```powershell
.\.venv\Scripts\python.exe -m pytest -q
.\.venv\Scripts\ruff.exe check src tests
```

Linux / macOS:

```sh
./.venv/bin/python -m pytest -q
./.venv/bin/ruff check src tests
```

Tests use mocked upstream responses and do not consume RAP credits. They cover MCP tool calls, authentication headers, model selection, limits, error sanitization, and startup.

Live model access, account quotas, and full RAP response compatibility require testing with an actual RAP API key.

## Official references

Documentation reviewed on November 5, 2026.

- [RAP multi-model service overview](https://rap.genai.nchc.org.tw/doc?section=multi-model-api): embeds the official RAP documentation.
- [RAP API usage guide](https://rap-docs.genai.nchc.org.tw/docs/sw_intro/core_features/api_usage/API%20%E5%8A%9F%E8%83%BD%E6%8C%87%E5%8D%97/): `https://portal.genai.nchc.org.tw/api/v1`, model and chat endpoints, and `x-api-key` examples.
- [RAP API reference](https://rap-docs.genai.nchc.org.tw/docs/api/taiwan-ai-rap-api/): OpenAI / LiteLLM compatibility and Bearer authentication.
- [FastMCP transports](https://gofastmcp.com/deployment/running-server) and [token verification](https://gofastmcp.com/servers/auth/token-verification).
- [Claude Code MCP](https://code.claude.com/docs/en/mcp) and [OpenAI MCP integration](https://developers.openai.com/api/docs/mcp).
- [ChatGPT desktop MCP configuration](https://learn.chatgpt.com/docs/extend/mcp) and [ChatGPT cloud custom MCP connections](https://developers.openai.com/api/docs/guides/custom-mcp-server).