sipgate-mcp 0.3.1 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,142 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.1 - 2026-08-30
4
+
5
+ - List user numbers from sipgate's own user-number endpoint instead of matching
6
+ account numbers against device endpoints. Numbers that are assigned to a user
7
+ but routed nowhere carry an empty `endpointId`, so the endpoint match dropped
8
+ them and `list_numbers` came back empty on a real account.
9
+ - Name the denied endpoint in HTTP 403 errors. One denied endpoint no longer
10
+ reads as a blanket token or account problem when the rest of the API works.
11
+
12
+ ## 0.5.0 - 2026-08-30
13
+ - Add the final 32 tools for contacts, incoming blocklists, call/product
14
+ restrictions, history updates/deletes/CSV export, balance, portings,
15
+ account-wide sipgate.io settings, and webhook logs using the exact v2 paths,
16
+ verbs, query parameters, and request bodies.
17
+ - Permit account-wide contact, blacklist, balance, porting, sipgate.io, and
18
+ webhook-log reads in user scope. Require `confirm_account_wide: true` for
19
+ account-wide contact/blacklist writes, sipgate.io updates in user scope, and
20
+ every porting cancellation.
21
+ - Verify every single and bulk history mutation against owned history entries.
22
+ When user scope requests bulk deletion without IDs, enumerate both archived
23
+ and unarchived entries through owned connection IDs and send only those IDs;
24
+ never issue an unconstrained account-wide `DELETE /history`.
25
+ - Return `{before, after}` for all new mutations, including explicit
26
+ no-read-back/deletion notes. Mark contact CSV import, contact/history
27
+ deletion, and porting cancellation as destructive or irreversible.
28
+ - Add raw-text transport for contact/history CSV exports and explicit
29
+ 403/404-unavailable results for sipgate.io settings and webhook logs.
30
+ - Add 35 phoneline, voicemail/greeting, automated-recording, and faxline-
31
+ configuration tools covering every requested GET/POST/PUT/DELETE operation,
32
+ with exact v2 paths and payloads.
33
+ - Add phoneline detail, anonymous-call blocking, attached-device, and parallel-
34
+ forwarding reads/writes; enforce authenticated-user, owned-phoneline,
35
+ owned-device, and nested-forwarding boundaries.
36
+ - Add phoneline voicemail settings, greeting upload/activation/deletion,
37
+ transcription, global voicemail reads, and voicemail playback/recording call
38
+ sessions. Global results are filtered to voicemail IDs discovered under the
39
+ authenticated user's phonelines.
40
+ - Add automated call-recording announcement and per-extension settings. User
41
+ scope accepts settings only for an owned phoneline or faxline extension. The
42
+ account-global announcement has no user ownership link, so its read/create/
43
+ delete operations require administrator account scope.
44
+ - Add faxline creation, alias/deletion, caller-ID reads/writes, and tagline
45
+ updates with owned-faxline and owned-caller-number checks.
46
+ - Return explicit `phonelinesAvailable: false` / `changed: false` results for
47
+ phoneline-only tools when sipgate returns 403/404, without attempting a
48
+ mutation. An available but empty phoneline collection still denies access.
49
+ - Warn that voicemail call sessions and recording features may incur charges,
50
+ and that callers remain responsible for legally required recording consent.
51
+ - Expand read-only registration to 47 read tools and the full write-enabled
52
+ surface to 129 tools. Add one definition and backend endpoint test per new
53
+ tool plus foreign-resource and phoneline-less access-policy coverage.
54
+ - Add notification listing, creation, and deletion for call email/SMS, fax
55
+ email/SMS/report, incoming-SMS email, and voicemail email/SMS targets.
56
+ - Expose established calls and add hangup, hold, mute, recording, transfer,
57
+ DTMF, and announcement controls with before/after call snapshots.
58
+ - Add faxline and faxline-number reads plus chargeable fax send and resend
59
+ actions using sipgate's documented session payloads.
60
+ - Restrict user-scoped active calls to participants matching owned devices or
61
+ phone numbers, verify nested notification IDs before deletion, and verify
62
+ faxline ownership for reads, notifications, sends, and resends. Unknown or
63
+ unreadable ownership fails closed.
64
+ - Warn explicitly that fax transmission incurs charges and that call recording
65
+ can incur charges and requires participant consent in Germany.
66
+ - Keep a shared emergency address from leaking or rewriting other users' data:
67
+ user scope filters foreign numbers out of an address's number list and
68
+ refuses to edit an address that other users' numbers are attached to.
69
+ - Establish number ownership from the direct user-number endpoint as well as
70
+ routing, so quick dials that no phoneline or device routes can still be
71
+ updated and deleted by their owner.
72
+ - Page through every owned number when deciding ownership instead of stopping
73
+ after 1000.
74
+ - Redact PUK and ICCID values that arrive outside a credentials wrapper.
75
+ - Establish active-call ownership from the participant sipgate marks as the
76
+ call owner. Being the remote party of another user's call is not ownership,
77
+ and a call without a marked owner is denied.
78
+ - Verify that a resent fax belongs to the authenticated user, not just that the
79
+ faxline does.
80
+ - Accept national phone formats for transfer targets and fax recipients, which
81
+ the API documents as plain strings.
82
+ - Report the observed HTTP status when a phoneline or recording feature is
83
+ unavailable, so a denied token scope is no longer indistinguishable from an
84
+ account that simply has no phoneline layer.
85
+ - Say explicitly when a phoneline change was applied but only its read-back was
86
+ denied, instead of reporting the feature as unavailable.
87
+ - Accept an owned device as an automated-recording extension; sipgate documents
88
+ that feature for register endpoints, not only phonelines and faxlines.
89
+ - Refuse to delete an automated-recording greeting other than the one currently
90
+ configured.
91
+ - Refuse a history deletion whose entry list is present but empty. An empty
92
+ list serializes to no query parameter, which sipgate reads as "delete the
93
+ entire account history".
94
+ - Enforce the account-wide confirmation inside SipgateBackend as well, not only
95
+ at the access-control boundary, since the backend is exported on its own.
96
+ - Reject a bulk history update at sipgate's documented limit of 150 entries.
97
+ - Strip query strings from webhook log URLs, which carry their credentials
98
+ there as plain strings that key-based redaction cannot see.
99
+
100
+ - Add complete self-service tools for the requested sipgate v2 device surface:
101
+ device reads, updates and deletion; aliases; caller ID; local prefix; tariff
102
+ announcement; single-row display; external-device target/display settings;
103
+ password rotation; register/mobile/external device creation; and contingents.
104
+ - Add direct user-number reads plus quick-dial validation, creation, updates,
105
+ and deletion without routing these operations through phonelines.
106
+ - Add emergency-address listing, detail, number association, and updates for
107
+ assigning verified addresses to register devices.
108
+ - Enforce every new user-scoped resource target against owned devices, owned
109
+ numbers (including the device fallback on phoneline-less accounts), or
110
+ addresses associated with an owned device/number. Unknown ownership fails
111
+ closed with an access-policy error; administrator account scope retains its
112
+ broader behavior.
113
+ - Return `{before, after}` for all mutations, with explicit no-read-back notes
114
+ for creates and deletes. Redact credential containers and the one-time
115
+ password returned by device password rotation.
116
+ - Expand read-only mode from seven to 47 read tools; write tools are never
117
+ registered in read-only mode.
118
+ - Bump the package, CLI, and setup skill to version 0.5.0.
119
+
120
+ ## 0.4.0 - 2026-08-30
121
+
122
+ - Treat a 403/404 from the phoneline endpoints as "feature absent" instead of a
123
+ hard failure. Accounts without a phoneline layer keep their numbers directly
124
+ on a device, and a single failing phoneline lookup previously took down
125
+ `list_numbers`, `call_history`, `get_routing`, and `get_settings`.
126
+ - Resolve user numbers through the owning device when no phoneline layer
127
+ exists, and report the fallback via `source`, `phonelinesAvailable`, and
128
+ `numbersAvailable`.
129
+ - Scope user call history to device IDs when no phoneline IDs are available, so
130
+ history is no longer silently empty or denied.
131
+ - Accept an owned device as a routing destination in user scope. Numbers on
132
+ phoneline-less accounts point at a device, so the previous phoneline-only
133
+ check rejected every legitimate destination.
134
+ - Read every page of account numbers instead of a single 1000-number page, so
135
+ ownership checks and pagination stay correct on large accounts.
136
+ - Ask during interactive setup whether to register write tools instead of
137
+ silently defaulting to read-only. `--allow-writes` and the new `--read-only`
138
+ skip the question; a non-interactive run without either stays read-only.
139
+
3
140
  ## 0.3.1 - 2026-08-30
