Loopback-only MCP server for OpenShock
Project description
OpenShock MCP
Loopback-only MCP server for OpenShock.
It exposes OpenShock devices and shockers as MCP tools through Python and Nanashi-OpenShockPY.
This server is meant to run on the same machine as your MCP client. It should not be reachable from other devices.
Liability Waiver
Read this before pressing buttons you might later pretend were "just testing".
This software sends real commands to real hardware. If you call shock,
vibrate, or beep, devices receive that action. This project does not detect
sarcasm, hesitation, or regret.
By using this project, you agree that:
- You are fully responsible for setup, configuration, and usage.
- You only use it with informed consent and lawful, ethical intent.
- You leave confirmation safeguards enabled unless you intentionally accept the risk.
- You understand there is no undo for actions already sent to hardware.
- You understand "I did not think it would actually do that" is not a bug report.
Short version: tool execute command. Consequences belong to operator.
Quick Start
- Install:
pipx install --force 'git+https://github.com/NanashiTheNameless/OpenShockMCP.git@main'
- First run with your API key to generate config and start the server:
OPENSHOCK_API_KEY="your-api-key" openshock-mcp
- Point your MCP client to
openshock-mcp(stdio is the default and recommended transport).
If you prefer the full setup details, continue below.
Requirements
- Python 3.10 or newer
pipxgit(required if you install this project from a GitHub URL)- An OpenShock API key
Dependencies:
mcp>=1.27.0
Nanashi-OpenShockPY>=0.0.1.7
Installation
Install from GitHub (default):
pipx install --force 'git+https://github.com/NanashiTheNameless/OpenShockMCP.git@main'
Also available on PyPI:
pipx install openshock-mcp
Install a specific tag or commit:
pipx install --force 'git+https://github.com/NanashiTheNameless/OpenShockMCP.git@0.0.0.3'
For local development from a checkout:
pipx install --editable /path/to/OpenShockMCP
Check install:
openshock-mcp --version
Expected version:
0.0.0.3
First Run And Config Creation
The server uses a TOML config file. If no config exists, openshock-mcp creates
one automatically in the normal per-user config directory for your OS:
Windows: %APPDATA%\openshock-mcp\config.toml
macOS: ~/Library/Application Support/openshock-mcp/config.toml
Linux: ~/.config/openshock-mcp/config.toml
Other: ~/.config/openshock-mcp/config.toml
If OPENSHOCK_API_KEY is set during first run, the generated config includes it
and the server starts:
OPENSHOCK_API_KEY="your-api-key" openshock-mcp
If no API key is available, the server creates a template config and exits. Edit
openshock.api_key, then run it again.
Configuration
Default Config File
Generated config contents:
[server]
transport = "stdio"
host = "127.0.0.1"
port = 8000
path = "/mcp"
json_response = false
[openshock]
api_key = "your-api-key"
base_url = "https://api.openshock.app"
timeout = 15
[safety]
max_intensity = 100
max_duration_ms = 65535
require_confirmation = true
Config Lookup Order
Config lookup order:
--config /path/to/config.toml$OPENSHOCK_MCP_CONFIG./openshock-mcp.toml- OS user config path
On Unix-like systems, $XDG_CONFIG_HOME/openshock-mcp/config.toml is used before
~/.config/openshock-mcp/config.toml when XDG_CONFIG_HOME is set.
Environment Variable Overrides
Environment variables can override matching config values for automation.
OPENSHOCK_USER_AGENT is env-only; User-Agent is not written to config files.
OPENSHOCK_API_KEY
OPENSHOCK_BASE_URL
OPENSHOCK_TIMEOUT
OPENSHOCK_USER_AGENT
OPENSHOCK_MCP_MAX_INTENSITY
OPENSHOCK_MCP_MAX_DURATION_MS
OPENSHOCK_MCP_REQUIRE_CONFIRMATION
OPENSHOCK_MCP_TRANSPORT
OPENSHOCK_MCP_HOST
OPENSHOCK_MCP_PORT
OPENSHOCK_MCP_PATH
OPENSHOCK_MCP_JSON_RESPONSE
OPENSHOCK_MCP_CONFIG
openshock-mcp.toml is ignored by git so local secrets do not get committed.
openshock-mcp.example.toml is a safe template.
Running The Server
Stdio (Recommended)
stdio is the default and recommended transport for desktop MCP clients. It
does not open a network port.
Do not use stdio as an interactive terminal program. MCP clients launch it and
send JSON-RPC over stdin. If you run openshock-mcp directly in a terminal, it
prints usage guidance instead of starting the protocol stream.
With explicit config:
openshock-mcp --config ~/.config/openshock-mcp/config.toml
On Windows PowerShell, pass a Windows path:
openshock-mcp --config "$env:APPDATA\openshock-mcp\config.toml"
Claude Desktop style config:
{
"mcpServers": {
"openshock": {
"command": "openshock-mcp",
"args": ["--config", "/home/YOUR_USER/.config/openshock-mcp/config.toml"]
}
}
}
HTTP (Only If Your Client Requires It)
Use streamable HTTP only when your MCP client needs an HTTP MCP endpoint. The
server refuses non-loopback hosts such as 0.0.0.0 and LAN IP addresses.
openshock-mcp \
--transport streamable-http \
--host 127.0.0.1 \
--port 8765 \
--config ~/.config/openshock-mcp/config.toml
MCP endpoint:
http://127.0.0.1:8765/mcp
On startup, the server prints sanitized startup info to stderr:
openshock-mcp 0.0.0.3 starting
transport: streamable-http
mcp endpoint: http://127.0.0.1:8765/mcp
config: /path/to/config.toml
api key configured: yes
safety: max_intensity=100, max_duration_ms=65535, require_confirmation=true
Stdio startup info also goes to stderr so stdout stays reserved for MCP JSON-RPC.
This is allowed:
openshock-mcp --transport http --host 127.0.0.1
This is rejected:
openshock-mcp --transport http --host 0.0.0.0
Tools
Read-only tools:
openshock_status: show sanitized config status. Does not reveal API key.list_devices: list OpenShock devices.get_device: get one device by ID.list_shockers: list shockers, optionally filtered by device ID.get_shocker: get one shocker by ID.
Action tools:
shock: shock one shocker, or useshocker_id="all".vibrate: vibrate one shocker, or useshocker_id="all".beep: beep one shocker, or useshocker_id="all".stop: stop one shocker, or useshocker_id="all".
shock, vibrate, and beep require confirm=true by default. Keep
require_confirmation = true unless you understand the risk. stop does not
require confirmation.
Typical action arguments:
{
"shocker_id": "your-shocker-id",
"intensity": 25,
"duration": 1000,
"exclusive": false,
"confirm": true
}
Limits:
intensity:0to100, also capped bymax_intensityduration:300to65535ms, also capped bymax_duration_ms
Security Model (Local Only)
stdioopens no network listener.- HTTP mode only accepts loopback bind hosts:
127.0.0.1,localhost, or::1. - Non-loopback hosts are rejected before startup.
- The MCP SDK enables DNS rebinding protection for loopback hosts.
- API keys are read from local config or environment only.
Troubleshooting
OpenShock API key missing
Set [openshock].api_key in your config file, or set OPENSHOCK_API_KEY.
config file not found
The path passed to --config must exist. If you want default lookup, omit
--config.
refusing non-loopback HTTP host
Use 127.0.0.1, localhost, or ::1. This project intentionally does not bind
to LAN or public interfaces.
git not found during install
Install git. OpenShockPY is installed from GitHub main.
License
PolyForm Noncommercial License 1.0.0. See LICENSE.md.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file openshock_mcp-0.0.0.3.tar.gz.
File metadata
- Download URL: openshock_mcp-0.0.0.3.tar.gz
- Upload date:
- Size: 17.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0d51afc218ce0635fc71b4a86e78c31c2130a63159203908a12e8218cf5dea72
|
|
| MD5 |
f37e4e408db8af8f0504d848ec1f9c36
|
|
| BLAKE2b-256 |
f57b526997877c66366cab2d1f7869cd05a63be4274f14900e4ac4e6be1c567c
|
Provenance
The following attestation bundles were made for openshock_mcp-0.0.0.3.tar.gz:
Publisher:
python-publish.yml on NanashiTheNameless/OpenShockMCP
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
openshock_mcp-0.0.0.3.tar.gz -
Subject digest:
0d51afc218ce0635fc71b4a86e78c31c2130a63159203908a12e8218cf5dea72 - Sigstore transparency entry: 1316208889
- Sigstore integration time:
-
Permalink:
NanashiTheNameless/OpenShockMCP@e3d16e516f4d50f6aca207482586d59f669cda99 -
Branch / Tag:
refs/tags/0.0.0.3 - Owner: https://github.com/NanashiTheNameless
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@e3d16e516f4d50f6aca207482586d59f669cda99 -
Trigger Event:
release
-
Statement type:
File details
Details for the file openshock_mcp-0.0.0.3-py3-none-any.whl.
File metadata
- Download URL: openshock_mcp-0.0.0.3-py3-none-any.whl
- Upload date:
- Size: 15.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a8cff3c6b2800afea46b8951d85bb9787579a5e14d1e7fbf5db3d2820b37f343
|
|
| MD5 |
a718931b495e048dc61af98d06f10f82
|
|
| BLAKE2b-256 |
44bb7371f7f399fc6cb52cb1dc0b718a54139a752edc4665ef42dbed383a80f1
|
Provenance
The following attestation bundles were made for openshock_mcp-0.0.0.3-py3-none-any.whl:
Publisher:
python-publish.yml on NanashiTheNameless/OpenShockMCP
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
openshock_mcp-0.0.0.3-py3-none-any.whl -
Subject digest:
a8cff3c6b2800afea46b8951d85bb9787579a5e14d1e7fbf5db3d2820b37f343 - Sigstore transparency entry: 1316208913
- Sigstore integration time:
-
Permalink:
NanashiTheNameless/OpenShockMCP@e3d16e516f4d50f6aca207482586d59f669cda99 -
Branch / Tag:
refs/tags/0.0.0.3 - Owner: https://github.com/NanashiTheNameless
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@e3d16e516f4d50f6aca207482586d59f669cda99 -
Trigger Event:
release
-
Statement type: