← WebMCP Directory

Tool tree

gabrielcatdeveloper.github.io

Travel & EventsTools verified
Website
portami
Explore capabilities
    get_identityAnswer

    Return the current anonymous identity (pubKey, anonId, createdAt). Read-only — never returns the private key.

    View tool JSON
    {
      "name": "get_identity",
      "kind": "answer",
      "impl": "imperative",
      "description": "Return the current anonymous identity (pubKey, anonId, createdAt). Read-only — never returns the private key.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    export_identity_jwkAction

    Return the private key as a JSON Web Key. ⚠️ Anyone with this file can sign as you — handle with care. Destructive to leak.

    View tool JSON
    {
      "name": "export_identity_jwk",
      "kind": "act",
      "impl": "imperative",
      "description": "Return the private key as a JSON Web Key. ⚠️ Anyone with this file can sign as you — handle with care. Destructive to leak.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    import_identity_jwkSensitive Action

    Replace the local identity with the one in the provided JWK. ⚠️ Destructive: your previous anonId and any votes tied to it are gone.

    View tool JSON
    {
      "name": "import_identity_jwk",
      "kind": "transact",
      "impl": "imperative",
      "description": "Replace the local identity with the one in the provided JWK. ⚠️ Destructive: your previous anonId and any votes tied to it are gone.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "privKeyJwk": {
            "type": "string",
            "description": "The JSON Web Key containing the private key (must include `d`)."
          }
        },
        "required": [
          "privKeyJwk"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    regenerate_identitySensitive Action

    Generate a fresh Ed25519 keypair. ⚠️ Destructive: previous anonId, votes, and trust relationships are lost.

    View tool JSON
    {
      "name": "regenerate_identity",
      "kind": "transact",
      "impl": "imperative",
      "description": "Generate a fresh Ed25519 keypair. ⚠️ Destructive: previous anonId, votes, and trust relationships are lost.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    reset_identitySensitive Action

    Wipe the identity AND all local data (routes, proposals, recordings, drafts, paired devices, trips, sync metadata). ⚠️⚠️ Very destructive — cannot be undone.

    View tool JSON
    {
      "name": "reset_identity",
      "kind": "transact",
      "impl": "imperative",
      "description": "Wipe the identity AND all local data (routes, proposals, recordings, drafts, paired devices, trips, sync metadata). ⚠️⚠️ Very destructive — cannot be undone.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    export_identity_backup_fileAction

    Return a passphrase-protected backup file (.portami-backup shape). Pass the same passphrase to `import_identity_backup_file` to restore. PBKDF2-SHA256 600k iters + AES-GCM.

    View tool JSON
    {
      "name": "export_identity_backup_file",
      "kind": "act",
      "impl": "imperative",
      "description": "Return a passphrase-protected backup file (.portami-backup shape). Pass the same passphrase to `import_identity_backup_file` to restore. PBKDF2-SHA256 600k iters + AES-GCM.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "passphrase": {
            "type": "string",
            "description": "Passphrase (≥8 chars) used to encrypt the private key."
          }
        },
        "required": [
          "passphrase"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    import_identity_backup_fileSensitive Action

    Restore an identity from a passphrase-protected backup. ⚠️ Destructive: replaces the current identity.

    View tool JSON
    {
      "name": "import_identity_backup_file",
      "kind": "transact",
      "impl": "imperative",
      "description": "Restore an identity from a passphrase-protected backup. ⚠️ Destructive: replaces the current identity.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "backupJson": {
            "type": "string",
            "description": "The full backup object as a JSON string (the contents of the .portami-backup file)."
          },
          "passphrase": {
            "type": "string",
            "description": "The passphrase used at export time."
          }
        },
        "required": [
          "backupJson",
          "passphrase"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    list_routesAnswer

    List routes from the local cache. Optional filters: only mine, only favourites, vehicle kind, name substring.

    View tool JSON
    {
      "name": "list_routes",
      "kind": "answer",
      "impl": "imperative",
      "description": "List routes from the local cache. Optional filters: only mine, only favourites, vehicle kind, name substring.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "onlyMine": {
            "type": "string",
            "description": "Filter to routes I created.",
            "enum": [
              "true",
              "false"
            ]
          },
          "onlyFavorites": {
            "type": "string",
            "description": "Filter to favourite routes.",
            "enum": [
              "true",
              "false"
            ]
          },
          "vehicleKind": {
            "type": "string",
            "description": "Filter by vehicle kind.",
            "enum": [
              "bus",
              "train",
              "tram",
              "metro",
              "other"
            ]
          },
          "query": {
            "type": "string",
            "description": "Case-insensitive substring match on the route name."
          },
          "limit": {
            "type": "number",
            "description": "Max routes to return (default 100, max 500).",
            "minimum": 1,
            "maximum": 500
          }
        },
        "required": [],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    get_routeAnswer

    Return a single route by id (from the local cache).

    View tool JSON
    {
      "name": "get_route",
      "kind": "answer",
      "impl": "imperative",
      "description": "Return a single route by id (from the local cache).",
      "inputSchema": {
        "type": "object",
        "properties": {
          "routeId": {
            "type": "string",
            "description": "The route id."
          }
        },
        "required": [
          "routeId"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    find_routes_nearbyAnswer

    Query the server for routes near a coordinate. Results are merged into the local cache and returned.

    View tool JSON
    {
      "name": "find_routes_nearby",
      "kind": "answer",
      "impl": "imperative",
      "description": "Query the server for routes near a coordinate. Results are merged into the local cache and returned.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "lat": {
            "type": "number",
            "description": "Latitude (WGS84).",
            "minimum": -90,
            "maximum": 90
          },
          "lng": {
            "type": "number",
            "description": "Longitude (WGS84).",
            "minimum": -180,
            "maximum": 180
          },
          "radiusKm": {
            "type": "number",
            "description": "Search radius in km (default 5).",
            "minimum": 0.1,
            "maximum": 50
          }
        },
        "required": [
          "lat",
          "lng"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    mark_route_favoriteAction

    Toggle a route's favourite flag in the local cache.

    View tool JSON
    {
      "name": "mark_route_favorite",
      "kind": "act",
      "impl": "imperative",
      "description": "Toggle a route's favourite flag in the local cache.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "routeId": {
            "type": "string",
            "description": "Route id."
          },
          "favorite": {
            "type": "string",
            "description": "\"true\" to mark, \"false\" to unmark.",
            "enum": [
              "true",
              "false"
            ]
          }
        },
        "required": [
          "routeId",
          "favorite"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    get_active_busesAnswer

    List buses currently on trips. Optionally filter by routeId. Returns trip id, route, anonId, position, speed, vehicle kind.

    View tool JSON
    {
      "name": "get_active_buses",
      "kind": "answer",
      "impl": "imperative",
      "description": "List buses currently on trips. Optionally filter by routeId. Returns trip id, route, anonId, position, speed, vehicle kind.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "routeId": {
            "type": "string",
            "description": "Optional. If set, return only buses on this route."
          }
        },
        "required": [],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    get_stop_requestAnswer

    Return how to ask the driver to stop on a given route (button, shout, app, other/unknown) and the confirmation count.

    View tool JSON
    {
      "name": "get_stop_request",
      "kind": "answer",
      "impl": "imperative",
      "description": "Return how to ask the driver to stop on a given route (button, shout, app, other/unknown) and the confirmation count.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "routeId": {
            "type": "string",
            "description": "Route id."
          }
        },
        "required": [
          "routeId"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    set_stop_requestAction

    Propose new stop-request info for a route. The server increments the confirmation count if it already exists; otherwise it seeds a new entry.

    View tool JSON
    {
      "name": "set_stop_request",
      "kind": "act",
      "impl": "imperative",
      "description": "Propose new stop-request info for a route. The server increments the confirmation count if it already exists; otherwise it seeds a new entry.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "routeId": {
            "type": "string",
            "description": "Route id."
          },
          "type": {
            "type": "string",
            "description": "Mechanism to request a stop.",
            "enum": [
              "button",
              "shout",
              "app",
              "other",
              "unknown"
            ]
          },
          "notes": {
            "type": "string",
            "description": "Free-text instructions (optional)."
          },
          "buttonPhotoUrl": {
            "type": "string",
            "description": "Data URL of a photo of the button (optional)."
          }
        },
        "required": [
          "routeId",
          "type"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    list_proposalsAnswer

    List proposals for a route. Optional status filter. Pulls from the server (and merges into local cache).

    View tool JSON
    {
      "name": "list_proposals",
      "kind": "answer",
      "impl": "imperative",
      "description": "List proposals for a route. Optional status filter. Pulls from the server (and merges into local cache).",
      "inputSchema": {
        "type": "object",
        "properties": {
          "routeId": {
            "type": "string",
            "description": "Route id."
          },
          "status": {
            "type": "string",
            "description": "Filter by status.",
            "enum": [
              "pending",
              "approved",
              "rejected",
              "expired"
            ]
          },
          "limit": {
            "type": "number",
            "description": "Max proposals to return (default 50, max 200).",
            "minimum": 1,
            "maximum": 200
          }
        },
        "required": [
          "routeId"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    get_proposalAnswer

    Read a single proposal by id (from the local cache).

    View tool JSON
    {
      "name": "get_proposal",
      "kind": "answer",
      "impl": "imperative",
      "description": "Read a single proposal by id (from the local cache).",
      "inputSchema": {
        "type": "object",
        "properties": {
          "proposalId": {
            "type": "string",
            "description": "Proposal id."
          }
        },
        "required": [
          "proposalId"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    create_proposalAction

    Propose changes to a route. Pass `diff` as a JSON string with one or more RouteDiff entries. Each entry shape: stop-added {stop}, stop-removed {stopId}, stop-moved {stopId, fromLat, fromLng, toLat, toLng}, stop-renamed {stopId, fromName, toName}, polyline-partial-replaced {fromIdx, toIdx, newSegment}, meta-changed {field:"name", from, to}.

    View tool JSON
    {
      "name": "create_proposal",
      "kind": "act",
      "impl": "imperative",
      "description": "Propose changes to a route. Pass `diff` as a JSON string with one or more RouteDiff entries. Each entry shape: stop-added {stop}, stop-removed {stopId}, stop-moved {stopId, fromLat, fromLng, toLat, toLng}, stop-renamed {stopId, fromName, toName}, polyline-partial-replaced {fromIdx, toIdx, newSegment}, meta-changed {field:\"name\", from, to}.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "routeId": {
            "type": "string",
            "description": "Route id."
          },
          "title": {
            "type": "string",
            "description": "Short title for the proposal."
          },
          "rationale": {
            "type": "string",
            "description": "Why this change is needed (optional)."
          },
          "diff": {
            "type": "string",
            "description": "JSON-encoded array of RouteDiff entries. Example: [{\"kind\":\"stop-renamed\",\"stopId\":\"s1\",\"fromName\":\"A\",\"toName\":\"A (norte)\"}]"
          }
        },
        "required": [
          "routeId",
          "title",
          "diff"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    vote_proposalAction

    Cast your vote (approve or reject) on a proposal. You can only vote once per proposal; revote is not allowed.

    View tool JSON
    {
      "name": "vote_proposal",
      "kind": "act",
      "impl": "imperative",
      "description": "Cast your vote (approve or reject) on a proposal. You can only vote once per proposal; revote is not allowed.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "proposalId": {
            "type": "string",
            "description": "Proposal id."
          },
          "vote": {
            "type": "string",
            "description": "Your vote.",
            "enum": [
              "approve",
              "reject"
            ]
          }
        },
        "required": [
          "proposalId",
          "vote"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    list_proposal_diff_kindsAnswer

    Return the RouteDiff kinds accepted by `create_proposal`.

    View tool JSON
    {
      "name": "list_proposal_diff_kinds",
      "kind": "answer",
      "impl": "imperative",
      "description": "Return the RouteDiff kinds accepted by `create_proposal`.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": [],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    get_active_tripAnswer

    Return the currently active trip (or null). Includes route, startedAt, last sample.

    View tool JSON
    {
      "name": "get_active_trip",
      "kind": "answer",
      "impl": "imperative",
      "description": "Return the currently active trip (or null). Includes route, startedAt, last sample.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": [],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    start_tripAction

    Start a new trip on a route. Requires the route to be in the local cache. Calls POST /trips/start (signed).

    View tool JSON
    {
      "name": "start_trip",
      "kind": "act",
      "impl": "imperative",
      "description": "Start a new trip on a route. Requires the route to be in the local cache. Calls POST /trips/start (signed).",
      "inputSchema": {
        "type": "object",
        "properties": {
          "routeId": {
            "type": "string",
            "description": "Route id to start the trip on."
          }
        },
        "required": [
          "routeId"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    end_tripAction

    End the currently active trip. Also stops any in-flight trip-share. Reason is one of "manual" (user), "heuristic" (auto-end from trip detector), or "arrival" (got off at destination).

    View tool JSON
    {
      "name": "end_trip",
      "kind": "act",
      "impl": "imperative",
      "description": "End the currently active trip. Also stops any in-flight trip-share. Reason is one of \"manual\" (user), \"heuristic\" (auto-end from trip detector), or \"arrival\" (got off at destination).",
      "inputSchema": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "description": "Why the trip ended.",
            "enum": [
              "manual",
              "heuristic",
              "arrival"
            ]
          }
        },
        "required": [
          "reason"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    list_recent_tripsAnswer

    Return trips stored locally, newest first.

    View tool JSON
    {
      "name": "list_recent_trips",
      "kind": "answer",
      "impl": "imperative",
      "description": "Return trips stored locally, newest first.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "routeId": {
            "type": "string",
            "description": "Optional routeId filter."
          },
          "limit": {
            "type": "number",
            "description": "Max trips to return (default 20, max 100).",
            "minimum": 1,
            "maximum": 100
          }
        },
        "required": [],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    push_gps_sampleAction

    Push a single GPS sample for the active trip to the server. Requires the "Modo colaborador" flag enabled in Settings and an active trip. Signed POST /trips/:id/samples.

    View tool JSON
    {
      "name": "push_gps_sample",
      "kind": "act",
      "impl": "imperative",
      "description": "Push a single GPS sample for the active trip to the server. Requires the \"Modo colaborador\" flag enabled in Settings and an active trip. Signed POST /trips/:id/samples.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ts": {
            "type": "number",
            "description": "Sample timestamp (ms since epoch)."
          },
          "lat": {
            "type": "number",
            "description": "Latitude.",
            "minimum": -90,
            "maximum": 90
          },
          "lng": {
            "type": "number",
            "description": "Longitude.",
            "minimum": -180,
            "maximum": 180
          },
          "acc": {
            "type": "number",
            "description": "Accuracy in meters."
          },
          "speed": {
            "type": "number",
            "description": "Speed in m/s (optional)."
          }
        },
        "required": [
          "ts",
          "lat",
          "lng",
          "acc"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    start_trip_shareAction

    Begin broadcasting the active trip to all connected paired peers. Requires an active trip (call start_trip first). Returns the share id and per-recipient status.

    View tool JSON
    {
      "name": "start_trip_share",
      "kind": "act",
      "impl": "imperative",
      "description": "Begin broadcasting the active trip to all connected paired peers. Requires an active trip (call start_trip first). Returns the share id and per-recipient status.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "plannedRouteJson": {
            "type": "string",
            "description": "Optional JSON-encoded Journey plan (pass to override the trip's attached plan)."
          }
        },
        "required": [],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    stop_trip_shareAction

    Stop broadcasting the active trip and notify recipients.

    View tool JSON
    {
      "name": "stop_trip_share",
      "kind": "act",
      "impl": "imperative",
      "description": "Stop broadcasting the active trip and notify recipients.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "description": "Why sharing stopped.",
            "enum": [
              "manual",
              "heuristic",
              "arrival",
              "trip-ended"
            ]
          }
        },
        "required": [],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    get_outgoing_shareAnswer

    Return the currently active outgoing share (or null if not sharing). Includes per-recipient delivery status.

    View tool JSON
    {
      "name": "get_outgoing_share",
      "kind": "answer",
      "impl": "imperative",
      "description": "Return the currently active outgoing share (or null if not sharing). Includes per-recipient delivery status.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    list_incoming_sharesAnswer

    List trips friends are currently sharing with you (Following). Includes last known location, planned route, ETA to next stop.

    View tool JSON
    {
      "name": "list_incoming_shares",
      "kind": "answer",
      "impl": "imperative",
      "description": "List trips friends are currently sharing with you (Following). Includes last known location, planned route, ETA to next stop.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    list_outgoing_share_historyAnswer

    Return the last 20 outgoing trip shares (newest first).

    View tool JSON
    {
      "name": "list_outgoing_share_history",
      "kind": "answer",
      "impl": "imperative",
      "description": "Return the last 20 outgoing trip shares (newest first).",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    retry_trip_share_recipientAction

    Manually retry sending the trip-share-start message to a specific paired device (by deviceId). No-op if the peer is disconnected.

    View tool JSON
    {
      "name": "retry_trip_share_recipient",
      "kind": "act",
      "impl": "imperative",
      "description": "Manually retry sending the trip-share-start message to a specific paired device (by deviceId). No-op if the peer is disconnected.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "deviceId": {
            "type": "string",
            "description": "Paired device id (== pubKey)."
          }
        },
        "required": [
          "deviceId"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    get_friend_locationAnswer

    Return the most recent location received from a specific friend (by their anonId).

    View tool JSON
    {
      "name": "get_friend_location",
      "kind": "answer",
      "impl": "imperative",
      "description": "Return the most recent location received from a specific friend (by their anonId).",
      "inputSchema": {
        "type": "object",
        "properties": {
          "fromAnonId": {
            "type": "string",
            "description": "Friend anonId."
          }
        },
        "required": [
          "fromAnonId"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    remove_incoming_shareAction

    Delete the local record of an incoming shared trip. The friend keeps sharing — you just stop following.

    View tool JSON
    {
      "name": "remove_incoming_share",
      "kind": "act",
      "impl": "imperative",
      "description": "Delete the local record of an incoming shared trip. The friend keeps sharing — you just stop following.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "fromAnonId": {
            "type": "string",
            "description": "Friend anonId."
          }
        },
        "required": [
          "fromAnonId"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    is_sharingAnswer

    Return true iff the user is currently broadcasting a trip.

    View tool JSON
    {
      "name": "is_sharing",
      "kind": "answer",
      "impl": "imperative",
      "description": "Return true iff the user is currently broadcasting a trip.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    list_peer_statusesAnswer

    Return the current WebRTC connection status of every paired device: disconnected, connecting, connected, reconnecting, unreachable, revoked, error.

    View tool JSON
    {
      "name": "list_peer_statuses",
      "kind": "answer",
      "impl": "imperative",
      "description": "Return the current WebRTC connection status of every paired device: disconnected, connecting, connected, reconnecting, unreachable, revoked, error.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    list_paired_devicesAnswer

    List every WebRTC-paired device the user has, with last-seen timestamps.

    View tool JSON
    {
      "name": "list_paired_devices",
      "kind": "answer",
      "impl": "imperative",
      "description": "List every WebRTC-paired device the user has, with last-seen timestamps.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    revoke_paired_deviceAction

    Remove a paired device from the local store and close its WebRTC connection. ⚠️ Destructive: you'll need to re-pair to share trips with them again.

    View tool JSON
    {
      "name": "revoke_paired_device",
      "kind": "act",
      "impl": "imperative",
      "description": "Remove a paired device from the local store and close its WebRTC connection. ⚠️ Destructive: you'll need to re-pair to share trips with them again.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "deviceId": {
            "type": "string",
            "description": "Device id (== pubKey)."
          }
        },
        "required": [
          "deviceId"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    create_pairing_offerAction

    Initiate a pairing session: generate an SDP offer. The returned `offer` is an opaque JSON string — paste it into the friend's portami (or hand it to `join_with_offer`).

    View tool JSON
    {
      "name": "create_pairing_offer",
      "kind": "act",
      "impl": "imperative",
      "description": "Initiate a pairing session: generate an SDP offer. The returned `offer` is an opaque JSON string — paste it into the friend's portami (or hand it to `join_with_offer`).",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    join_with_pairing_offerAction

    Joiner side: take an SDP offer from the initiator and produce an SDP answer to send back.

    View tool JSON
    {
      "name": "join_with_pairing_offer",
      "kind": "act",
      "impl": "imperative",
      "description": "Joiner side: take an SDP offer from the initiator and produce an SDP answer to send back.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "offer": {
            "type": "string",
            "description": "The SDP offer JSON string."
          }
        },
        "required": [
          "offer"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    finish_pairing_as_initiatorAction

    Initiator side: paste the joiner's SDP answer here to complete the handshake.

    View tool JSON
    {
      "name": "finish_pairing_as_initiator",
      "kind": "act",
      "impl": "imperative",
      "description": "Initiator side: paste the joiner's SDP answer here to complete the handshake.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "answer": {
            "type": "string",
            "description": "The SDP answer JSON string."
          }
        },
        "required": [
          "answer"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    reset_pairingAction

    Abort the current pairing flow and clear all transient state. Useful when a flow stalls.

    View tool JSON
    {
      "name": "reset_pairing",
      "kind": "act",
      "impl": "imperative",
      "description": "Abort the current pairing flow and clear all transient state. Useful when a flow stalls.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    get_pairing_statusAnswer

    Return the current pairing phase (idle, awaiting-peer, verifying, transferring, syncing, success, error) and the pair-code for verification.

    View tool JSON
    {
      "name": "get_pairing_status",
      "kind": "answer",
      "impl": "imperative",
      "description": "Return the current pairing phase (idle, awaiting-peer, verifying, transferring, syncing, success, error) and the pair-code for verification.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    create_invite_linkAction

    Create a /connect deeplink that bundles an SDP offer with the emitter's anonId + alias + optional tripShareId. The friend opens it in portami to pair + accept the trip share.

    View tool JSON
    {
      "name": "create_invite_link",
      "kind": "act",
      "impl": "imperative",
      "description": "Create a /connect deeplink that bundles an SDP offer with the emitter's anonId + alias + optional tripShareId. The friend opens it in portami to pair + accept the trip share.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "tripShareId": {
            "type": "string",
            "description": "Optional tripShareId to auto-attach on accept."
          },
          "baseUrl": {
            "type": "string",
            "description": "Override the origin (default: current location)."
          }
        },
        "required": [],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    build_answer_back_urlAction

    Joiner side: produce the /connect-back URL containing the SDP answer, to be opened by the initiator.

    View tool JSON
    {
      "name": "build_answer_back_url",
      "kind": "act",
      "impl": "imperative",
      "description": "Joiner side: produce the /connect-back URL containing the SDP answer, to be opened by the initiator.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "emitterAnonId": {
            "type": "string",
            "description": "Initiator's anonId (the `for` parameter)."
          },
          "answer": {
            "type": "string",
            "description": "The SDP answer JSON string."
          }
        },
        "required": [
          "emitterAnonId",
          "answer"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    plan_journeyAction

    Plan a multi-leg journey from a coordinate A to coordinate B. Optional filters: departAfter (ms epoch), maxWalkSpeedMs (default 1.4), maxBoardings (default 3), walkRadiusM (default 600), excludeRouteIds (JSON array of strings), vehicleKinds (JSON array).

    View tool JSON
    {
      "name": "plan_journey",
      "kind": "act",
      "impl": "imperative",
      "description": "Plan a multi-leg journey from a coordinate A to coordinate B. Optional filters: departAfter (ms epoch), maxWalkSpeedMs (default 1.4), maxBoardings (default 3), walkRadiusM (default 600), excludeRouteIds (JSON array of strings), vehicleKinds (JSON array).",
      "inputSchema": {
        "type": "object",
        "properties": {
          "fromLat": {
            "type": "number",
            "description": "Origin latitude.",
            "minimum": -90,
            "maximum": 90
          },
          "fromLng": {
            "type": "number",
            "description": "Origin longitude.",
            "minimum": -180,
            "maximum": 180
          },
          "toLat": {
            "type": "number",
            "description": "Destination latitude.",
            "minimum": -90,
            "maximum": 90
          },
          "toLng": {
            "type": "number",
            "description": "Destination longitude.",
            "minimum": -180,
            "maximum": 180
          },
          "departAfterUtc": {
            "type": "number",
            "description": "Depart after this timestamp (ms epoch). Defaults to now."
          },
          "maxWalkSpeedMs": {
            "type": "number",
            "description": "Max walking speed in m/s (default 1.4)."
          },
          "maxBoardings": {
            "type": "number",
            "description": "Max boardings including the first (default 3)."
          },
          "walkRadiusM": {
            "type": "number",
            "description": "Search radius around from/to in meters (default 600)."
          },
          "excludeRouteIdsJson": {
            "type": "string",
            "description": "JSON array of route ids to exclude, e.g. [\"r1\",\"r2\"]."
          },
          "vehicleKindsJson": {
            "type": "string",
            "description": "JSON array of vehicle kinds to include, e.g. [\"bus\",\"train\"]. Allowed: bus, train, tram, metro, other."
          }
        },
        "required": [
          "fromLat",
          "fromLng",
          "toLat",
          "toLng"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    list_incidentsAnswer

    List active service incidents. Optional routeId filter. Auto-hides resolved + auto-expired.

    View tool JSON
    {
      "name": "list_incidents",
      "kind": "answer",
      "impl": "imperative",
      "description": "List active service incidents. Optional routeId filter. Auto-hides resolved + auto-expired.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "routeId": {
            "type": "string",
            "description": "Optional route id filter."
          }
        },
        "required": [],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    report_incidentAction

    Report a service incident (cancellation, delay, diversion, other) on a route. Signed.

    View tool JSON
    {
      "name": "report_incident",
      "kind": "act",
      "impl": "imperative",
      "description": "Report a service incident (cancellation, delay, diversion, other) on a route. Signed.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "routeId": {
            "type": "string",
            "description": "Route id."
          },
          "kind": {
            "type": "string",
            "description": "Incident kind.",
            "enum": [
              "cancellation",
              "delay",
              "diversion",
              "other"
            ]
          },
          "reason": {
            "type": "string",
            "description": "Free text explaining the incident (e.g. \"Manifestación en Sol\")."
          },
          "endsAt": {
            "type": "number",
            "description": "Optional auto-expiry timestamp (ms epoch)."
          }
        },
        "required": [
          "routeId",
          "kind",
          "reason"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    resolve_incidentAction

    Mark an incident as resolved. Signed.

    View tool JSON
    {
      "name": "resolve_incident",
      "kind": "act",
      "impl": "imperative",
      "description": "Mark an incident as resolved. Signed.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "incidentId": {
            "type": "string",
            "description": "Incident id."
          }
        },
        "required": [
          "incidentId"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    list_stop_alertsAnswer

    List local stop alerts. Either pass a routeId to filter, or omit to list every alert on the device.

    View tool JSON
    {
      "name": "list_stop_alerts",
      "kind": "answer",
      "impl": "imperative",
      "description": "List local stop alerts. Either pass a routeId to filter, or omit to list every alert on the device.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "routeId": {
            "type": "string",
            "description": "Route id filter (omit for all)."
          }
        },
        "required": [],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    add_stop_alertAction

    Add a stop alert. Provide either `triggerMinutes` (ETA-based) or `triggerDistanceM` (distance-based) or both.

    View tool JSON
    {
      "name": "add_stop_alert",
      "kind": "act",
      "impl": "imperative",
      "description": "Add a stop alert. Provide either `triggerMinutes` (ETA-based) or `triggerDistanceM` (distance-based) or both.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "routeId": {
            "type": "string",
            "description": "Route id this alert belongs to."
          },
          "stopId": {
            "type": "string",
            "description": "Stop id within the route."
          },
          "stopName": {
            "type": "string",
            "description": "Stop name (human-readable, used in the notification)."
          },
          "triggerMinutes": {
            "type": "number",
            "description": "Fire when ETA ≤ this many minutes."
          },
          "triggerDistanceM": {
            "type": "number",
            "description": "Fire when distance ≤ this many meters."
          }
        },
        "required": [
          "routeId",
          "stopId",
          "stopName"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    remove_stop_alertSensitive Action

    Delete a stop alert by id.

    View tool JSON
    {
      "name": "remove_stop_alert",
      "kind": "transact",
      "impl": "imperative",
      "description": "Delete a stop alert by id.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "description": "Alert id (autoincrement)."
          }
        },
        "required": [
          "id"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    reset_stop_alerts_for_routeAction

    Reset the "triggered" flag on every alert for a route so they'll fire again on the next trip.

    View tool JSON
    {
      "name": "reset_stop_alerts_for_route",
      "kind": "act",
      "impl": "imperative",
      "description": "Reset the \"triggered\" flag on every alert for a route so they'll fire again on the next trip.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "routeId": {
            "type": "string",
            "description": "Route id."
          }
        },
        "required": [
          "routeId"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    clear_stop_alertsSensitive Action

    Delete every stop alert on the device. ⚠️ Destructive.

    View tool JSON
    {
      "name": "clear_stop_alerts",
      "kind": "transact",
      "impl": "imperative",
      "description": "Delete every stop alert on the device. ⚠️ Destructive.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    get_settingsAnswer

    Return current settings: language, collaborate flag, testing mode + GPS source, and server health snapshot.

    View tool JSON
    {
      "name": "get_settings",
      "kind": "answer",
      "impl": "imperative",
      "description": "Return current settings: language, collaborate flag, testing mode + GPS source, and server health snapshot.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    set_collaborate_enabledAction

    Enable or disable the "Modo colaborador" flag. When ON, every GPS sample of an active trip is POSTed (signed) to the server. OFF by default — the user must opt in.

    View tool JSON
    {
      "name": "set_collaborate_enabled",
      "kind": "act",
      "impl": "imperative",
      "description": "Enable or disable the \"Modo colaborador\" flag. When ON, every GPS sample of an active trip is POSTed (signed) to the server. OFF by default — the user must opt in.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "string",
            "description": "\"true\" to enable, \"false\" to disable.",
            "enum": [
              "true",
              "false"
            ]
          }
        },
        "required": [
          "enabled"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    set_testing_modeAction

    Enable or disable testing mode. When ON, MSW intercepts every API call and the GPS source becomes synthetic (unless you also pass gpsMode="real"). Requires page reload for the change to fully take effect.

    View tool JSON
    {
      "name": "set_testing_mode",
      "kind": "act",
      "impl": "imperative",
      "description": "Enable or disable testing mode. When ON, MSW intercepts every API call and the GPS source becomes synthetic (unless you also pass gpsMode=\"real\"). Requires page reload for the change to fully take effect.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "string",
            "description": "\"true\" to enable testing mode.",
            "enum": [
              "true",
              "false"
            ]
          },
          "gpsMode": {
            "type": "string",
            "description": "GPS source when testing mode is on.",
            "enum": [
              "simulated",
              "real"
            ]
          }
        },
        "required": [],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    set_languageAction

    Change the UI language (es/ca/en). Reload the page for the change to apply everywhere.

    View tool JSON
    {
      "name": "set_language",
      "kind": "act",
      "impl": "imperative",
      "description": "Change the UI language (es/ca/en). Reload the page for the change to apply everywhere.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "language": {
            "type": "string",
            "description": "Language code.",
            "enum": [
              "es",
              "ca",
              "en"
            ]
          }
        },
        "required": [
          "language"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    get_current_positionAnswer

    Return the most recent GPS sample (or wait for one if none has arrived). May trigger the browser permission prompt on first call.

    View tool JSON
    {
      "name": "get_current_position",
      "kind": "answer",
      "impl": "imperative",
      "description": "Return the most recent GPS sample (or wait for one if none has arrived). May trigger the browser permission prompt on first call.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    get_geolocation_permissionAnswer

    Return the current geolocation permission state without requesting it. One of: unknown, granted, denied, prompt, error.

    View tool JSON
    {
      "name": "get_geolocation_permission",
      "kind": "answer",
      "impl": "imperative",
      "description": "Return the current geolocation permission state without requesting it. One of: unknown, granted, denied, prompt, error.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    export_my_routes_geojsonAction

    Build a signed GeoJSON FeatureCollection containing all routes the user created + their proposals. Returns the full JSON so the agent can write it to disk or hand it off.

    View tool JSON
    {
      "name": "export_my_routes_geojson",
      "kind": "act",
      "impl": "imperative",
      "description": "Build a signed GeoJSON FeatureCollection containing all routes the user created + their proposals. Returns the full JSON so the agent can write it to disk or hand it off.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": [],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    import_geojsonAction

    Import a previously-exported FeatureCollection. Verifies the signature; if invalid, marks the import as read-only (no edits applied). Use `resolutionsJson` to override the per-route resolution (default: keep if exists, replace otherwise).

    View tool JSON
    {
      "name": "import_geojson",
      "kind": "act",
      "impl": "imperative",
      "description": "Import a previously-exported FeatureCollection. Verifies the signature; if invalid, marks the import as read-only (no edits applied). Use `resolutionsJson` to override the per-route resolution (default: keep if exists, replace otherwise).",
      "inputSchema": {
        "type": "object",
        "properties": {
          "geojson": {
            "type": "string",
            "description": "The GeoJSON object as a JSON string."
          },
          "resolutionsJson": {
            "type": "string",
            "description": "Optional JSON map of routeId → mode. Mode is one of: replace, keep, merge."
          }
        },
        "required": [
          "geojson"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    list_bus_reportsAnswer

    List observations about specific buses on a route, newest first.

    View tool JSON
    {
      "name": "list_bus_reports",
      "kind": "answer",
      "impl": "imperative",
      "description": "List observations about specific buses on a route, newest first.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "routeId": {
            "type": "string",
            "description": "Route id."
          },
          "limit": {
            "type": "number",
            "description": "Max reports to return (default 20, max 100).",
            "minimum": 1,
            "maximum": 100
          }
        },
        "required": [
          "routeId"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    report_busAction

    Record an observation about a specific bus on a route (license plate, stop button presence, photo, notes). Signed.

    View tool JSON
    {
      "name": "report_bus",
      "kind": "act",
      "impl": "imperative",
      "description": "Record an observation about a specific bus on a route (license plate, stop button presence, photo, notes). Signed.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "routeId": {
            "type": "string",
            "description": "Route id."
          },
          "plate": {
            "type": "string",
            "description": "License plate / fleet number."
          },
          "hasStopButton": {
            "type": "string",
            "description": "\"true\" if the bus has a stop button.",
            "enum": [
              "true",
              "false"
            ]
          },
          "notes": {
            "type": "string",
            "description": "Free notes (optional)."
          },
          "buttonPhotoUrl": {
            "type": "string",
            "description": "Data URL of a photo of the button (optional)."
          }
        },
        "required": [
          "routeId",
          "plate"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    send_rescue_meSensitive Action

    Broadcast a panic alert to every connected paired peer. Use ONLY when the user is in trouble. The receivers see a top-of-screen banner with the user's last location.

    View tool JSON
    {
      "name": "send_rescue_me",
      "kind": "transact",
      "impl": "imperative",
      "description": "Broadcast a panic alert to every connected paired peer. Use ONLY when the user is in trouble. The receivers see a top-of-screen banner with the user's last location.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Short message included in the alert (optional)."
          },
          "lat": {
            "type": "number",
            "description": "Optional current latitude to attach."
          },
          "lng": {
            "type": "number",
            "description": "Optional current longitude to attach."
          },
          "accuracyM": {
            "type": "number",
            "description": "Optional accuracy in meters."
          }
        },
        "required": [],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    list_pending_rescuesAnswer

    List rescue alerts received from paired friends that have not yet been acknowledged.

    View tool JSON
    {
      "name": "list_pending_rescues",
      "kind": "answer",
      "impl": "imperative",
      "description": "List rescue alerts received from paired friends that have not yet been acknowledged.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": [],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    list_all_rescuesAnswer

    List every rescue alert currently in memory (acknowledged + pending).

    View tool JSON
    {
      "name": "list_all_rescues",
      "kind": "answer",
      "impl": "imperative",
      "description": "List every rescue alert currently in memory (acknowledged + pending).",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": [],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    acknowledge_rescueAction

    Locally mark a rescue alert as acknowledged (no effect on the sender). Use `remove_rescue` to also drop it from memory.

    View tool JSON
    {
      "name": "acknowledge_rescue",
      "kind": "act",
      "impl": "imperative",
      "description": "Locally mark a rescue alert as acknowledged (no effect on the sender). Use `remove_rescue` to also drop it from memory.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "rescueId": {
            "type": "string",
            "description": "Rescue id."
          }
        },
        "required": [
          "rescueId"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    remove_rescueAction

    Drop a rescue alert from the in-memory store.

    View tool JSON
    {
      "name": "remove_rescue",
      "kind": "act",
      "impl": "imperative",
      "description": "Drop a rescue alert from the in-memory store.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "rescueId": {
            "type": "string",
            "description": "Rescue id."
          }
        },
        "required": [
          "rescueId"
        ],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    get_rescue_ttl_msAnswer

    Return the in-memory TTL (ms) applied to rescue alerts after acknowledgement. Default 5 minutes.

    View tool JSON
    {
      "name": "get_rescue_ttl_ms",
      "kind": "answer",
      "impl": "imperative",
      "description": "Return the in-memory TTL (ms) applied to rescue alerts after acknowledgement. Default 5 minutes.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": [],
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    get_server_healthAnswer

    Return the current health snapshot: status (unknown | healthy | degraded | offline), lastCheckedAt, consecutiveFailures, apiBase.

    View tool JSON
    {
      "name": "get_server_health",
      "kind": "answer",
      "impl": "imperative",
      "description": "Return the current health snapshot: status (unknown | healthy | degraded | offline), lastCheckedAt, consecutiveFailures, apiBase.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "page": "/portami/"
    }
    get_api_baseAnswer

    Return the configured API base URL. Empty string means the app is using MSW mocks (dev mode, or testing enabled).

    View tool JSON
    {
      "name": "get_api_base",
      "kind": "answer",
      "impl": "imperative",
      "description": "Return the configured API base URL. Empty string means the app is using MSW mocks (dev mode, or testing enabled).",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "page": "/portami/"
    }