4
141
 
5
142
  - Fix Claude Code registration by using its unambiguous `mcp add-json` command
package/README.md CHANGED
@@ -43,13 +43,18 @@ sipgate-mcp setup
43
43
 
44
44
  The setup stores the PAT token ID and token in macOS Keychain without placing
45
45
  either value in shell history or an MCP configuration file. It registers every
46
- installed supported client (Codex and Claude Code) in user/read-only mode.
46
+ installed supported client (Codex and Claude Code) in user scope. An
47
+ interactive setup asks whether to enable write tools; a non-interactive setup
48
+ without a mode flag registers read-only.
47
49
  Those clients start and stop the stdio server automatically; `sipgate-mcp` does
48
50
  not run as a daemon and does not need to be started manually.
49
51
 
50
52
  Use `sipgate-mcp setup --client codex` or `--client claude` to configure only
51
- one client. Add `--allow-writes` only when agent-initiated account changes are
52
- deliberately wanted. `--dry-run` prints the secret-free registration commands
53
+ one client. `--allow-writes` and `--read-only` pick the mode without being
54
+ asked; write tools let the assistant place calls, send SMS/faxes, and configure
55
+ routing, devices, phonelines, voicemail, greetings, recordings, faxlines,
56
+ contacts, blocklists, call restrictions, history, portings, and sipgate.io.
57
+ `--dry-run` prints the secret-free registration commands
53
58
  without changing the Keychain or client configuration. Repeated setup runs
54
59
  reuse existing Keychain credentials; use `--replace-credentials` only to rotate
55
60
  the stored PAT-ID and PAT.
@@ -104,7 +109,7 @@ addition to sipgate's own user role and PAT scopes:
104
109
 
105
110
  | Value | Behavior |
106
111
  | --- | --- |
107
- | `user` (default) | Resolves the authenticated user through `/authorization/userinfo`; returns only that user and their assigned numbers; forces user-specific device, routing, and settings reads; constrains call history to owned connection IDs; and validates every write target against owned numbers, phonelines, or devices. |
112
+ | `user` (default) | Resolves the authenticated user through `/authorization/userinfo`; returns only that user and their assigned numbers, notifications, faxlines, phonelines, voicemails, greetings, and attached devices; forces user-specific device, routing, restriction, and settings reads; constrains history reads, exports, and mutations to owned connections/entries; and validates every write target against owned numbers, phonelines, nested voicemail/forwarding/greeting resources, devices, faxlines, notifications, or emergency addresses associated with an owned device/number. Account-wide contact, blacklist, porting-cancellation, and sipgate.io writes require `confirm_account_wide: true`; their reads are allowed and clearly labelled account-wide. |
108
113
  | `account` | Enables account-wide reads and writes. Startup fails unless `/users/{authenticatedUserId}` reports `admin: true`. Requires `users:read` for the administrator check. |
109
114
 
110
115
  Token scopes are permission ceilings, not role elevation. For example,
@@ -131,32 +136,165 @@ listed specific and parent scopes offered by the PAT UI when in doubt.
131
136
  | --- | --- | --- | --- |
132
137
  | `account_info` | Read | User: cached `/authorization/userinfo`; account: plus `GET /account` | Account: `account:read` (`userinfo` has no scope declaration in Swagger) |
133
138
  | `list_users` | Read | User: `GET /users/{self}`; account: `GET /users` | `users:read` |
134
- | `list_numbers` | Read | User: `GET /{self}/phonelines` and each phoneline's `/numbers`; account: `GET /numbers` | User: `phonelines:read`, `phonelines:numbers:read`; account: `numbers:read` |
139
+ | `list_numbers` | Read | User: own phonelines, or owned devices plus paginated `GET /numbers` when phonelines are unavailable; account: `GET /numbers` | User: `phonelines:read`, `phonelines:numbers:read`; fallback: `devices:read`, `numbers:read`; account: `numbers:read` |
135
140
  | `list_devices` | Read | User: `GET /{self}/devices`; account: `GET /users`, `GET /{userId}/devices` | `devices:read`; account also needs `users:read` when `user_id` is omitted |
