An MCP server exposing Southeast Asian language tools — variant detection, translation + localization, and safety classification — backed by AI Singapore's hosted SEA-LION API.
What this is. A specialist sidecar for agents, not a replacement for your main model. Your assistant keeps doing general reasoning; SEA-LION gets called when Southeast Asian language, culture, or safety is the bottleneck.
Status. v0.1, pre-alpha. Three tools, MCP stdio and HTTP transports, hosted backend only. See CLAUDE.md for the v0.1 plan.
| Tool | Use it when |
|---|---|
detect_language_variant |
Routing primitive. Call first — returns language, regional variant (e.g. singapore_colloquial_english), code-switching flag, register. |
translate_localize |
Translation plus localization notes. The notes are the differentiator — every non-literal choice is surfaced for review. Supports tone and reading-level controls. |
safety_check |
SEA-Guard wrapper. Three modes: prompt_only, prompt_response, response_only. Returns {safe, category, raw_output} where category is the stable enum safe | sensitive_content. Advisory only — not a decisional moderation system. |
The following examples show the tools in action inside LM Studio.
Colloquial Malay detection — the host agent identifies bahasa_malay_colloquial and explains the meaning and cultural context of an informal complaint.
Jakarta localization — translate_localize produces two register variants: standard Indonesian and Gen Z / "Jaksel" style with code-switching, with notes on why each choice works for the target demographic.
Singlish safety check — safety_check flags a forum comment containing a derogatory nationalities slur, returning safe: false, category: sensitive_content, without the host model needing to know the SEA context itself.
Manglish + AWS docs — the host agent runs detect_language_variant first (Manglish code-switching), then searches AWS documentation, and finally answers the S3 versioning question back in the user's own register.
To try out the MCP server, get a SEA-LION API key and proceed to set up your AI interface, using https://api.sea-lion.ai/mcp/sealion as the server URL, and insert your API key as per the setup instructions.
To deploy your own MCP server, proceed with the following instructions from Install onwards.
git clone https://github.com/aisingapore/sealion-sidecar.git
cd sealion-sidecar
uv syncRequires Python 3.13+. uv is the recommended package manager.
-
Sign in at the SEA-LION Playground with Google.
-
Open the API Key Manager and generate a key. Copy or download it immediately — you can't view it again.
-
Export it:
export SEALION_API_KEY=sk-...Add it to your shell rc for persistence.
Rate limit is 10 requests/minute per user as of March 2025. Contact sealion@aisingapore.org for an increase before a demo.
Local deployment (stdio or direct sealion mcp):
mkdir -p ~/.sealion
cp config.example.yaml ~/.sealion/config.yamlDocker — copy to the repo root instead; it gets volume-mounted into the container:
cp config.example.yaml config.yamlEdit profiles or routing as needed. Four profiles ship pre-wired:
| Profile | Model | Used by |
|---|---|---|
standard |
Gemma-SEA-LION v4 27B | detect_language_variant, default fallback |
best-language |
Gemma-SEA-LION v4 27B | translate_localize |
reasoning |
Llama-SEA-LION v3.5 70B (thinking_mode: on) |
(none in v0.1 — reserved for future tools) |
safety |
aisingapore/SEA-Guard alias |
safety_check. Pin to aisingapore/Gemma-SEA-Guard-12B-2602 for the explicit largest variant. |
uv run sealion doctorVerifies config loads, the API key is set, the endpoint is reachable, and every configured profile resolves to a model present in /v1/models. Sample output:
SEA-LION Sidecar — sealion doctor
config /Users/you/.sealion/config.yaml OK
api key SEALION_API_KEY OK
api https://api.sea-lion.ai/v1 OK (12 models available)
profiles
standard aisingapore/Gemma-SEA-LION-v4-27B-IT OK
best-language aisingapore/Gemma-SEA-LION-v4-27B-IT OK
reasoning aisingapore/Llama-SEA-LION-v3.5-70B-R OK
safety aisingapore/SEA-Guard OK
All checks passed.
Run the sidecar as a persistent HTTP server that multiple clients connect to over the network. The server holds no API key — each user passes their own AISG key as a header.
sealion mcp --port 8000This starts an HTTP server on 0.0.0.0:8000 using the streamable-http transport (MCP spec 2025-03-26). Options:
sealion mcp --host 127.0.0.1 --port 9000 # custom host/port
sealion mcp --transport sse --port 8000 # older SSE protocol, for clients that don't yet support streamable-http
sealion mcp --transport stdio # local subprocess mode (see below)Clients connect to http://your-server:8000/mcp and include their key as a header. See each client's setup below.
API key fallback. By default the server rejects any request that arrives without an Authorization: Bearer header. If you want the server to fall back to its own env key for unauthenticated requests (e.g. a private internal deployment where clients don't supply keys), set allow_env_key_fallback: true in config.yaml under api:, or export SEALION_ALLOW_ENV_KEY_FALLBACK=true before starting the server. When a valid Bearer key is present it is always used regardless of this flag.
Requires Docker with the Compose plugin.
1. Create a config file (the container expects it at ./config.yaml):
cp config.example.yaml config.yaml
# edit profiles or routing as neededconfig.yaml is gitignored — it's instance-specific. The API key does not go here; clients pass it per-request as a header.
2. Start the server:
docker compose up --buildThe server starts on http://localhost:8000/mcp. On subsequent starts, omit --build unless you've changed the source.
3. Verify it's running:
docker compose exec sealion sealion doctorConnecting an MCP client is the same as server-hosted mode — point it at http://your-host:8000/mcp with Authorization: Bearer sk-.... See Wire into your agent below.
Custom port:
# docker-compose.yaml → ports: "9000:8000"
# or override at runtime:
PORT=9000 docker compose upSwitching to SSE transport (for clients that don't support streamable-http yet):
# docker-compose.yaml
command: ["sealion", "mcp", "--transport", "sse", "--host", "0.0.0.0", "--port", "8000"]Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"sealion": {
"type": "streamable-http",
"url": "https://your-server:8000/mcp",
"headers": {
"Authorization": "Bearer sk-..."
}
}
}
}Restart Claude Desktop. The three tools appear in the tools panel.
Ensure that your server URL has SSL certification (begins with
https://), if not you might not be able to configure the MCP server.
Spawns the sidecar as a subprocess on your machine. Use this if you're running the sidecar locally rather than connecting to a server.
{
"mcpServers": {
"sealion": {
"command": "uv",
"args": ["--directory", "/absolute/path/to/SEA-LION_mcp", "run", "sealion", "mcp", "--transport", "stdio"],
"env": {
"SEALION_API_KEY": "sk-..."
}
}
}
}claude mcp add --transport http sealion http://your-server:8000/mcp \
--header "Authorization: Bearer sk-..."claude mcp add sealion -- uv --directory /absolute/path/to/SEA-LION_mcp \
run sealion mcp --transport stdioSet the API key in your shell environment (export SEALION_API_KEY=sk-...) before starting Claude Code, or add it to your shell rc.
Edit ~/.cursor/mcp.json:
{
"mcpServers": {
"sealion": {
"type": "streamable-http",
"url": "http://your-server:8000/mcp",
"headers": {
"Authorization": "Bearer sk-..."
}
}
}
}{
"mcpServers": {
"sealion": {
"command": "uv",
"args": ["--directory", "/absolute/path/to/SEA-LION_mcp", "run", "sealion", "mcp", "--transport", "stdio"],
"env": {
"SEALION_API_KEY": "sk-..."
}
}
}
}hermes mcp add sealion \
--url http://your-server:8000/mcp \
--header "Authorization=Bearer sk-..."
hermes mcp test sealionhermes mcp add sealion \
--command "uv --directory /absolute/path/to/SEA-LION_mcp run sealion mcp --transport stdio"
hermes mcp test sealionOpen LM Studio → Developer tab → MCP Servers, click Add, and paste:
{
"mcpServers": {
"sealion": {
"type": "streamable-http",
"url": "http://your-server:8000/mcp",
"headers": {
"Authorization": "Bearer sk-..."
}
}
}
}Save, then select a model and start a chat. The three tools appear in the tool-call panel.
In the same MCP Servers panel, add:
{
"mcpServers": {
"sealion": {
"command": "uv",
"args": ["--directory", "/absolute/path/to/SEA-LION_mcp", "run", "sealion", "mcp", "--transport", "stdio"],
"env": {
"SEALION_API_KEY": "sk-..."
}
}
}
}LM Studio spawns the sidecar as a subprocess. No separate server process needed.
One eval per tool, runnable locally:
uv run python -m sealion_sidecar.evals.detect_language_variant
uv run python -m sealion_sidecar.evals.safety_check
uv run python -m sealion_sidecar.evals.translate_localizeEach prints input → SEA-LION output → expected → PASS/FAIL on a small embedded dataset (4–6 examples). To compare against Claude:
uv sync --extra evals
export ANTHROPIC_API_KEY=sk-ant-...
uv run python -m sealion_sidecar.evals.detect_language_variant --baseline claudeDatasets are intentionally small — easy to grow as you find regressions. Mind the 10 req/min rate limit (evals run sequentially with retry-aware backoff).
uv sync --extra dev
uv run pytest
uv run ruff check sealion_sidecar/ tests/Adding a new tool means files in three parallel locations:
sealion_sidecar/
schemas/<tool>.input.json
schemas/<tool>.output.json
prompts/<tool>.md
tasks/<tool>.py # NAME, DESCRIPTION, input_schema(), async run()
evals/<tool>.py
Then add a @mcp.tool() decorated handler inside build_mcp() in mcp_server.py, import the task module there, and add a routing entry in config.example.yaml.
- Rate limit. 10 req/min per user for the SEA-LION API Key still applies to MCP calls as well.
safety_checkis advisory. SEA-Guard is a classifier, not a decisional moderation system. Thecategoryenum is intentionally two-value (safe,sensitive_content) — readraw_outputfor richer detail.- No streaming. Tools return single responses.
Call SEA-LION when a SEA language, regional slang or dialect, translation/localization for a SEA audience, regional safety moderation, or low-latency voice with local fluency is involved.
Don't call SEA-LION for general world knowledge, long strategic reasoning without a SEA dimension, or final high-stakes advice without verification.
The pattern: run detect_language_variant first; route to the right tool based on what comes back. This is what makes the sidecar a sidecar instead of a replacement.



