You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Feature request: built-in MCP endpoint for sending messages from AI agents #1059
Is your feature request related to a problem? Please describe.
AI coding agents and assistants (Claude Code, VS Code Copilot, Cherry Studio, n8n, …) increasingly run long tasks unattended, and a common need is "notify me on my phone when you're done or need input". These tools speak the Model Context Protocol (MCP). Today, connecting them to Gotify requires either writing a custom script per agent or running a separate local MCP bridge process (e.g. taigrr/gotify-mcp, stdio only) on every machine the agent runs on. That doesn't work for remote/hosted agents that can only reach an HTTP URL.
Describe the solution you'd like
An optional, built-in MCP endpoint at /mcp that lets an agent send a message using an application token, so setup is a single line:
I have a working implementation at RedwindA/server@feat/mcp and I'm happy to open a PR if you're open to the idea. Scope was deliberately kept minimal:
Auth: only application tokens, via the existing RequireApplicationToken middleware (header, Authorization: Bearer, or ?token= query, which is already masked in the access log). Client tokens and basic auth are rejected, so an agent can never read or delete messages or manage anything.
One tool: send_message with message (required), title, priority, and three convenience flags mapped to the documented extras: markdown → client::display.contentType, click_url → client::notification.click.url, big_image_url → client::notification.bigImageUrl. Raw extras are intentionally not exposed, to keep LLMs from making up namespaces.
Stateless: Streamable HTTP in stateless + JSON-response mode. No sessions, no SSE, no long-lived connections, no extra state in the server. It behaves like any other REST endpoint behind a reverse proxy or with multiple instances.
Code reuse: the defaulting/store/notify logic of CreateMessage is extracted into a shared helper, so REST and MCP behave the same (default title = app name, default priority, stream notification).
Opt-out: GOTIFY_SERVER_MCP_ENABLED (default true; false means /mcp is not registered at all).
Size: ~115 lines in api/mcp.go, a small refactor in api/message.go, config/router wiring, integration tests using the SDK client, and a README section.
Dependency: the official github.com/modelcontextprotocol/go-sdk (v1.x, maintained by the MCP org together with Google). It adds 5 small indirect modules (google/jsonschema-go, segmentio/encoding, segmentio/asm, yosida95/uritemplate, golang.org/x/time).
Describe alternatives you've considered
External bridge / contrib project (like taigrr/gotify-mcp): works for local stdio use, but every agent host needs an extra binary and config, and it can't serve remote agents that only accept an HTTP URL.
Plugin: a plugin could host an HTTP endpoint under /plugin/:id/custom/…, but it would send as the plugin's own internal application rather than the user's existing apps, and it wouldn't reuse the normal token auth. Once the new IPC plugin system ([RFC] A plugin system that does not rely on Go plugin/dynamic linker #825) lands, this could be revisited, but it would still be less discoverable than a built-in endpoint.
Plain REST: agents can be told to curl/message, but that needs shell access, per-agent prompting, and exposes the token in the agent's command history. MCP tools are discovered automatically and the token stays in the client config.
Additional context
I understand if you'd rather keep this out of core. In that case I'd be glad to turn it into a standalone HTTP service and submit it to gotify/contrib instead. Feedback on the tool shape (names/parameters) is welcome either way.
Is your feature request related to a problem? Please describe.
AI coding agents and assistants (Claude Code, VS Code Copilot, Cherry Studio, n8n, …) increasingly run long tasks unattended, and a common need is "notify me on my phone when you're done or need input". These tools speak the Model Context Protocol (MCP). Today, connecting them to Gotify requires either writing a custom script per agent or running a separate local MCP bridge process (e.g. taigrr/gotify-mcp, stdio only) on every machine the agent runs on. That doesn't work for remote/hosted agents that can only reach an HTTP URL.
Describe the solution you'd like
An optional, built-in MCP endpoint at
/mcpthat lets an agent send a message using an application token, so setup is a single line:claude mcp add gotify --transport http https://gotify.example.com/mcp --header "Authorization: Bearer <apptoken>"Bark ships a similar built-in endpoint.
I have a working implementation at RedwindA/server@feat/mcp and I'm happy to open a PR if you're open to the idea. Scope was deliberately kept minimal:
RequireApplicationTokenmiddleware (header,Authorization: Bearer, or?token=query, which is already masked in the access log). Client tokens and basic auth are rejected, so an agent can never read or delete messages or manage anything.send_messagewithmessage(required),title,priority, and three convenience flags mapped to the documented extras:markdown→client::display.contentType,click_url→client::notification.click.url,big_image_url→client::notification.bigImageUrl. Rawextrasare intentionally not exposed, to keep LLMs from making up namespaces.CreateMessageis extracted into a shared helper, so REST and MCP behave the same (default title = app name, default priority, stream notification).GOTIFY_SERVER_MCP_ENABLED(defaulttrue;falsemeans/mcpis not registered at all).api/mcp.go, a small refactor inapi/message.go, config/router wiring, integration tests using the SDK client, and a README section.github.com/modelcontextprotocol/go-sdk(v1.x, maintained by the MCP org together with Google). It adds 5 small indirect modules (google/jsonschema-go,segmentio/encoding,segmentio/asm,yosida95/uritemplate,golang.org/x/time).Describe alternatives you've considered
/plugin/:id/custom/…, but it would send as the plugin's own internal application rather than the user's existing apps, and it wouldn't reuse the normal token auth. Once the new IPC plugin system ([RFC] A plugin system that does not rely on Go plugin/dynamic linker #825) lands, this could be revisited, but it would still be less discoverable than a built-in endpoint.curl/message, but that needs shell access, per-agent prompting, and exposes the token in the agent's command history. MCP tools are discovered automatically and the token stays in the client config.Additional context
I understand if you'd rather keep this out of core. In that case I'd be glad to turn it into a standalone HTTP service and submit it to gotify/contrib instead. Feedback on the tool shape (names/parameters) is welcome either way.