141
+ | `get_device` | Read | Ownership `GET /{self}/devices`, then `GET /devices/{deviceId}` | `devices:read` |
142
+ | `get_device_caller_id` | Read | Device ownership read, then `GET /devices/{deviceId}/callerid` | `devices:read`, `devices:callerid:read` |
143
+ | `get_device_local_prefix` | Read | Device ownership read, then `GET /devices/{deviceId}/localprefix` | `devices:read`, `devices:localprefix:read` |
144
+ | `get_device_tariff_announcement` | Read | Device ownership read, then `GET /devices/{deviceId}/tariffannouncement` | `devices:read`, `devices:tariffannouncement:read` |
145
+ | `get_device_single_row_display` | Read | Device ownership read, then `GET /devices/{deviceId}/singlerowdisplay` | `devices:read`, `devices:singlerowdisplay:read` |
146
+ | `get_device_contingents` | Read | Device/user ownership reads, then `GET /{userId}/devices/{deviceId}/contingents` | `devices:read` |
147
+ | `list_user_numbers` | Read | `GET /{userId}/numbers`; this direct endpoint never uses phonelines | `numbers:read` |
148
+ | `validate_quick_dial` | Read | `GET /numbers/quickdial/validation/{quickDialNumber}` | `numbers:read` |
149
+ | `list_addresses` | Read | `GET /addresses`; user scope filters through owned device/number relationships | `addresses:read`; user ownership also needs `devices:read`, `numbers:read` and the applicable owned-number read scopes |
150
+ | `get_address` | Read | Address ownership reads, then `GET /addresses/{addressId}` | `addresses:read`; user ownership also needs `devices:read`, `numbers:read` and the applicable owned-number read scopes |
151
+ | `list_address_numbers` | Read | Address ownership reads, then `GET /addresses/{addressId}/numbers` | `numbers:read`, plus user ownership read scopes |
136
152
  | `get_routing` | Read | User: own phonelines, numbers, and forwardings; account: also `GET /numbers` and `GET /users` | `phonelines:read`, `phonelines:numbers:read`, `phonelines:forwardings:read`; account also needs `numbers:read` and, when `user_id` is omitted, `users:read` |
137
153
  | `call_history` | Read | User: ownership reads for own phonelines/devices, then filtered `GET /history`; account: `GET /history` | `history:read`; user also needs `phonelines:read`, `devices:read` |
