Skip to content

Feature request: built-in MCP endpoint for sending messages from AI agents #1059

Description

@RedwindA

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:

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:

  • 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions