{"id":30866595,"url":"https://github.com/conacademy/buttplug-mcp","last_synced_at":"2025-09-07T22:06:06.756Z","repository":{"id":296393218,"uuid":"959259324","full_name":"ConAcademy/buttplug-mcp","owner":"ConAcademy","description":"Buttplug.io Model Context Protocol (MCP) Server","archived":false,"fork":false,"pushed_at":"2025-05-30T19:06:01.000Z","size":21,"stargazers_count":114,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-05T10:58:18.490Z","etag":null,"topics":["buttplug","llm","mcp","mcp-server"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ConAcademy.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-04-02T13:57:50.000Z","updated_at":"2025-07-04T09:24:09.000Z","dependencies_parsed_at":"2025-05-30T17:05:12.419Z","dependency_job_id":"dfe21f96-3dc5-478e-8bd0-72affba312ee","html_url":"https://github.com/ConAcademy/buttplug-mcp","commit_stats":null,"previous_names":["conacademy/buttplug-mcp"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/ConAcademy/buttplug-mcp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ConAcademy%2Fbuttplug-mcp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ConAcademy%2Fbuttplug-mcp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ConAcademy%2Fbuttplug-mcp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ConAcademy%2Fbuttplug-mcp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ConAcademy","download_url":"https://codeload.github.com/ConAcademy/buttplug-mcp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ConAcademy%2Fbuttplug-mcp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274101771,"owners_count":25222447,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-07T02:00:09.463Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["buttplug","llm","mcp","mcp-server"],"created_at":"2025-09-07T22:03:13.189Z","updated_at":"2025-09-07T22:06:06.714Z","avatar_url":"https://github.com/ConAcademy.png","language":"Go","readme":"# buttplug-mcp - Buttplug.io MCP Server\n\n`buttplug-mcp` is a [Model Context Protocol (MCP)](https://www.anthropic.com/news/model-context-protocol) server for the [Buttplug.io ecosystem](https://buttplug.io).  It allows Tool-supporting LLM programs like [Claude Desktop](https://claude.ai/download) query and control your Genital Interface Devices.\n\n*|insert AI-generated slop image of robots doing nasty things|*\n\u003cbr\u003e`LLM|=\u003e - - (__(__)`\n\n\nOnce set up, you can prompt your LLM:\n * \"What are my connected buttplug devices?\"\n * \"Set the second motor on my LELO F1S to 50% strength\"\n * \"How much battery is left on my Lovense Max 2?\"\n * \"Does my WeWibe have weak signal?\"\n\n**NOTE: The above is aspirational and really the [current experience](#current-state) is unstable and frustating.**\n\nIt supports the following Resources and Tools:\n\n| Resource | Description |\n|----------|-------------|\n| `/devices` | List of connected Buttplug devices in JSON. |\n| `/device/{id}` | Device information by device ID where`id` is a number from `/devices` |\n| `/device/{id}/rssi` | RSSI signal level by device ID where `id` is a number from `/devices` |\n| `/device/{id}/battery` | Battery level by device ID where `id` is a number from `/devices` |\n\n\n| Tool | Params | Description |\n|------|--------|-------------|\n| `device_vibrate` | `id`, `motor`, `strength` | Vibrates device by `id`, selecting `strength` and optional `motor` |\n\n\u003cdetails\u003e\n\u003csummary\u003eJSON Schema for Resources.  Click to expand\u003c/summary\u003e\n\n[`schema_resources.json`](./schema_resources.json)\n```\n{\n  \"jsonrpc\": \"2.0\",\n  \"id\": 1,\n  \"result\": {\n    \"resources\": [\n      {\n        \"uri\": \"devices\",\n        \"name\": \"Device List\",\n        \"description\": \"List of connected Buttplug devices in JSON\",\n        \"mimeType\": \"application/json\"\n      }\n    ]\n  }\n}\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eJSON Schema for Tools.  Click to expand\u003c/summary\u003e\n\n[`schema_tools.json`](./schema_tools.json)\n```\n{\n  \"jsonrpc\": \"2.0\",\n  \"id\": 1,\n  \"result\": {\n    \"tools\": [\n      {\n        \"description\": \"Vibrates device by `id`, selecting `strength` and optional `motor`\",\n        \"inputSchema\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"id\": {\n              \"description\": \"Device ID to query, sourced from `/devices`\",\n              \"pattern\": \"^[0-9]*$\",\n              \"type\": \"number\"\n            },\n            \"motor\": {\n              \"description\": \"Motor number to vibrate, defaults to 0\",\n              \"pattern\": \"^[0-9]*$\",\n              \"type\": \"number\"\n            },\n            \"strength\": {\n              \"description\": \"Strength from 0.0 to 1.0, with 0.0 being off and 1.0 being full\",\n              \"pattern\": \"^(0(\\\\.\\\\d+)?|1(\\\\.0+)?)$\",\n              \"type\": \"number\"\n            }\n          },\n          \"required\": [\n            \"id\",\n            \"strength\"\n          ]\n        },\n        \"name\": \"device_vibrate\"\n      }\n    ]\n  }\n}\n```\n\u003c/details\u003e\n\n\n## Current State\n\nI started working on this on 2025-04-01, April Fool's Day, after having created another experimental MCP service, [`dbn-go` for financial market data](https://github.com/NimbleMarkets/dbn-go/blob/main/cmd/dbn-go-mcp/README.md), the day prior.  So it is fresh meat and was intended as a quick, fun educational project.\n\nWhile it does work, I found the underlying [`go-buttplug` library](https://github.com/diamondburned/go-buttplug) to be unstable in connection handling.   I could ask Claude for my devices, but my specific device wouldn't vibrate even just with just Intiface Central -- it was like in read-only mode!    I also wish I had a virtual buttplug.io device for testing, rather than relying on a physical device.\n\nSo, it has not truly been tested \"end-to-end\" :wink:\n\nI will dig more into the `go-buttplug` library and see why connections are unstable.  I also need to understand the MCP protocol current state of MCP hosts -- it seems they focus on Tools rather than Resources and Resoure Templates.\n\n## Installing the binary\n\nBinaries for multiple platforms are [released on GitHub](https://github.com/conacademy/buttplug-mcp/releases) through [GitHub Actions](https://github.com/conacademy/buttplug-mcp/actions).\n\nYou can also install for various platforms with [Homebrew](https://brew.sh) from [`conacademy/homebrew-tap`](https://github.com/conacademy/homebrew-tap):\n\n```\nbrew tap conacademy/homebrew-tap\nbrew install conacademy/tap/buttplug-mcp\n```\n\n## Usage\n\nDownload the [Intiface Central](https://intiface.com/central/) hub application to manage your devices.  Start it and note the server port (default seems to be `12345`).\n\nTo use this the `buttplug-mcp` MCP server, you must configure your host program to use it.  We will illustrate with [Claude Desktop](https://claude.ai/download).  We must find the `buttplug-mcp` program on our system; the example below shows where `buttplug-mcp` is installed with MacOS Homebrew (perhaps build your own and point at that).  \n\nThe following [configuration JSON](./claude_desktop_config.json) sets this up:\n\n```json\n{\n  \"mcpServers\": {\n    \"buttplug\": {\n      \"command\": \"/opt/homebrew/bin/buttplug-mcp\",\n      \"args\": [\n        \"--ws-port\", \"12345\"\n      ]\n    }\n  }\n}\n```\n\nUsing Claude Desktop, you can follow [their configuration tutorial](https://modelcontextprotocol.io/quickstart/user) but substitute the configuration above.  With that in place, you can ask Claude question and it will use the `buttplug-mcp` server.  Here's example conversations:\n\nPerhaps you can use the [HomeAssistant MCP](https://www.home-assistant.io/integrations/mcp_server/) integration to turn the lights down low...\n\n### Ollama and `mcphost`\n\nFor local inferencing, there are MCP hosts that support [Ollama](https://ollama.com/download).  You can use any [Ollama LLM that supports \"Tools\"](https://ollama.com/search?c=tools).  We experimented with [`mcphost`](https://github.com/mark3labs/mcphost), authored by the developer of the [`mcp-go` library](https://github.com/mark3labs/mcp-go) that peformed the heavy lifting for us.\n\nHere's how to install and run with it with the configuration above, stored in `mcp.json`:\n\n```\n$ go install github.com/mark3labs/mcphost@latest\n$ mcphost -m ollama:llama3.3 --config mcp.json\n...chat away...\n```\n\nIt seems that only \"Tools\" are supported and not \"Resources\", so I couldn't enumerate and introspect my device.   But I had this Tool interaction (but as noted [above](#current-state), my device didn't actually vibrate):\n\n```\n$ mcphost -m ollama:phi4-mini --config mcp.json\n2025/04/02 09:25:05 INFO Model loaded provider=ollama model=phi4-mini\n2025/04/02 09:25:05 INFO Initializing server... name=buttplug\n2025/04/02 09:25:05 INFO Server connected name=buttplug\n2025/04/02 09:25:05 INFO Tools loaded server=buttplug count=1\n2025/04/02 09:28:31 INFO Model loaded provider=ollama model=phi4-mini\n2025/04/02 09:28:31 INFO Initializing server... name=buttplug\n2025/04/02 09:28:31 INFO Server connected name=buttplug\n2025/04/02 09:28:31 INFO Tools loaded server=buttplug count=1\n/servers\n      # buttplug\n      Command /opt/homebrew/bin/buttplug-mcp\n      Arguments --ws-port 12345\n\n/tools\n  • buttplug\n    • device_vibrate\n      • Vibrates device by ID, selecting strength and optional motor\n\n  You: buttplug device_vibrate id 0 at strength 1\n\n  Assistant:\n  \u003c|tool_call|\u003e[start_processing]\n\n  [{\"type\":\"function\",\"function\":{\"name\":\"buttplug__device_vibrate\",\"description\":\"Vibrates device by ID, selecting strength and optional\n  motor\",\"parameters\":{\"id\":0,\"strength\":1}}]\n\n  {}\n\n  {\"status\":\"success\",\"message\":\"Device with id 0 is vibrating at full strength.\"}\n```\n\n## Building\n\nBuilding is performed with [task](https://taskfile.dev/), with the binary available in `bin/buttplug-mcp`.\n\n```\n$ task\ntask: [tidy] go mod tidy\ntask: [build] go build -o bin/buttplug-mcp cmd/buttplug-mcp/main.go\n```\n\nUseful testing tools:\n * `task stdio-schema | jq` -- prints out JSON schemas\n * `npx @modelcontextprotocol/inspector node build/index.js` -- [MCP Inspector Web GUI](https://github.com/modelcontextprotocol/inspector)\n\n\n## CLI Arguments\n\n```\nR buttplug-mcp --help\nusage: buttplug-mcp [opts]\n\n  -h, --help              Show help\n  -l, --log-file string   Log file destination (or MCP_LOG_FILE envvar). Default is stderr\n  -j, --log-json          Log in JSON (default is plaintext)\n      --sse               Use SSE Transport (default is STDIO transport)\n      --sse-host string   host:port to listen to SSE connections\n  -v, --verbose           Verbose logging\n      --ws-port int       port to connect to the Buttplug Websocket server\n```\n\n## Contribution and Conduct\n\nAs with all ConAcademy projects, pull requests are welcome.  Or fork it.  You do you.\n\nEither way, obey our [Code of Conduct](./CODE_OF_CONDUCT.md).  Be shady, but don't be a jerk.\n\n## Credits and License\n\nThanks for `go-buttplug` for the [Golang Buttplug.io library](https://github.com/diamondburned/go-buttplug) and its [`buttplughttp` example](https://github.com/diamondburned/go-buttplug/tree/plug/cmd/buttplughttp), and `go-mcp` for the [Golang Model Context Protocol library](https://github.com/mark3labs/mcp-go).\n\nCopyright (c) 2025 Neomantra BV.  Authored by Evan Wies for [ConAcademy](https://github.com/conacademy).\n\nReleased under the [MIT License](https://en.wikipedia.org/wiki/MIT_License), see [LICENSE.txt](./LICENSE.txt).\n","funding_links":[],"categories":["🤖 AI/ML"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconacademy%2Fbuttplug-mcp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fconacademy%2Fbuttplug-mcp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconacademy%2Fbuttplug-mcp/lists"}