154
+ | `list_calls` | Read | `GET /calls`; user scope filters calls to participants matching an owned device ID or phone number | `rtcm:read`; user ownership also needs `devices:read`, `numbers:read` and applicable owned-number scopes |
155
+ | `list_notifications` | Read | `GET /{userId}/notifications` | `notifications:read` |
156
+ | `list_faxlines` | Read | `GET /{userId}/faxlines` | `faxlines:read` |
157
+ | `list_faxline_numbers` | Read | User: faxline ownership read, then `GET /{userId}/faxlines/{faxlineId}/numbers`; account: direct `GET` | `faxlines:read`, `faxlines:numbers:read` |
158
+ | `get_phoneline` | Read | Owned-phoneline lookup, then `GET /{userId}/phonelines/{phonelineId}` | `phonelines:read` |
159
+ | `get_phoneline_block_anonymous` | Read | Owned-phoneline lookup, then `GET /{userId}/phonelines/{phonelineId}/blockanonymous` | `phonelines:read`, `phonelines:blockanonymous:read` |
160
+ | `list_phoneline_devices` | Read | Owned-phoneline/device filtering, then `GET /{userId}/phonelines/{phonelineId}/devices` | `phonelines:read`, `phonelines:devices:read`; user filtering also needs `devices:read` |
161
+ | `list_parallel_forwardings` | Read | Owned-phoneline lookup, then `GET /{userId}/phonelines/{phonelineId}/parallelforwardings` | `phonelines:read`, `phonelines:parallelforwardings:read` |
162
+ | `list_phoneline_voicemails` | Read | Owned-phoneline lookup, then `GET /{userId}/phonelines/{phonelineId}/voicemails` | `phonelines:read`, `phonelines:voicemails:read` |
163
+ | `list_voicemail_greetings` | Read | Owned phoneline/voicemail lookup, then `GET /{userId}/phonelines/{phonelineId}/voicemails/{voicemailId}/greetings` | `phonelines:read`, `phonelines:voicemails:read`, `phonelines:voicemails:greetings:read` |
164
+ | `list_voicemails` | Read | `GET /voicemails`; user scope filters by voicemail IDs discovered under owned phonelines | `voicemails:read`; user filtering also needs `phonelines:read`, `phonelines:voicemails:read` |
165
+ | `get_voicemail` | Read | Owned-voicemail lookup, then `GET /voicemails/{voicemailId}` | `voicemails:read`; user ownership also needs `phonelines:read`, `phonelines:voicemails:read` |
166
+ | `list_autorecording_greetings` | Read | Account scope only: `GET /autorecordings/greetings`; the account-global resource has no user ownership link | `autorecording:greeting:read`; sipgate also requires administrator privileges and activated call recording |
167
+ | `get_autorecording_settings` | Read | Owned phoneline/faxline extension lookup, then `GET /autorecordings/{extension}/settings` | `devices:read`; ownership also needs `phonelines:read`, `faxlines:read` |
168
+ | `get_faxline_caller_id` | Read | Owned-faxline lookup, then `GET /{userId}/faxlines/{faxlineId}/callerid` | `faxlines:read` |
169
+ | `create_phoneline` | Write/action | `POST /{userId}/phonelines`; 403/404 becomes a clean unavailable result | `phonelines:write` |
170
+ | `update_phoneline_alias` | Write | Owned-phoneline before/after reads and `PUT /{userId}/phonelines/{phonelineId}` | `phonelines:read`, `phonelines:write` |
171
+ | `delete_phoneline` | Write | Owned-phoneline before-state read and `DELETE /{userId}/phonelines/{phonelineId}` | `phonelines:read`, `phonelines:write` |
172
+ | `set_phoneline_block_anonymous` | Write | Owned-phoneline setting reads and `PUT /{userId}/phonelines/{phonelineId}/blockanonymous` | `phonelines:read`, `phonelines:blockanonymous:read`, `phonelines:blockanonymous:write` |
173
+ | `attach_device_to_phoneline` | Write/action | Owned phoneline/device reads, pre/post assignment reads, and `POST /{userId}/phonelines/{phonelineId}/devices` | `phonelines:read`, `phonelines:devices:read`, `phonelines:devices:write`, `devices:read` |
174
+ | `detach_device_from_phoneline` | Write | Owned phoneline/device reads, pre/post assignment reads, and `DELETE /{userId}/phonelines/{phonelineId}/devices/{deviceId}` | `phonelines:read`, `phonelines:devices:read`, `phonelines:devices:write`, `devices:read` |
175
+ | `create_parallel_forwarding` | Write/action | Owned-phoneline check, pre/post forwarding reads, and `POST /{userId}/phonelines/{phonelineId}/parallelforwardings` | `phonelines:read`, `phonelines:write`, `phonelines:parallelforwardings:read`, `phonelines:parallelforwardings:write` |
176
+ | `update_parallel_forwarding` | Write | Verify forwarding in the owned phoneline, pre/post reads, and `PUT /{userId}/phonelines/{phonelineId}/parallelforwardings/{parallelForwardingId}` | `phonelines:read`, `phonelines:write`, `phonelines:parallelforwardings:read`, `phonelines:parallelforwardings:write` |
177
+ | `delete_parallel_forwarding` | Write | Verify forwarding in the owned phoneline, pre/post reads, and `DELETE /{userId}/phonelines/{phonelineId}/parallelforwardings/{parallelForwardingId}` | `phonelines:read`, `phonelines:write`, `phonelines:parallelforwardings:read`, `phonelines:parallelforwardings:write` |
178
+ | `update_voicemail` | Write | Verify voicemail in the owned phoneline, pre/post voicemail reads, and `PUT /{userId}/phonelines/{phonelineId}/voicemails/{voicemailId}` | `phonelines:read`, `phonelines:write`, `phonelines:voicemails:read`, `phonelines:voicemails:write` |
179
+ | `create_voicemail_greeting` | Write/action | Verify owned voicemail, pre/post greeting reads, and `POST /{userId}/phonelines/{phonelineId}/voicemails/{voicemailId}/greetings` | `phonelines:read`, `phonelines:write`, `phonelines:voicemails:read`, `phonelines:voicemails:write`, `phonelines:voicemails:greetings:read`, `phonelines:voicemails:greetings:write` |
180
+ | `update_voicemail_greeting` | Write | Verify greeting under the owned voicemail, pre/post reads, and `PUT /{userId}/phonelines/{phonelineId}/voicemails/{voicemailId}/greetings/{greetingId}` | Same phoneline/voicemail/greeting read/write scopes as greeting creation |
181
+ | `delete_voicemail_greeting` | Write | Verify greeting under the owned voicemail, pre/post reads, and `DELETE /{userId}/phonelines/{phonelineId}/voicemails/{voicemailId}/greetings/{greetingId}` | Same phoneline/voicemail/greeting read/write scopes as greeting creation |
182
+ | `set_voicemail_transcription` | Write | Verify owned voicemail, pre/post voicemail reads, and `PUT /{userId}/phonelines/{phonelineId}/voicemails/{voicemailId}/transcriptions` | `phonelines:read`, `phonelines:write`, `phonelines:voicemails:read`, `phonelines:voicemails:write` |
183
+ | `play_voicemail` | Write/action | User: verify owned device and history/data entry; then `POST /sessions/voicemail/play` | `sessions:write`, `sessions:calls:write`; user ownership also needs `devices:read`, `history:read` and owned-connection scopes |
184
+ | `record_voicemail_greeting` | Write/action | User: verify owned device and target voicemail; then `POST /sessions/voicemail/recording` | `sessions:write`, `sessions:calls:write`; user ownership also needs `devices:read`, `phonelines:read`, `phonelines:voicemails:read` |
185
+ | `create_autorecording_greeting` | Write/action | Account scope only: pre/post `GET /autorecordings/greetings`, `POST /autorecordings/greetings` | `autorecording:greeting:read`, `autorecording:greeting:write`; sipgate requires administrator privileges and activated call recording |
186
+ | `delete_autorecording_greeting` | Write | Account scope only: before-state read, then `DELETE /autorecordings/greetings/{greetingId}` | `autorecording:greeting:read`, `autorecording:greeting:write`; sipgate requires administrator privileges and activated call recording |
187
+ | `set_autorecording_settings` | Write | Owned phoneline/faxline extension lookup, pre/post setting reads, and `PUT /autorecordings/{extension}/settings` | `devices:read`; ownership also needs `phonelines:read`, `faxlines:read` |
188
+ | `create_faxline` | Write/action | `POST /{userId}/faxlines` | `faxlines:write` |
189
+ | `update_faxline_alias` | Write | Owned-faxline pre/post list reads and `PUT /{userId}/faxlines/{faxlineId}` | `faxlines:read`, `faxlines:write` |
190
+ | `delete_faxline` | Write | Owned-faxline before-state read and `DELETE /{userId}/faxlines/{faxlineId}` | `faxlines:read`, `faxlines:write` |
191
+ | `set_faxline_caller_id` | Write | Owned faxline/number checks, pre/post caller-ID reads, and `PUT /{userId}/faxlines/{faxlineId}/callerid` | `faxlines:read`, `faxlines:write`, plus owned-number read scopes |
192
+ | `set_faxline_tagline` | Write | Owned-faxline pre/post list reads and `PUT /{userId}/faxlines/{faxlineId}/tagline` | `faxlines:read`, `faxlines:write` |
138
193
  | `get_settings` | Read | `GET /users[/userId]`, `GET /{userId}/devices`, `GET /{userId}/phonelines[/phonelineId]` | `users:read`, `devices:read`, `phonelines:read` |
