SignOps MCP
An official MCP server provided by SignOps that allows AI coding agents to interact with the SignOps API. It enables sending push notifications to Android, iOS, and web, managing user devices and topics, creating login approvals, and handling authenticator codes, all via a streamable HTTP endpoint requiring an API key.
Endpoint and access
No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.
https://api.signops.dev/mcpWhat you can do with it
- Send push notifications to users or topics
- Manage user devices and registration tokens
- Create and manage login approvals via push
- Check or remove user authenticator codes
Source and maintenance
Protocol and capabilities
- Server
- signops 1.0.0
- MCP protocol
- 2025-06-18
- Tools
- 23 advertised
- Resources
- Not advertised
- Resource templates
- Not advertised
- Prompts
- Not advertised
{
"tools": {
"listChanged": false
}
}Server-provided instructions
Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.
Tools
23 advertised
send_push — Send a push
Send a push notification to one user (user_id), a list (user_ids, up to 1,000), a topic, or everyone (all: true). Give exactly one target. A push to one user, sent now, answers with its result at once; others answer with status sending or scheduled. With a test key (sk_test_) only test devices receive it.
{
"type": "object",
"required": [],
"properties": {
"all": {
"type": "boolean",
"description": "true to send to every device of the app."
},
"body": {
"type": "string",
"description": "The text under it."
},
"data": {
"type": "object",
"description": "Key and value pairs the app reads. With no title, the push is silent.",
"additionalProperties": {
"type": "string"
}
},
"link": {
"type": "string",
"description": "A deep link or URL opened on tap."
},
"image": {
"type": "string",
"description": "An https image URL."
},
"title": {
"type": "string",
"description": "The notification title."
},
"topic": {
"type": "string",
"description": "A topic name."
},
"fields": {
"type": "object",
"description": "Values for the template's {{fields}}."
},
"send_at": {
"type": "string",
"description": "An ISO time with a zone, up to 30 days ahead, like 2026-10-24T18:00:00+05:30."
},
"user_id": {
"type": "string",
"description": "Your own id for one user."
},
"template": {
"type": "string",
"description": "A saved template's name; title, body and the rest come from it."
},
"user_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "Up to 1,000 of your user ids."
},
"marketing": {
"type": "boolean",
"description": "true applies the app's daily cap of marketing pushes per user."
},
"fields_by_user": {
"type": "object",
"description": "With user_ids: each user's own field values, keyed by user id."
},
"idempotency_key": {
"type": "string",
"description": "Optional. The same key within 24 hours replays the first answer instead of sending again."
}
},
"additionalProperties": false
}{
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}get_push — Get a push
One push by id: status, devices, sent and failed, per platform.
{
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "The push id, msg_..."
}
},
"additionalProperties": false
}{
"readOnlyHint": true,
"openWorldHint": false
}list_pushes — List pushes
Pushes, newest first. On the Free plan only pushes still to go are listed (no delivery logs).
{
"type": "object",
"required": [],
"properties": {
"limit": {
"type": "integer",
"maximum": 100,
"minimum": 1
},
"before": {
"type": "string",
"description": "The next value from the previous page."
}
},
"additionalProperties": false
}{
"readOnlyHint": true,
"openWorldHint": false
}cancel_push — Cancel a scheduled push
Cancel a push that is scheduled and has not started sending.
{
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "The push id, msg_..."
}
},
"additionalProperties": false
}{
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}register_device — Register a device
Store a device's push token under your user id. Android and iOS tokens come from the Firebase or Apple SDK; for web, token is the PushSubscription as JSON.
{
"type": "object",
"required": [
"user_id",
"token",
"platform"
],
"properties": {
"name": {
"type": "string",
"description": "Optional label, like Rushi's iPhone."
},
"token": {
"type": "string",
"description": "The push token."
},
"user_id": {
"type": "string",
"description": "Your own id for the user."
},
"platform": {
"enum": [
"android",
"ios",
"web"
],
"type": "string"
}
},
"additionalProperties": false
}{
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}list_devices — List a user's devices
The devices registered for one user id, newest first, with platform and whether each is trusted for approvals.
{
"type": "object",
"required": [
"user_id"
],
"properties": {
"user_id": {
"type": "string",
"description": "Your own id for the user."
}
},
"additionalProperties": false
}{
"readOnlyHint": true,
"openWorldHint": false
}remove_device — Remove a device
Remove one device by id; it gets no more pushes.
{
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "The device id, dev_..."
}
},
"additionalProperties": false
}{
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}list_topics — List topics
Topics with how many users each has.
{
"type": "object",
"required": [],
"properties": {},
"additionalProperties": false
}{
"readOnlyHint": true,
"openWorldHint": false
}subscribe_topic — Subscribe a user to a topic
Add a user to a topic. The topic exists once it has a user.
{
"type": "object",
"required": [
"topic",
"user_id"
],
"properties": {
"topic": {
"type": "string",
"description": "Up to 64 letters, digits, dashes, dots or underscores."
},
"user_id": {
"type": "string",
"description": "Your own id for the user."
}
},
"additionalProperties": false
}{
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}unsubscribe_topic — Unsubscribe a user from a topic
Take a user off a topic.
{
"type": "object",
"required": [
"topic",
"user_id"
],
"properties": {
"topic": {
"type": "string",
"description": "The topic name."
},
"user_id": {
"type": "string",
"description": "Your own id for the user."
}
},
"additionalProperties": false
}{
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}list_templates — List templates
Saved push templates with their fields.
{
"type": "object",
"required": [],
"properties": {},
"additionalProperties": false
}{
"readOnlyHint": true,
"openWorldHint": false
}get_template — Get a template
One template by name.
{
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The template name, like payment_received."
}
},
"additionalProperties": false
}{
"readOnlyHint": true,
"openWorldHint": false
}save_template — Save a template
Create or replace a template. Put {{field}} where a value goes, or {{field|default}} for one with a fallback.
{
"type": "object",
"required": [
"name"
],
"properties": {
"body": {
"type": "string",
"description": "Body, with {{fields}}."
},
"data": {
"type": "object",
"description": "Optional data, with {{fields}} in the values.",
"additionalProperties": {
"type": "string"
}
},
"link": {
"type": "string",
"description": "Optional link."
},
"name": {
"type": "string",
"description": "Lowercase letters, digits and underscores."
},
"image": {
"type": "string",
"description": "Optional image URL."
},
"title": {
"type": "string",
"description": "Title, with {{fields}}."
}
},
"additionalProperties": false
}{
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}delete_template — Delete a template
Delete a template by name. Pushes already made from it are not changed.
{
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The template name."
}
},
"additionalProperties": false
}{
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}create_approval — Ask a user to approve
Send an approval request to the user's trusted phone, with number matching. The user must have a phone enrolled through the SignOps SDK.
{
"type": "object",
"required": [
"user_id",
"context"
],
"properties": {
"context": {
"type": "string",
"description": "What they are approving, up to 120 characters, like Sign in from Chrome on Windows."
},
"user_id": {
"type": "string",
"description": "Your own id for the user."
}
},
"additionalProperties": false
}{
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}get_approval — Get an approval
An approval request's status: pending, approved, denied, expired or cancelled.
{
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "The approval id, apr_..."
}
},
"additionalProperties": false
}{
"readOnlyHint": true,
"openWorldHint": false
}cancel_approval — Cancel an approval
Cancel a pending approval request.
{
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "The approval id, apr_..."
}
},
"additionalProperties": false
}{
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}list_passkeys — List a user's passkeys
The passkeys registered for one user id.
{
"type": "object",
"required": [
"user_id"
],
"properties": {
"user_id": {
"type": "string",
"description": "Your own id for the user."
}
},
"additionalProperties": false
}{
"readOnlyHint": true,
"openWorldHint": false
}get_authenticator — Get a user's authenticator
Whether a user has an authenticator app (TOTP) confirmed, when it was last used, backup codes left, and whether wrong codes have locked them.
{
"type": "object",
"required": [
"user_id"
],
"properties": {
"user_id": {
"type": "string",
"description": "Your own id for the user."
}
},
"additionalProperties": false
}{
"readOnlyHint": true,
"openWorldHint": false
}remove_authenticator — Remove a user's authenticator
Remove a user's authenticator app and backup codes, for a lost phone. They can enrol again.
{
"type": "object",
"required": [
"user_id"
],
"properties": {
"user_id": {
"type": "string",
"description": "Your own id for the user."
}
},
"additionalProperties": false
}{
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}unlock_user — Unlock a user
Clear the lock that five wrong codes in 15 minutes put on a user, and their count of wrong codes.
{
"type": "object",
"required": [
"user_id"
],
"properties": {
"user_id": {
"type": "string",
"description": "Your own id for the user."
}
},
"additionalProperties": false
}{
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}export_user — Export a user's data
Everything SignOps holds on one user id as JSON: devices (tokens shortened), topics, passkeys, authenticator status, approvals of the last 90 days, consent history and pushes sent to them.
{
"type": "object",
"required": [
"user_id"
],
"properties": {
"user_id": {
"type": "string",
"description": "Your own id for the user."
}
},
"additionalProperties": false
}{
"readOnlyHint": true,
"openWorldHint": false
}get_consent — Get a user's consent
The latest consent answer per purpose for one user, like marketing_push, and the history.
{
"type": "object",
"required": [
"user_id"
],
"properties": {
"user_id": {
"type": "string",
"description": "Your own id for the user."
}
},
"additionalProperties": false
}{
"readOnlyHint": true,
"openWorldHint": false
}Prompts
Not advertised
Resources
Not advertised
30-day availability
Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.
- Successful checks
- 1 of 1 (100%)
- Average latency
- 161 ms
- 95th percentile latency
- 161 ms
Maintenance history
Public check and source-refresh events. Editorial and ownership records remain private.
- · probe · passed · 161 ms · metadata changed · 23 tool(s)
Connect from your client
Each snippet registers the same endpoint; pick the client you use.
Claude Code
claude mcp add --transport http signops-mcp https://api.signops.dev/mcpCodex
codex mcp add signops-mcp --url https://api.signops.dev/mcpCursor
{
"mcpServers": {
"signops-mcp": {
"url": "https://api.signops.dev/mcp"
}
}
}Cline
{
"mcpServers": {
"signops-mcp": {
"type": "streamableHttp",
"url": "https://api.signops.dev/mcp",
"disabled": false
}
}
}VS Code
{
"servers": {
"signops-mcp": {
"type": "http",
"url": "https://api.signops.dev/mcp"
}
}
}Gemini CLI
gemini mcp add --transport http signops-mcp https://api.signops.dev/mcpClaude Desktop
{
"mcpServers": {
"signops-mcp": {
"url": "https://api.signops.dev/mcp"
}
}
}Windsurf
{
"mcpServers": {
"signops-mcp": {
"serverUrl": "https://api.signops.dev/mcp"
}
}
}Let your agent find its tools
Find servers like SignOps MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.
Other ai and machine learning servers
Do you run SignOps MCP?
Prove ownership with a DNS record, a well-known file, or your Official MCP Registry entry, and your edits publish immediately. Proofs are re-checked weekly; admins can still hide or remove a listing.