sg-eli-mcp
# sg-eli-mcp
<!-- mcp-name: io.github.matematicsolutions/sg-eli-mcp -->
An MCP server for **Singapore Statutes Online** (SSO, `sso.agc.gov.sg`), the Attorney-General's
Chambers' official portal for Singapore legislation. It browses, fetches, and cites Acts, with
a verifiable citation on every response.
Part of the MateMatic `eu-legal-mcp` production line, extended into Asia alongside `jp-eli-mcp`.
Same citation contract (a stable identifier + a human-readable citation + a source URL),
adapted for a jurisdiction with no ELI and no public search API.
> **Scope.** SSO's `robots.txt` disallows `/search`; discovery here is by browsing the current
> Acts listing (`sg_list_acts`, paginated), not by title or keyword query. Fetch a specific
> section (`sg_get_provision`) or the full text (`sg_get_full_text`, truncated for very large
> Acts). Every response carries a `dataset_note`.
>
> **Licence.** SSO legislation is official public information published by the Singapore
> government. This connector relays it with attribution and a `source_url`, respects
> `robots.txt` (no `/search` calls), and does not cache more aggressively than a normal browser
> visit would.
## The tools
| Tool | What it does |
|---|---|
| `sg_list_acts` | Browse the current Acts, paginated (no keyword search - see Scope above). |
| `sg_get_provision` | The text of one numbered section of an Act, by `act_code` and section number. |
| `sg_get_full_text` | The full text of an Act (truncated at ~300,000 characters). |
| `sg_coverage` | Declare what this connector covers, when each family was captured, and - explicitly - what it does NOT cover. Every gap carries a fallback. |
Every response carries the contract: `eli_uri` (Singapore has no ELI - this is the durable SSO
act URL, e.g. `https://sso.agc.gov.sg/Act/CoA1967`, see `eli_note`), `human_readable_citation`
(the Act title as SSO itself renders it, e.g. `Companies Act 1967`), and `source_url`.
## Install
As a Claude plugin (Claude Code or the desktop app, needs [uv](https://docs.astral.sh/uv/));
see [plugin/README.md](plugin/README.md) for what it sends and stores:
```
/plugin marketplace add matematicsolutions/sg-eli-mcp
/plugin install sg-eli-mcp@sg-eli-mcp
```
As a standalone server, from PyPI:
```bash
uvx sg-eli-mcp
```
Configuration via env:
- `SG_ELI_BASE_URL` - default `https://sso.agc.gov.sg`
- `SG_ELI_CACHE_DIR` - default `~/.matematic/cache/sg-eli`
- `SG_ELI_AUDIT_DIR` - default `~/.matematic/audit`
No API key. SSO is keyless.
### Configure (Claude Code / any MCP client)
```json
{
"mcpServers": {
"sg-eli-mcp": { "command": "sg-eli-mcp" }
}
}
```
### Windows 11 with Smart App Control
Smart App Control blocks unsigned executables, which covers `uvx.exe`, `pip.exe`
and the `sg-eli-mcp.exe` launcher that pip writes at install time. The `python.exe` and
`py.exe` from the python.org installer are signed by the Python Software
Foundation, so running the module through the interpreter works:
```bash
python -m pip install sg-eli-mcp
python -m sg_eli_mcp
```
`pip.exe` is blocked for the same reason, so install with `python -m pip`, not
`pip install`. If `python` is not on PATH, use the Windows launcher: `py -3 -m sg_eli_mcp`.
```json
{ "mcpServers": { "sg-eli-mcp": { "command": "python", "args": ["-m", "sg_eli_mcp"] } } }
```
Do not turn Smart App Control off to work around this - it cannot be re-enabled
without reinstalling Windows.
## Governance
- **Public data only** - read-only against SSO; no client data leaves the machine.
- **Robots-compliant** - never calls `/search` (disallowed by SSO's `robots.txt`); discovery
uses only the allowed `/Browse` listing.
- **Audit log** - every tool call appends one JSON line to `~/.matematic/audit/sg-eli-mcp.jsonl`.
- **Network** - the server talks to `sso.agc.gov.sg` and the local filesystem. Once, on first
use, it also fetches a small configuration file (`sg-runtime.json.gz`, updated source
addresses) from this repository's GitHub Releases. That request carries no query content;
GitHub's download counter for the file is the only usage signal we see.
`SG_ELI_RUNTIME_URL=""` turns it off; the Claude plugin ships with it off. No LLM provider,
no other telemetry.
- **Verifiable citations** - every response is independently checkable via `source_url`.
See `CONSTITUTION.md` and `DISCOVERY.md`.
## Tests
```bash
pip install -e ".[dev]"
pytest tests/test_instructions_drift.py -v # offline
pytest tests/test_smoke.py -v # hits live SSO
```
## Licence
Apache-2.0. © Matematic Solutions / Wieslaw Mazur.
TDQS
Scored across 4 tools
Each tool targets a distinct action: listing acts, retrieving a single provision, retrieving full act text, and exposing connector coverage. There is no meaningful overlap that would cause an agent to select the wrong tool.
Three tools follow a consistent sg_<verb>_<noun> pattern: sg_list_acts, sg_get_provision, and sg_get_full_text. The outlier is sg_coverage, which uses a bare noun instead of a verb_noun form, but the naming remains predictable overall.
Four tools is a well-scoped size for a focused read-only legal retrieval connector. Each tool covers a distinct core need, and there are no redundant or unnecessary additions.
The set covers listing acts, fetching full text, and fetching individual provisions, with an explicit coverage tool that documents known gaps and fallbacks. It lacks a section index and paginated full-text continuation for large acts, but those gaps are surfaced rather than hidden.