194
+ | `list_contacts` | Read, account-wide | `GET /contacts` with phone, scope, and pagination filters | `contacts:read` |
195
+ | `get_contact` | Read, account-wide | `GET /contacts/{contactId}` | `contacts:read` |
196
+ | `list_internal_contacts` | Read, account-wide | Deprecated `GET /contacts/internal` compatibility route | `contacts:read` |
197
+ | `export_contacts_csv` | Read, account-wide | `GET /contacts/csv` and return CSV text | `contacts:read` |
198
+ | `get_contacts_vcard` | Read, account-wide | `GET /contacts/vcard` with structured-vCard filters | `contacts:read` |
199
+ | `create_contact` | Write/action, account-wide | `POST /contacts`; user scope requires `confirm_account_wide: true` | `contacts:write` |
200
+ | `update_contact` | Write, account-wide | Before/after `GET /contacts/{contactId}`, then `PUT` on the same path; confirmation required in user scope | `contacts:read`, `contacts:write` |
201
+ | `delete_contact` | Destructive write, account-wide | Before-state `GET`, then `DELETE /contacts/{contactid}`; confirmation required in user scope | `contacts:read`, `contacts:write` |
202
+ | `delete_contacts` | Destructive write, account-wide | Before-state contact reads, then `DELETE /contacts`; omitted filters delete all; confirmation required in user scope | `contacts:read`, `contacts:write` |
203
+ | `import_contacts_csv` | Destructive write/action, account-wide | Pre/post `GET /contacts`, then `POST /contacts/import/csv`; confirmation required in user scope | `contacts:read`, `contacts:write` |
204
+ | `put_contacts_vcard` | Write, account-wide | Pre/post `GET /contacts/vcard`, then `PUT /contacts/vcard`; supplied IDs are overwritten; confirmation required in user scope | `contacts:read`, `contacts:write` |
205
+ | `list_incoming_blacklist` | Read, account-wide | `GET /blacklist/incoming` | `blacklist:read` |
206
+ | `add_incoming_blacklist` | Write/action, account-wide | Pre/post blacklist reads, then `POST /blacklist/incoming`; confirmation required in user scope | `blacklist:read`, `blacklist:write` |
207
+ | `remove_incoming_blacklist` | Write, account-wide | Before-state blacklist read, then `DELETE /blacklist/incoming/{phoneNumber}`; confirmation required in user scope | `blacklist:read`, `blacklist:write` |
208
+ | `list_call_restrictions` | Read | User scope forces the authenticated ID in `GET /callrestrictions`; account scope accepts selected IDs | `callrestrictions:read` |
209
+ | `set_call_restriction` | Write | Pre/post restriction reads, then `POST /{authenticatedUserId}/callrestrictions/{restriction}` | `callrestrictions:read`, `callrestrictions:write` |
210
+ | `list_restrictions` | Read | `GET /restrictions`; user scope accepts only the authenticated user ID | Swagger declares the internal scope |
211
+ | `export_history` | Read | User: owned-connection-filtered `GET /history/export`; account: filtered or account-wide export | `history:read`; user ownership also needs `phonelines:read`, `devices:read` |
212
+ | `set_history_read` | Write | Owned-entry check, pre/post `GET /history/{entryId}`, then `PUT /history/{entryId}/read` | `history:read`, `history:write`; user ownership also needs connection read scopes |
213
+ | `set_history_note` | Write | Owned-entry check, pre/post entry reads, then `PUT /history/{entryId}/note` | `history:read`, `history:write`; user ownership also needs connection read scopes |
214
+ | `set_history_archive` | Write | Owned-entry check, pre/post entry reads, then `PUT /history/{entryId}/archive` | `history:read`, `history:write`; user ownership also needs connection read scopes |
215
+ | `update_history_entry` | Write | Owned-entry check, pre/post entry reads, then `PUT /history/{entryId}` | `history:read`, `history:write`; user ownership also needs connection read scopes |
216
+ | `delete_history_entry` | Destructive write | Owned-entry and before-state reads, then `DELETE /history/{entryId}` | `history:read`, `history:write`; user ownership also needs connection read scopes |
217
+ | `update_history_entries` | Write | Verify every entry, read before/after state, then `PUT /history` with fewer than 150 entries | `history:read`, `history:write`; user ownership also needs connection read scopes |
218
+ | `delete_history_entries` | Destructive write | `DELETE /history`; user scope expands omission to IDs enumerated through owned connection filters and never sends an unconstrained delete | `history:read`, `history:write`; user ownership also needs `phonelines:read`, `devices:read` |
219
+ | `get_balance` | Read, account-wide | `GET /balance` | `balance:read` |
220
+ | `list_portings` | Read, account-wide | `GET /portings` | `portings:read` |
221
+ | `get_porting` | Read, account-wide | `GET /portings/{portingId}` | `portings:read` |
222
+ | `cancel_porting` | Destructive write, account-wide | Before-state `GET`, then `DELETE /portings/{portingId}`; always requires `confirm_account_wide: true` | `portings:read`, `portings:write` |
223
+ | `get_sipgateio_settings` | Read, account-wide | `GET /settings/sipgateio`; 403/404 returns an unavailable result | `settings:read`, `settings:sipgateio:read` |
224
+ | `update_sipgateio_settings` | Write, account-wide | Pre/post settings reads, then `PUT /settings/sipgateio`; confirmation required in user scope | `settings:read`, `settings:write`, `settings:sipgateio:read`, `settings:sipgateio:write` |
225
+ | `list_webhook_logs` | Read, account-wide | `GET /log/webhooks`; 403/404 returns an unavailable result | `log:webhooks:read` |
139
226
  | `set_number_routing` | Write | User: pre/post reads through own phonelines; account: pre/post `GET /numbers`; all modes: `PUT /numbers/{numberId}` | `numbers:write`; user also needs `phonelines:read`, `phonelines:numbers:read`; account needs `numbers:read` |
140
227
  | `set_forwarding` | Write | User: phoneline ownership read; then pre/post forwarding reads and `PUT` | `phonelines:read`, `phonelines:write`, `phonelines:forwardings:read`, `phonelines:forwardings:write` |
141
228
  | `set_dnd` | Write | User: device ownership read; then pre/post `GET /devices/{deviceId}` and `PUT` | `devices:read`, `devices:write` |
229
+ | `update_device` | Write | Device and optional emergency-address ownership reads; pre/post `GET` plus `PUT /devices/{deviceId}` | `devices:read`, `devices:write`; address ownership may also need `numbers:read` and owned-number read scopes |
230
+ | `delete_device` | Write | Device ownership and before-state reads, then `DELETE /devices/{deviceId}` | `devices:read`, `devices:write` |
231
+ | `set_device_alias` | Write | Device ownership read; pre/post device reads and `PUT /devices/{deviceId}/alias` | `devices:read`, `devices:write` |
232
+ | `set_device_caller_id` | Write | Device and caller-number ownership reads; pre/post caller-ID reads and `PUT /devices/{deviceId}/callerid` | `devices:read`, `devices:write`, `devices:callerid:read`, `devices:callerid:write`, plus owned-number read scopes |
233
+ | `set_device_local_prefix` | Write | Device ownership read; pre/post setting reads and `PUT /devices/{deviceId}/localprefix` | `devices:read`, `devices:write`, `devices:localprefix:read`, `devices:localprefix:write` |
234
+ | `set_device_tariff_announcement` | Write | Device ownership read; pre/post setting reads and `PUT /devices/{deviceId}/tariffannouncement` | `devices:read`, `devices:write`, `devices:tariffannouncement:read`, `devices:tariffannouncement:write` |
235
+ | `set_device_single_row_display` | Write | Device ownership read; pre/post setting reads and `PUT /devices/{deviceId}/singlerowdisplay` | `devices:read`, `devices:write`, `devices:singlerowdisplay:read`, `devices:singlerowdisplay:write` |
236
+ | `set_external_device_target_number` | Write | Device ownership read; pre/post device reads and `PUT /devices/{deviceId}/external/targetnumber` | `devices:read`, `devices:write` |
237
+ | `set_external_device_incoming_call_display` | Write | Device ownership read; pre/post device reads and `PUT /devices/{deviceId}/external/incomingcalldisplay` | `devices:read`, `devices:write` |
238
+ | `change_device_password` | Write/action | Device ownership/before-state reads, then `POST /devices/{deviceId}/credentials/password`; the response is redacted | `devices:read`, `devices:write` |
239
+ | `create_register_device` | Write/action | `POST /{userId}/devices/register` | `devices:write` |
240
+ | `create_mobile_device` | Write/action | `POST /{userId}/devices/mobile` | `devices:write` |
241
+ | `create_external_device` | Write/action | `POST /{userId}/devices/external` | `devices:write` |
242
+ | `create_quick_dial` | Write/action | `POST /numbers/quickdial` | `numbers:write` |
243
+ | `update_quick_dial` | Write | Owned-number before/after reads and `PUT /numbers/quickdial/{quickdialId}` | `numbers:read`, `numbers:write`, plus applicable owned-number read scopes |
244
+ | `delete_quick_dial` | Write | Owned-number before-state read and `DELETE /numbers/quickdial/{numberId}` | `numbers:read`, `numbers:write`, plus applicable owned-number read scopes |
245
+ | `update_address` | Write | Address ownership and pre/post address reads, then `PUT /addresses/{addressId}` | `addresses:read`, `addresses:write`, plus user ownership read scopes |
142
246
  | `send_sms` | Write/action | `GET /{userId}/sms`, pre/post `GET /history`, `POST /sessions/sms` | `sms:read`, `history:read`, `sessions:write`, `sessions:sms:write` |
