Metadata-Version: 2.4
Name: switch-parental-controls
Version: 1.1.1
Summary: Nintendo Switch Parental Controls
License: MIT
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: mcp[cli]>=1.0.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: pynintendoparental>=2.4.0
Requires-Dist: aiohttp>=3.9.0
Requires-Dist: click>=8.1.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
Requires-Dist: ruff>=0.4.0; extra == "dev"
Requires-Dist: python-dotenv>=1.0.0; extra == "dev"
Dynamic: license-file

# Nintendo Switch Parental Controls

A [CLI](#cli-usage) and [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server that expose Nintendo Switch Parental Controls as commands and AI-accessible tools. It wraps the [`pynintendoparental`](https://github.com/pantherale0/pynintendoparental) library and allows humans and AI assistants to monitor and manage parental control settings on Nintendo Switch devices.

## Table of Contents

- [Features](#features)
- [Prerequisites](#prerequisites)
- [CLI Usage](#cli-usage)
  - [Installation](#installation)
  - [Authentication](#authentication)
    - [Interactive login](#interactive-login)
    - [Storing your token](#storing-your-token)
  - [Global Options](#global-options)
  - [Commands](#commands)
- [Caching](#caching)
- [MCP Server](#mcp-server)
  - [Running the Server](#running-the-server)
  - [Environment Variables](#environment-variables)
  - [MCP Client Configuration](#mcp-client-configuration)
  - [Available Tools](#available-tools)
- [Development](#development)
- [CI](#ci)
- [Legal](#legal)
- [License](#license)

## <a name="features"></a>Features

- **Authentication**: Interactive Nintendo OAuth login flow, or pre-configured session token
- **Device monitoring**: List devices, view playtime, remaining time, sync status
- **Playtime controls**: Set daily limits, add extra time, configure per-day-of-week schedules
- **Bedtime controls**: Set bedtime alarms and end times
- **Restriction controls**: Set restriction mode (forced termination vs. alarm), content restriction levels
- **Player tracking**: View player profiles and today's app usage
- **Application management**: List apps, manage the allow-list (bypass content restrictions)

## <a name="prerequisites"></a>Prerequisites

- [uv](https://docs.astral.sh/uv/) — install once, no Python or clone needed:

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

## <a name="cli-usage"></a>CLI Usage

The `switch-parental-controls` CLI gives you direct terminal access to all parental control features.

### <a name="installation"></a>Installation

No clone required — run directly with `uvx`:

```bash
uvx switch-parental-controls --help
```

Or install globally:

```bash
pip install switch-parental-controls
switch-parental-controls --help
```

### <a name="authentication"></a>Authentication

#### <a name="interactive-login"></a>Interactive login

```bash
switch-parental-controls login
```

This starts an interactive flow:

1. A Nintendo login URL is printed — open it in your browser
2. Log in with your Nintendo Account
3. Right-click the **"Select this person"** button and copy the link
4. Paste the copied URL at the prompt

On success, the token is saved to `~/.config/switch-parental-controls/credentials` (respects `XDG_CONFIG_HOME`) — all other commands will use it automatically. No further setup needed.

The CLI also prints an `export SWITCH_PARENTAL_CONTROLS_SESSION_TOKEN=...` snippet after login, so you can copy the token value for use in other tools or scripts.

#### <a name="storing-your-token"></a>Storing your token

The token lookup order is: **environment variable → credentials file**.

**Credentials file (recommended):**

The `login` command writes the token here automatically. To store it manually:

```bash
mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/switch-parental-controls"
echo "your-token-here" > "${XDG_CONFIG_HOME:-$HOME/.config}/switch-parental-controls/credentials"
chmod 600 "${XDG_CONFIG_HOME:-$HOME/.config}/switch-parental-controls/credentials"
```

The default path is `~/.config/switch-parental-controls/credentials`; set `XDG_CONFIG_HOME` to use a different base directory. The file must contain only the token, one line, no quotes. The `chmod 600` keeps it readable by your user only.

**Environment variable (shell profile):**

```bash
# Add to ~/.zshrc, ~/.bashrc, or equivalent
export SWITCH_PARENTAL_CONTROLS_SESSION_TOKEN="your-token-here"
```

The environment variable takes precedence over the credentials file, so this is also useful for temporarily overriding a stored token.

**Inline for one-off runs:**

```bash
SWITCH_PARENTAL_CONTROLS_SESSION_TOKEN="your-token-here" switch-parental-controls today-summary
```

> **Note**: Session tokens can expire. If you get authentication errors, repeat the login flow.

### <a name="global-options"></a>Global Options

```text
switch-parental-controls [OPTIONS] COMMAND [ARGS]...

Options:
  -t, --timezone TEXT   IANA timezone  [env: SWITCH_PARENTAL_CONTROLS_TIMEZONE; default: Europe/London]
  -l, --lang TEXT       Language code  [env: SWITCH_PARENTAL_CONTROLS_LANG; default: en-GB]
```

### <a name="commands"></a>Commands

All device commands accept an optional `[DEVICE]` argument — a device name or ID. If omitted and the account has exactly one Switch, it is auto-selected. Run `list-devices` once to populate the local cache.

**Device info:**

```bash
switch-parental-controls list-devices [--format markdown|json]
switch-parental-controls get-device [DEVICE] [--format markdown|json]
switch-parental-controls today-summary [DEVICE] [--format markdown|json]
switch-parental-controls monthly-summary [DEVICE] [--year YEAR --month MONTH] [--player PLAYER_ID] [--no-cache] [--format markdown|json]
switch-parental-controls playtime [DEVICE] [--year YEAR --month MONTH] [--day DAY] [--player PLAYER_ID] [--no-cache] [--format markdown|json]

# DEVICE may be a name or an ID
switch-parental-controls today-summary "Switch #1"
switch-parental-controls today-summary abc123def456
```

**Playtime limits:**

```bash
switch-parental-controls set-playtime-limit [DEVICE] --minutes 120   # set 2-hour limit
switch-parental-controls set-playtime-limit [DEVICE] --no-limit       # remove limit
switch-parental-controls add-extra-time [DEVICE] 30                   # add 30 extra minutes today
switch-parental-controls set-timer-mode [DEVICE] DAILY
switch-parental-controls set-timer-mode [DEVICE] EACH_DAY_OF_THE_WEEK
```

**Per-day restrictions:**

```bash
# Enable playtime + bedtime on Monday
switch-parental-controls set-day-restrictions [DEVICE] MONDAY \
  --playtime-enabled --max-playtime-minutes 90 \
  --bedtime-enabled \
  --bedtime-alarm-hour 21 --bedtime-alarm-minute 0 \
  --bedtime-end-hour 7 --bedtime-end-minute 0

# Disable all restrictions on Saturday
switch-parental-controls set-day-restrictions [DEVICE] SATURDAY \
  --playtime-disabled --bedtime-disabled
```

**Restriction and content controls:**

```bash
switch-parental-controls set-restriction-mode [DEVICE] FORCED_TERMINATION
switch-parental-controls set-restriction-mode [DEVICE] ALARM
switch-parental-controls set-content-restriction [DEVICE] CHILDREN
switch-parental-controls set-bedtime-alarm [DEVICE] 21 0    # 21:00
switch-parental-controls set-bedtime-alarm [DEVICE] 0 0     # disable
switch-parental-controls set-bedtime-end [DEVICE] 7 0       # 07:00
```

**Players and applications:**

```bash
switch-parental-controls list-players [DEVICE] [--format json]
switch-parental-controls get-player [DEVICE] <player-id>
switch-parental-controls list-applications [DEVICE]
switch-parental-controls set-app-allow-list [DEVICE] <app-id> --allow
switch-parental-controls set-app-allow-list [DEVICE] <app-id> --no-allow

# Per-player usage data — use --player to filter monthly-summary and playtime
switch-parental-controls monthly-summary [DEVICE] --year 2026 --month 4 --player <player-id>
switch-parental-controls playtime [DEVICE] --year 2026 --month 4 --player <player-id>
switch-parental-controls playtime [DEVICE] --player <player-id>   # current month

# Single-day playtime — use --day to get one specific date instead of the whole month
switch-parental-controls playtime [DEVICE] --year 2026 --month 5 --day 15
switch-parental-controls playtime [DEVICE] --year 2026 --month 5 --day 15 --player <player-id>
```

**Cache management:**

```bash
switch-parental-controls clear-cache                          # clear entire cache
switch-parental-controls clear-cache --device "Switch #1"    # clear for one device
switch-parental-controls clear-cache --year 2026             # clear all months of a year
switch-parental-controls clear-cache --year 2026 --month 4   # clear a specific month
```

**Start the MCP server:**

```bash
switch-parental-controls mcp
```

## <a name="caching"></a>Caching

`monthly-summary` and `playtime` cache their API responses locally so past months don't require a network round-trip on subsequent calls.

**What is cached:** Raw API responses for months where both `--year` and `--month` are provided explicitly and the month is not the current calendar month. Data for the current month — and requests without an explicit year/month — always fetch live from the Nintendo API.

**Cache location:** `~/.config/switch-parental-controls/cache/` (respects `XDG_CONFIG_HOME`), organised as `{device-id}/{YYYY}-{MM}.json`.

**Bypassing the cache:** Pass `--no-cache` to `monthly-summary` or `playtime` to skip both reading from and writing to the cache. Useful when data looks unexpectedly stale.

**Clearing the cache:** Use the `clear-cache` command (CLI) or `switch_clear_cache` tool (MCP) — see the command examples above.

## <a name="mcp-server"></a>MCP Server

### <a name="running-the-server"></a>Running the Server

```bash
uvx switch-parental-controls mcp
```

No clone or install required — `uvx` fetches the package from PyPI and runs it in an isolated environment.

### <a name="environment-variables"></a>Environment Variables

| Variable                                | Required | Default         | Description                             |
| --------------------------------------- | -------- | --------------- | --------------------------------------- |
| `SWITCH_PARENTAL_CONTROLS_SESSION_TOKEN` | Yes\*    | —               | Nintendo session token                  |
| `SWITCH_PARENTAL_CONTROLS_TIMEZONE`      | No       | `Europe/London` | IANA timezone (e.g. `America/New_York`) |
| `SWITCH_PARENTAL_CONTROLS_LANG`          | No       | `en-GB`         | Language code (e.g. `en-US`)            |

\*The token can also be provided via the credentials file (`~/.config/switch-parental-controls/credentials` by default; respects `XDG_CONFIG_HOME`). Since the CLI `login` command writes to that same file, running `switch-parental-controls login` once is sufficient — the MCP server will pick up the stored token automatically, no environment variable needed. The only exception where no token is needed upfront at all is when using the interactive `switch_get_login_url` / `switch_complete_login` tools to authenticate.

### <a name="mcp-client-configuration"></a>MCP Client Configuration

Add to your MCP client configuration (e.g. Claude Desktop `claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "nintendo": {
      "command": "uvx",
      "args": ["switch-parental-controls", "mcp"],
      "env": {
        "SWITCH_PARENTAL_CONTROLS_SESSION_TOKEN": "your-token-here",
        "SWITCH_PARENTAL_CONTROLS_TIMEZONE": "America/New_York",
        "SWITCH_PARENTAL_CONTROLS_LANG": "en-US"
      }
    }
  }
}
```

### <a name="available-tools"></a>Available Tools

#### Authentication Tools

| Tool                    | Description                                                   |
| ----------------------- | ------------------------------------------------------------- |
| `switch_get_login_url`  | Generate the Nintendo login URL and step-by-step instructions |
| `switch_complete_login` | Complete login with the redirect URL from the browser         |

#### Devices

| Tool                          | Description                                                              |
| ----------------------------- | ------------------------------------------------------------------------ |
| `switch_list_devices`         | List all Nintendo Switch devices on the account                          |
| `switch_get_device`           | Get detailed status for a specific device                                |
| `switch_get_today_summary`    | Get today's usage summary for a device                                   |
| `switch_get_monthly_summary`  | Get monthly usage summary (optionally for a specific month)              |
| `switch_get_playtime`         | Get per-day playtime breakdown for a month (current month or historical) |
| `switch_clear_cache`          | Clear locally cached historic play data (all, by device, year, or month) |

#### Playtime Controls

| Tool                              | Description                                                |
| --------------------------------- | ---------------------------------------------------------- |
| `switch_set_daily_playtime_limit` | Set the daily playtime limit (0-360 min, or -1 to remove)  |
| `switch_add_extra_time`           | Add extra playtime for today                               |
| `switch_set_timer_mode`           | Switch between DAILY and EACH_DAY_OF_THE_WEEK modes        |
| `switch_set_day_restrictions`     | Set per-day playtime and bedtime restrictions              |

#### Restriction Controls

| Tool                                    | Description                              |
| --------------------------------------- | ---------------------------------------- |
| `switch_set_restriction_mode`           | Set FORCED_TERMINATION or ALARM mode     |
| `switch_set_content_restriction_level`  | Set age-based content restrictions       |
| `switch_set_bedtime_alarm`              | Set the bedtime alarm time (16:00-23:00) |
| `switch_set_bedtime_end_time`           | Set when bedtime ends (05:00-09:00)      |

#### Players

| Tool                  | Description                                    |
| --------------------- | ---------------------------------------------- |
| `switch_list_players` | List all players on a device                   |
| `switch_get_player`   | Get player details including apps played today |

#### Applications

| Tool                           | Description                                               |
| ------------------------------ | --------------------------------------------------------- |
| `switch_list_applications`     | List all tracked applications on a device                 |
| `switch_set_app_allow_list`    | Add/remove an app from the content restriction allow-list |

## <a name="development"></a>Development

Requires [mise](https://mise.jdx.dev/):

```bash
# Install dependencies
mise run install

# Run tests
mise run test

# Run linter
mise run lint

# Fix lint issues
mise run lint-fix

# Open MCP Inspector (browser UI to test tools interactively)
mise run inspect
```

### MCP Inspector

The `inspect` task launches the [MCP Inspector](https://github.com/modelcontextprotocol/inspector) — a browser-based UI for testing MCP tools interactively without needing a full AI client.

```bash
mise run inspect
```

This opens the inspector connected to the switch_parental_controls server. You can call any tool directly from the UI, which is useful for testing the authentication flow and verifying tool responses.

## <a name="ci"></a>CI

Tests run automatically on pull requests via GitHub Actions. See [`.github/workflows/test.yml`](.github/workflows/test.yml).

## <a name="legal"></a>Legal

Nintendo and Nintendo Switch are trademarks or registered trademarks of Nintendo in the U.S. and/or other countries.

This project is not affiliated, funded, or in any way associated with Nintendo.

## <a name="license"></a>License

MIT
