At this stage, the code is known to work and has been thoroughly tested
This commit is contained in:
+161
@@ -0,0 +1,161 @@
|
||||
# Library Usage
|
||||
|
||||
The CLI uses the same client class that application code can use directly.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
require __DIR__ . '/../src/VoipMsClient.php';
|
||||
|
||||
use VoipMs\VoipMsClient;
|
||||
|
||||
$client = new VoipMsClient(
|
||||
getenv('VOIPMS_API_USERNAME'),
|
||||
getenv('VOIPMS_API_PASSWORD'),
|
||||
);
|
||||
|
||||
$response = $client->getPhonebookGroups();
|
||||
|
||||
if (!$response->successful()) {
|
||||
throw new RuntimeException($response->message() ?? 'VoIP.ms request failed.');
|
||||
}
|
||||
|
||||
foreach ($response->data()['phonebook_groups'] ?? [] as $group) {
|
||||
echo $group['phonebook_group'] . ' ' . $group['name'] . PHP_EOL;
|
||||
}
|
||||
```
|
||||
|
||||
If a command does not have a convenience method yet, use the generic request method:
|
||||
|
||||
```php
|
||||
$response = $client->request('getDIDsInfo', ['did' => '5551234567']);
|
||||
```
|
||||
|
||||
For backwards compatibility with the CLI, `call()` still returns the older array shape:
|
||||
|
||||
```php
|
||||
$result = $client->call('getBalance');
|
||||
echo $result['raw'];
|
||||
```
|
||||
|
||||
## Convenience Methods
|
||||
|
||||
General:
|
||||
|
||||
```php
|
||||
$client->getBalance();
|
||||
$client->getBalance(advanced: true);
|
||||
$client->getDidsInfo();
|
||||
$client->getDidsInfo('5551234567');
|
||||
```
|
||||
|
||||
Phonebook:
|
||||
|
||||
```php
|
||||
$client->getPhonebook();
|
||||
$client->getPhonebookByGroup('16389');
|
||||
$client->getPhonebookByGroupName('Spam');
|
||||
$client->getPhonebookGroups();
|
||||
$client->findPhonebookGroupByName('Spam');
|
||||
$client->findOrCreatePhonebookGroup('Spam');
|
||||
$client->findPhonebookEntriesByNumber('5553334444');
|
||||
$client->setPhonebook([
|
||||
'name' => 'Jane Smith',
|
||||
'number' => '5553334444',
|
||||
'group' => '16389',
|
||||
]);
|
||||
$client->deletePhonebook('32207');
|
||||
$client->setPhonebookGroup('Spam');
|
||||
$client->deletePhonebookGroup('16389');
|
||||
```
|
||||
|
||||
To add a number to a named group without creating duplicate entries:
|
||||
|
||||
```php
|
||||
$result = $client->addNumberToPhonebookGroup(
|
||||
number: '5553334444',
|
||||
groupName: 'Spam',
|
||||
name: 'Spam Caller',
|
||||
note: 'Marked by automation',
|
||||
);
|
||||
|
||||
if ($result->changed()) {
|
||||
echo 'Added entry IDs: ' . implode(', ', $result->addedEntryIds()) . PHP_EOL;
|
||||
}
|
||||
```
|
||||
|
||||
The helper creates the group if needed, reuses existing phonebook entries for
|
||||
the same number when possible, and only creates a new phonebook entry when the
|
||||
number does not already exist.
|
||||
|
||||
Removing a number from a group is a group membership update. VoIP.ms stores
|
||||
group members as phonebook entry IDs, and it may allow duplicate phonebook
|
||||
entries for the same number. The helper below removes every entry in the group
|
||||
whose `number` matches, but keeps the phonebook entries themselves:
|
||||
|
||||
```php
|
||||
$result = $client->removePhonebookNumberFromGroup('16389', '5553334444');
|
||||
|
||||
echo 'Removed IDs: ' . implode(', ', $result->removedEntryIds()) . PHP_EOL;
|
||||
|
||||
if (!$result->response()->successful()) {
|
||||
throw new RuntimeException($result->response()->message() ?? 'Group update failed.');
|
||||
}
|
||||
```
|
||||
|
||||
If you already know the phonebook entry IDs to remove:
|
||||
|
||||
```php
|
||||
$client->removePhonebookEntriesFromGroup('16389', ['32207', '32208']);
|
||||
```
|
||||
|
||||
Only pass `deleteMatchedEntries: true` when you want to delete those phonebook
|
||||
entries from the account entirely after removing them from the group:
|
||||
|
||||
```php
|
||||
$client->removePhonebookNumberFromGroup('16389', '5553334444', deleteMatchedEntries: true);
|
||||
```
|
||||
|
||||
Caller ID filtering:
|
||||
|
||||
```php
|
||||
$client->getCallerIdFiltering();
|
||||
$client->setCallerIdFiltering([
|
||||
'callerid' => 'p:16389',
|
||||
'did' => 'all',
|
||||
'routing' => 'sys:busy',
|
||||
'note' => 'Spam group',
|
||||
]);
|
||||
$client->deleteCallerIdFiltering('18915');
|
||||
```
|
||||
|
||||
Call records and SMS:
|
||||
|
||||
```php
|
||||
$client->getAccounts();
|
||||
$client->getCallAccounts();
|
||||
$client->getCdr('2026-04-01', '2026-04-20', '-4', [
|
||||
'calltype' => 'incoming',
|
||||
'callbilling' => 'all',
|
||||
]);
|
||||
$client->getCallRecordings('all', '2026-04-01', '2026-04-20');
|
||||
$client->getCallRecording('100000_VoIP', '<value-from-getCallRecordings>');
|
||||
$client->sendCallRecordingEmail('100000_VoIP', 'you@example.com', '<value-from-getCallRecordings>');
|
||||
$client->sendSms('5551234567', '5553334444', 'Hello');
|
||||
```
|
||||
|
||||
`getAccounts()` is a friendly alias for VoIP.ms `getCallAccounts`. It does not
|
||||
list VoIP.ms portal login users. It returns account filter values such as `all`
|
||||
or subaccount identifiers like `100000_VoIP`; use the returned `value` field as
|
||||
the `account` argument for `getCdr()`, `getCallRecordings()`,
|
||||
`getCallRecording()`, and `sendCallRecordingEmail()`.
|
||||
|
||||
`getCdr()` defaults to all call statuses (`answered`, `noanswer`, `busy`,
|
||||
and `failed`) because the VoIP.ms API rejects requests where none of those
|
||||
flags are set. Pass one or more status filters to narrow the result:
|
||||
|
||||
```php
|
||||
$client->getCdr('2026-04-01', '2026-04-20', '-4', [
|
||||
'answered' => '1',
|
||||
]);
|
||||
```
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
# Test MCP Server
|
||||
|
||||
This project includes a dependency-free HTTP JSON-RPC MCP endpoint for testing
|
||||
remote-agent access to the VoIP.ms library.
|
||||
|
||||
It is intended for development and testing. It binds to `0.0.0.0` by default,
|
||||
so use a firewall, VPN, or private network when exposing it beyond this machine.
|
||||
|
||||
## Start The Server
|
||||
|
||||
```bash
|
||||
export VOIPMS_API_USERNAME='you@example.com'
|
||||
export VOIPMS_API_PASSWORD='your-api-password'
|
||||
export MCP_AUTH_TOKEN='choose-a-long-random-token'
|
||||
|
||||
./bin/serve-mcp.sh
|
||||
```
|
||||
|
||||
Defaults:
|
||||
|
||||
```text
|
||||
MCP_HOST=0.0.0.0
|
||||
MCP_PORT=8787
|
||||
MCP endpoint: http://0.0.0.0:8787/mcp
|
||||
Health endpoint: http://0.0.0.0:8787/health
|
||||
```
|
||||
|
||||
If `MCP_AUTH_TOKEN` is not set, the launcher generates one for that session.
|
||||
For local unauthenticated testing only:
|
||||
|
||||
```bash
|
||||
MCP_ALLOW_UNAUTHENTICATED=1 ./bin/serve-mcp.sh
|
||||
```
|
||||
|
||||
The preferred authentication form is:
|
||||
|
||||
```text
|
||||
Authorization: Bearer <MCP_AUTH_TOKEN>
|
||||
```
|
||||
|
||||
For clients that cannot send custom headers during testing, the same token can
|
||||
be passed as a query parameter:
|
||||
|
||||
```text
|
||||
http://your-host:8787/mcp?token=<MCP_AUTH_TOKEN>
|
||||
```
|
||||
|
||||
Prefer the `Authorization` header when the client supports it.
|
||||
|
||||
## Smoke Test
|
||||
|
||||
```bash
|
||||
curl -s http://127.0.0.1:8787/health
|
||||
```
|
||||
|
||||
Initialize:
|
||||
|
||||
```bash
|
||||
curl -s http://127.0.0.1:8787/mcp \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $MCP_AUTH_TOKEN" \
|
||||
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"test"}}}'
|
||||
```
|
||||
|
||||
Streamable HTTP GET probe:
|
||||
|
||||
```bash
|
||||
curl -sN http://127.0.0.1:8787/mcp \
|
||||
-H "Accept: text/event-stream" \
|
||||
-H "Authorization: Bearer $MCP_AUTH_TOKEN"
|
||||
```
|
||||
|
||||
Legacy SSE probe:
|
||||
|
||||
```bash
|
||||
curl -sN http://127.0.0.1:8787/sse \
|
||||
-H "Accept: text/event-stream" \
|
||||
-H "Authorization: Bearer $MCP_AUTH_TOKEN"
|
||||
```
|
||||
|
||||
List tools:
|
||||
|
||||
```bash
|
||||
curl -s http://127.0.0.1:8787/mcp \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $MCP_AUTH_TOKEN" \
|
||||
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'
|
||||
```
|
||||
|
||||
Call a safe dry-run mutation:
|
||||
|
||||
```bash
|
||||
curl -s http://127.0.0.1:8787/mcp \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $MCP_AUTH_TOKEN" \
|
||||
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"voipms_add_number_to_phonebook_group","arguments":{"number":"5553334444","group_name":"Spam","dry_run":true}}}'
|
||||
```
|
||||
|
||||
## Exposed Tools
|
||||
|
||||
- `voipms_get_balance`
|
||||
- `voipms_get_phonebook_groups`
|
||||
- `voipms_get_phonebook_entries`
|
||||
- `voipms_get_callerid_filters`
|
||||
- `voipms_get_accounts`
|
||||
- `voipms_get_call_accounts`
|
||||
- `voipms_get_call_recordings`
|
||||
- `voipms_get_call_recording`
|
||||
- `voipms_send_call_recording_email`
|
||||
- `voipms_get_call_transcript`
|
||||
- `voipms_get_recent_cdr`
|
||||
- `voipms_add_number_to_phonebook_group`
|
||||
- `voipms_remove_number_from_phonebook_group`
|
||||
|
||||
Mutation tools default to `dry_run=true` and must be called with
|
||||
`dry_run=false` to apply changes.
|
||||
|
||||
`voipms_get_call_transcript` is currently a placeholder. It is listed so remote
|
||||
agents can discover that transcripts are planned, but transcription
|
||||
storage/provider support has not been implemented yet.
|
||||
|
||||
`voipms_get_accounts` is a friendly alias for `voipms_get_call_accounts`. These
|
||||
tools return account filter values for CDR and call recording tools. They do
|
||||
not list VoIP.ms portal login users. Use the returned `value` field as the
|
||||
`account` argument.
|
||||
Reference in New Issue
Block a user