143
247
  | `initiate_call` | Write/action | User: device/number ownership reads, then `POST /sessions/calls`; account: pre/post `GET /calls` plus `POST` | `sessions:write`, `sessions:calls:write`; user also needs `devices:read`, `phonelines:read`, `phonelines:numbers:read`; account needs `rtcm:read` |
144
-
145
- Every write tool reads current state first and returns a JSON object with `before` and `after`. SMS history can update asynchronously, and `/calls` only contains established calls, so those action snapshots also include an acceptance/session marker.
248
+ | `create_call_email_notification` | Write/action | User: endpoint ownership reads; all modes: pre/post `GET /{userId}/notifications`, `POST /{userId}/notifications/call/email` | `notifications:read`, `notifications:write`; user also needs `devices:read` or `phonelines:read` |
249
+ | `create_call_sms_notification` | Write/action | User: endpoint ownership reads; all modes: pre/post notification reads, `POST /{userId}/notifications/call/sms` | `notifications:read`, `notifications:write`; user also needs `devices:read` or `phonelines:read` |
250
+ | `create_fax_email_notification` | Write/action | User: faxline ownership read; all modes: pre/post notification reads, `POST /{userId}/notifications/fax/email` | `notifications:read`, `notifications:write`; user also needs `faxlines:read` |
251
+ | `create_fax_sms_notification` | Write/action | User: faxline ownership read; all modes: pre/post notification reads, `POST /{userId}/notifications/fax/sms` | `notifications:read`, `notifications:write`; user also needs `faxlines:read` |
252
+ | `create_fax_report_notification` | Write/action | User: faxline ownership read; all modes: pre/post notification reads, `POST /{userId}/notifications/fax/report` | `notifications:read`, `notifications:write`; user also needs `faxlines:read` |
253
+ | `create_sms_email_notification` | Write/action | Pre/post notification reads, `POST /{userId}/notifications/sms/email` | `notifications:read`, `notifications:write` |
254
+ | `create_voicemail_email_notification` | Write/action | Pre/post notification reads, `POST /{userId}/notifications/voicemail/email` | `notifications:read`, `notifications:write` |
255
+ | `create_voicemail_sms_notification` | Write/action | Pre/post notification reads, `POST /{userId}/notifications/voicemail/sms` | `notifications:read`, `notifications:write` |
256
+ | `delete_notification` | Write | User: verify the nested ID in `GET /{userId}/notifications`; all modes: before/after notification reads and `DELETE /{userId}/notifications/{notificationId}` | `notifications:read`, `notifications:write` |
257
+ | `hangup_call` | Write | User: participant ownership read; all modes: before/after `GET /calls`, `DELETE /calls/{callId}` | `rtcm:read`, `rtcm:write`; user also needs owned-device/number read scopes |
258
+ | `set_call_hold` | Write | User: participant ownership read; before/after `GET /calls`, `PUT /calls/{callId}/hold` | `rtcm:read`, `rtcm:write`; user also needs owned-device/number read scopes |
259
+ | `set_call_muted` | Write | User: participant ownership read; before/after `GET /calls`, `PUT /calls/{callId}/muted` | `rtcm:read`, `rtcm:write`; user also needs owned-device/number read scopes |
260
+ | `set_call_recording` | Write | User: participant ownership read; before/after `GET /calls`, `PUT /calls/{callId}/recording` | `rtcm:read`, `rtcm:write`; user also needs owned-device/number read scopes |
261
+ | `transfer_call` | Write/action | User: call-participant and optional caller-ID ownership reads; before/after `GET /calls`, `POST /calls/{callId}/transfer` | `rtcm:read`, `rtcm:write`; user also needs owned-device/number read scopes |
262
+ | `send_call_dtmf` | Write/action | User: participant ownership read; before/after `GET /calls`, `POST /calls/{callId}/dtmf` | `rtcm:read`, `rtcm:write`; user also needs owned-device/number read scopes |
263
+ | `start_call_announcement` | Write/action | User: participant ownership read; before/after `GET /calls`, `POST /calls/{callId}/announcements` | `rtcm:read`, `rtcm:write`; user also needs owned-device/number read scopes |
264
+ | `send_fax` | Write/action | User: faxline ownership read; `POST /sessions/fax` | `sessions:write`, `sessions:fax:write`; user also needs `faxlines:read` |
265
+ | `resend_fax` | Write/action | User: required faxline ownership read; `POST /sessions/fax/resend` | `sessions:write`, `sessions:fax:write`; user also needs `faxlines:read` |
266
+
267
+ Every write tool returns a JSON object with `before` and `after`. Where a resource can be read, the tool reads current state first and reads it back after the change. Fax send/resend, voicemail playback/recording, and contact creation use `before: null` and return an explicit no-read-back note where sipgate exposes no synchronous identity/state; deletes return the previous state and a deletion marker. SMS history can update asynchronously, and `/calls` only contains established calls.
146
268
 
147
269
  ### Tool notes
148
270
 
149
271
  - `list_devices` resolves devices through users because the documented account-wide route is `GET /{userId}/devices`; the live v2 Swagger document does not define `GET /devices`.
150
- - User scope resolves assigned numbers through the authenticated user's phonelines and never calls account-wide `GET /users` or `GET /numbers` for read tools.
272
+ - `list_user_numbers` calls the documented direct `GET /{userId}/numbers` endpoint and never uses phonelines. Ownership checks retain the device-based fallback required by accounts without a phoneline layer.
273
+ - Every phoneline-dependent tool treats sipgate HTTP 403/404 as feature absence. On accounts where numbers hang directly from a device, reads return `phonelinesAvailable: false` and writes return `changed: false` without attempting the mutation. An available but empty phoneline list still denies every supplied phoneline ID.
274
+ - User scope establishes nested ownership from the documented collections: parallel forwardings under an owned phoneline, voicemails under an owned phoneline, greetings under an owned voicemail, and attached devices that are independently owned. Global `/voicemails` results are filtered to those discovered IDs.
275
+ - Voicemail playback requires an owned device and an owned history/data entry in user scope. The live Swagger request field is spelled `datadId`; the MCP exposes the clearer `data_id` and maps it without changing the API payload. Voicemail greeting recording requires an owned device and target voicemail in user scope.
276
+ - Automated recording settings accept only an extension found in the authenticated user's phonelines or faxlines. The automated-recording greeting is account-global and has no user ownership relationship, so its read/create/delete tools fail closed in user scope and require administrator account scope. sipgate additionally requires activated call recording.
277
+ - User scope never calls account-wide `GET /users`. It calls paginated account `GET /numbers` only for the device-based ownership fallback when phonelines are unavailable.
151
278
  - User-scoped number-routing snapshots are also resolved through owned phonelines, and user-scoped Click2Dial deliberately omits account-wide `/calls` snapshots.
279
+ - User-scoped `list_calls` and every live-call mutation read the account-wide `/calls` feed but expose or operate on a call only when at least one participant's `participantId` matches an owned device or `phoneNumber` matches an owned phone number. A missing, unknown, or unreadable match fails closed. sipgate's Swagger does not expose a separate call-owner user or device field.
280
+ - Notification IDs live inside the nested email/SMS/report target arrays returned by `GET /{userId}/notifications`; deletion verifies that nested ID before sending the request. Call-notification endpoints are checked against owned devices/phonelines, and fax notifications against owned faxlines.
281
+ - Fax send and resend actions incur charges. In user scope `resend_fax` requires `faxline_id` even though sipgate marks it optional, because omitting it leaves no documented ownership relationship that can be verified before the chargeable action.
282
+ - Contacts and the incoming blacklist are account-wide sipgate resources. Their reads remain available in user scope, but every write requires `confirm_account_wide: true`; CSV import and contact/history deletion are described as destructive. Porting cancellation always requires the same explicit confirmation and is irreversible through v2.
283
+ - Every single-entry history mutation verifies `connectionIds` against the authenticated user's owned device/phoneline IDs. User-scoped bulk updates verify every entry. An omitted ID list on bulk deletion is expanded by paging both archived and unarchived history through owned connection filters, then deleting only those IDs; an unconstrained `DELETE /history` is never sent in user scope.
284
+ - `set_call_restriction` never accepts a user ID: the backend resolves `/authorization/userinfo` and posts only to `/{authenticatedUserId}/callrestrictions/{restriction}`. `list_call_restrictions` and `list_restrictions` reject foreign users in user scope.
285
+ - Balance, portings, global sipgate.io settings, and webhook logs are account-wide reads that remain visible in user scope. Updating global sipgate.io settings requires account-wide confirmation in user scope. sipgate.io settings/log endpoints translate 403/404 into explicit unavailable results.
286
+ - Call and automated recording can incur charges and are legally sensitive. In Germany the caller is responsible for obtaining consent from every participant; changing or disabling an announcement does not remove that responsibility. Voicemail playback/recording initiates a call and may also incur charges.
287
+ - Address IDs are exposed as integers because sipgate declares every address path parameter as `int32`. In user scope an address is visible or mutable only when an owned device references it, an owned number contains its `addressId`, or `/addresses/{addressId}/numbers` contains an owned number.
288
+ - Device creation can affect billing, and changing an address can deactivate associated telephone numbers depending on country. Every write-tool description advertises the account change and potential charges.
289
+ - Device password rotation intentionally redacts the complete credential container, including sipgate's one-time password response.
152
290
  - Number routing uses sipgate's documented `endpointId`. Obtain existing IDs from the read tools; a phoneline ID such as `p0` is the documented example.
153
291
  - `set_forwarding` replaces the complete phoneline forwarding list. Pass `forwardings: []` to remove all forwardings. A `timeout` of `0` represents immediate forwarding.
154
292
  - `send_sms` refuses to post unless `GET /{userId}/sms` returns the requested (or first available) SMS extension.
155
- - sipgate documents `POST /sessions/calls` as the classic-PBX Click2Dial route. The API documentation points Neo PBX accounts to `/calls`; supporting that distinct call workflow is left for a future compatibility pass.
293
+ - sipgate documents `POST /sessions/calls` as the classic-PBX Click2Dial route. Live established-call reads and controls use `/calls`; starting a new Neo PBX call through the separate `POST /calls` shape is outside this batch.
156
294
 
157
295
  ## Read-only mode
158
296
 
159
- Set `SIPGATE_MCP_READONLY=1` to register only the seven read tools. Write tools are absent from `tools/list`, rather than merely failing when called.
297
+ Set `SIPGATE_MCP_READONLY=1` to register only the 47 read tools. Write tools are absent from `tools/list`, rather than merely failing when called.
160
298
 
161
299
  ```bash
162
300
  export SIPGATE_MCP_READONLY=1
@@ -263,7 +401,11 @@ MCP stdio server
263
401
  - `sipgate-mcp setup` delegates secret entry directly to the macOS Keychain
264
402
  prompt. Secret values are never passed as command-line arguments and are not
265
403
  written to Codex or Claude configuration.
266
- - User scope is the default and validates user IDs plus number, phoneline, device, call, and history ownership before delegation.
404
+ - User scope is the default and validates user IDs plus number, phoneline,
405
+ nested voicemail/greeting/forwarding, device, faxline, call, recording-
406
+ extension, and history ownership before delegation. Bulk history deletion is
407
+ expanded to owned entry IDs, and account-wide writes require explicit
408
+ confirmation where documented above.
267
409
  - Account scope fails startup unless the authenticated sipgate user reports `admin: true`.
268
410
  - The Basic Auth header exists only in memory and is sent only to the fixed sipgate API base URL.
269
411
  - API error bodies are discarded. User-facing errors never include request headers, response bodies, or credentials.
@@ -295,7 +437,7 @@ Maintainer setup and the one-time first-publish procedure are documented in
295
437
 
296
438
  ## API provenance and limitations
297
439
 
298
- The endpoint paths, query parameters, request bodies, response models, and scope names were checked against sipgate's live public [REST API v2 Swagger document](https://api.sipgate.com/v2/swagger.json) and [Swagger UI](https://api.sipgate.com/v2/doc) on 2026-08-29. PAT Basic Auth was checked against sipgate's public authentication guide. No authenticated production account was available during development, so real-account behavior remains to be confirmed with the smoke test above—especially product-specific availability, eventual history updates, and classic versus Neo PBX calling.
440
+ The endpoint paths, query parameters, request bodies, response models, and scope names were checked against sipgate's live public [REST API v2 Swagger document](https://api.sipgate.com/v2/swagger.json) and [Swagger UI](https://api.sipgate.com/v2/doc) on 2026-08-30. PAT Basic Auth was checked against sipgate's public authentication guide. No authenticated production account was available during development, so real-account behavior remains to be confirmed with the smoke test above—especially product-specific availability, eventual history updates, and classic versus Neo PBX calling.
299
441
 
300
442
  ## Roadmap
301
443
 
package/SKILL.md CHANGED
@@ -2,7 +2,7 @@
2
2
  name: sipgate-mcp
3
3
  description: Install and securely configure the sipgate MCP server when a user asks to set up or connect a sipgate account to Codex or Claude. Do not use for ordinary sipgate product questions.
4
4
  metadata:
5
- version: "0.3.1"
5
+ version: "0.5.1"
6
6
  ---
7
7
 
8
8
  # Set up sipgate MCP
@@ -10,19 +10,19 @@ metadata:
10
10
  Install the matching CLI version with one available package manager:
11
11
 
12
12
  ```bash
13
- vp install -g sipgate-mcp@0.3.1
13
+ vp install -g sipgate-mcp@0.5.1
14
14
  ```
15
15
 
16
16
  ```bash
17
- npm install -g sipgate-mcp@0.3.1
17
+ npm install -g sipgate-mcp@0.5.1
18
18
  ```
19
19
 
20
20
  ```bash
21
- pnpm add -g sipgate-mcp@0.3.1
21
+ pnpm add -g sipgate-mcp@0.5.1
22
22
  ```
23
23
 
24
24
  Run only one install command. Confirm that `sipgate-mcp --version` reports
25
- `0.3.1` before continuing.
25
+ `0.5.1` before continuing.
26
26
 
27
27
  ## Security boundary
28
28
 
@@ -32,8 +32,36 @@ Run only one install command. Confirm that `sipgate-mcp --version` reports
32
32
  files, logs, or issue reports.
33
33
  - The local server uses a sipgate Personal Access Token. A sipgate OAuth API
34
34
  client ID and secret are not substitutes for this local setup.
35
- - Keep the first setup user-scoped and read-only. Do not enable write tools or
35
+ - Keep setup user-scoped. Let the setup prompt decide read-only versus write
36
+ tools, and do not pass `--allow-writes` on the user's behalf. Never enable
36
37
  account-wide administrator access without an explicit user request.
38
+ - The automated-recording greeting is account-global and intentionally fails
39
+ closed in user scope; its read/create/delete tools require explicitly
40
+ requested administrator account scope.
41
+ - User scope remains the resource boundary for write tools: device IDs,
42
+ phone-number IDs, emergency-address IDs, notification IDs, live-call
43
+ participants, phonelines, nested parallel forwardings, voicemails and
44
+ greetings, attached devices, faxlines, and automated-recording extensions
45
+ are checked against the authenticated user's ownership before account
46
+ changes are sent.
47
+ - Contacts and the incoming blacklist are account-wide resources. In user
48
+ scope, never call one of their write tools unless the user explicitly agrees
49
+ to the account-wide effect and the call includes
50
+ `confirm_account_wide: true`. The same confirmation is always required to
51
+ cancel a number porting, and user-scoped sipgate.io settings updates require
52
+ it as well.
53
+ - History writes are limited to owned entries. An omitted ID list for bulk
54
+ deletion is expanded to entries from owned connection IDs; never work around
55
+ that boundary with account scope unless the user explicitly requested
56
+ administrator-wide access.
57
+ - Never display device credentials. Password rotation deliberately redacts the
58
+ one-time password returned by sipgate.
59
+ - Fax send/resend and call-initiating voicemail playback/recording actions may
60
+ incur charges. Call and automated recording are legally sensitive; in
61
+ Germany the caller is responsible for obtaining every participant's consent,
62
+ even when the recording announcement is off.
63
+ - Contact CSV imports and history/contact deletions are destructive. Cancelling
64
+ a number porting is irreversible through the v2 API.
37
65
  - Do not remove or replace an existing MCP configuration without the user's
38
66
  approval.
39
67
 
@@ -54,8 +82,26 @@ sipgate-mcp setup --client claude
54
82
 
55
83
  Omit `--client` only when both installed clients should be configured. The
56
84
  setup delegates PAT entry directly to macOS Keychain and registers a
57
- user-scoped, read-only stdio server. The client starts and stops that process;
58
- do not launch `sipgate-mcp` as a daemon.
85
+ user-scoped stdio server. Its interactive prompt asks whether write tools should
86
+ be enabled; do not answer that choice on the user's behalf. The client starts
87
+ and stops that process, so do not launch `sipgate-mcp` as a daemon.
88
+
89
+ Version 0.5.1 adds user-scoped device, quick-dial, user-number, emergency-
90
+ address, notification, live-call-control, phoneline, voicemail/greeting,
91
+ automated-recording, fax, contact, blacklist, restriction, history-management,
92
+ porting, balance, and sipgate.io self-service. It supports accounts without
93
+ phonelines: direct number reads use `/{userId}/numbers`, ownership checks retain
94
+ the device-based number fallback, and phoneline-only tools return an explicit
95
+ unavailable result instead of surfacing sipgate's 403. Active calls are
96
+ filtered by participants matching owned devices or numbers; nested voicemail,
97
+ greeting, forwarding, attached-device, faxline, and recording-extension IDs
98
+ are verified before use. History updates/deletes and exports are constrained to
99
+ owned connection IDs; account-wide contacts/blacklist writes and sipgate.io
100
+ updates require explicit confirmation in user scope, as does porting
101
+ cancellation. Device/faxline/phoneline creation, fax transmission, call
102
+ sessions, recording, and other writes may incur charges or carry legal
103
+ consequences, and address changes can deactivate associated numbers depending
104
+ on country.
59
105
 
60
106
  When credentials already exist in Keychain, setup reuses them without another
61
107
  prompt. Use `--replace-credentials` only when the user explicitly wants to