Manage your VoIP.ms account from Claude/ChatGPT — an (unofficial) MCP server

Hi all — we built a hosted MCP (Model Context Protocol) server for VoIP.ms and wanted to share it with the community. It’s an independent, unofficial product (not affiliated with or endorsed by VoIP.ms).

What it does: it turns your VoIP.ms account into a set of tools an AI assistant (Claude, ChatGPT, or any MCP-capable client) can use. Once connected, you can just ask it to look up your DIDs, send a text, check your balance, set up voicemail, order/port a number, manage ring groups and IVRs, and more. It talks to the standard VoIP.ms REST/JSON API on your behalf.

How access works: it’s a hosted service (nothing to install). You sign in, register your VoIP.ms API username/password once (stored encrypted), and then grant per-area, view-only-or-manage permissions at connect time — the assistant can only touch what you approve.

There’s a free tier to try it out. Landing page + setup steps: https://voipms-mcp.ecliptical.io

Happy to answer questions or take feedback here. We saw a few recent threads asking about the API and integrations, so hopefully this is useful to some of you.

1 Like

Hello @pnehrer,

This is a very nice project: I have seen your posts on two other topics about it. But at the same time I could never give my voip.ms credentials, even for testing purposes.

If it was a local MCP, I might dare, but even there, I would also use a local AI to run it. (For security reasons. What one sends to AI, most of the time also stays somewhere in AI “memory”—to use simple terms). :face_with_diagonal_mouth:

Kind regards!

2 Likes

Thank your for the thoughtful feedback, @aleclerc!

I completely understand your reservations regarding the API credentials; however, I think there’s a detail in the design that addresses the heart of it: the AI agent never gets your VoIP.ms credentials. That’s one of the benefits of the MCP model. The MCP server is the only component that ever holds your API username/password — just like any other API client would — and it uses them to talk to the VoIP.ms REST API on your behalf. It never divulges them to the assistant or the LLM. The AI only ever sees the tools it’s allowed to call and the results that come back; the credentials stay sealed on the server.

On top of that, they’re stored encrypted, and at connect time you grant per-area, view-only-or-manage scopes — so a request can only touch the areas you explicitly approved.

Would love to hear any other feedback or concerns you may have — our aim is to make VoIP.ms easier to use by bringing the power of AI to scenarios that can otherwise get pretty complex.

1 Like

Hi @pnehrer,

You are right, thank you for these details. Only the MCP server has that information.

What do you do concerning the locally crypted and saved credentials? I understand this is required for the MCP server, but at the same time, it means it is still technically possible for people having the “key” to read the credentials. I guess this is a question of trust from that point on.

But on the other side, a local MCP server solves this instantly.

Well, thank you very much, again, for this information. This is an interesting project, especially for managers of big sites. This can be very useful to add and remove and manage telephony stuff when there are many users, etc.

Best regards!

I’m trying to understand what you mean by a local MCP server solving this instantly. I think it just moves where the credential sits. It still has to store your voip.ms credential somewhere on your machine and decrypt it to use it – so now the “key” is on your laptop, protected by whatever your OS and disk encryption provide, which isn’t obviously stronger than a gated, least-privilege, audited path. And unless you run your own LLM locally, it is the same whether the server is local or hosted – local vs. hosted moves the credential. Where local genuinely wins is removing us as a party you have to trust at all, and if that’s the deciding factor it’s a fair call.

Hosted buys you a few things in return: nothing to install, patch, or keep running; the OAuth2 scoping/revocation layer below, which a bare local setup usually skips in favor of a plaintext credential in a config file; the credential sealed server-side instead of sitting on a laptop that gets lost or stolen; and it works the same from any device without re-copying your credential onto each one.

To illustrate, here are the two credentials in play, because they’re different things going in different directions:

┌──────────────┐   OAuth2 access token    ┌──────────────┐   voip.ms API cred    ┌──────────────┐
│  AI agent    │ ───────────────────────> │  MCP server  │ ────────────────────> │  voip.ms API │
│ (Claude,     │   short-lived, scoped,   │              │   your real API user/ │  (backend)   │
│  ChatGPT)    │   per-client, revocable  │              │   pass, decrypted     │              │
└──────────────┘                          └──────────────┘   in-memory per call  └──────────────┘
     never sees your voip.ms credential          │
                                                 └─ credential encrypted at rest

  1. Agent → MCP server carries an OAuth2 access token, never your voip.ms credential. It’s short-lived, revocable, and scoped – you approve exactly which areas a client gets (say dids:read + sms, nothing else), and anything outside that is rejected. Revoke it and the agent is cut off with your voip.ms password untouched. Handing a fixed API credential straight to the agent has none of that: long-lived, all-or-nothing, and un-revocable short of changing the password everywhere.

  2. MCP server → voip.ms is the only leg that carries your real voip.ms credential, and the agent never sees it.

On “someone with the key can read the credentials” – which credential do you mean?

  • If it’s the OAuth2 access token (the thing the agent holds): yes, whoever holds that token can act with it – that’s true of any bearer token, including the one a local server would use. That’s exactly why it’s short-lived, scoped, and revocable: worst case is limited to the areas you granted, it expires, and you can kill it without touching your voip.ms password.
  • If it’s the voip.ms API credential (your real user/pass): no user ever holds a “key” to it. It’s sealed with envelope encryption – a data key encrypts it, and that data key is itself encrypted under a master key that can’t be exported by anyone, including us. There’s no key file to copy. Only the MCP server can decrypt it, through an authenticated, decrypt-only call, and only in memory for a single request – never stored or logged, never handed to a user or an agent. A database dump gets an attacker ciphertext, nothing more.
1 Like

Hello @pnehrer,

Yes, it is moving where the credentials are stored. It can be as secure locally as hosted. But it can also be less secure in both cases.

If the API access password (or token) is saved on your servers and accessible by you, or if the server is compromised, a bad actor could access the account and do damage (spam, rerouting, deleting things, etc.). Since the code is closed-source (which is fine) and no security audits are publicly available, a relation of trust is indeed required.

VoIP.ms API does not allow (yet) the creation of multiple tokens, nor the ability to set granular access rights. It is always full access. This creates a single point of failure. It is not possible to tell the VoIP.ms API that a given token cannot reroute DIDs, change billing, delete sub-accounts, etc. You see what I mean. So a bad actor could do a lot of damage to one’s setup (and very quickly with an AI).

Maybe you will be able to find ways to address these kinds of concerns.

Anyways, again, a very nice project. As for me personally, I am just a bit too paranoid at this point, and VoIP.ms does not yet give enough controls on the API side to help build that trust.

Best regards!

Hi @aleclerc,

I appreciate your concerns. Thank you again for your feedback!

–Peter

1 Like

This is exciting and useful! Amazing!

Peter, this is a really incredible contribution to the voip.ms community!

Is there a way to do this so that the model does not access my call reports? I am fine with the model having DID access. My DIDs are already linked to me. However, despite most AI companies stating they don’t sell data, I don’t know what the future holds and don’t totally trust them to really delete data. I just don’t need an AI company to know every single phone number that calls me or that I call.

This is so convenient that I may use it anyway, even if there’s no way to limit the model’s access to call reports, which would be my main privacy concern.

Hi @sipper, thank you for your kind words!

Yes, you can do precisely what you’re describing. Access is granted per capability area when you connect your agent to the MCP server, on the consent screen. Call reports have their own scope — “Call records (CDR)” — completely separate from DIDs. So when you connect, you’d simply grant DID access and leave Call records unchecked. The model then never receives your call detail records at all: the server won’t return them, and if the agent ever tries to call a CDR-related tool, it’s rejected outright rather than quietly handing over the data.

In other words, the AI only ever sees the areas you explicitly opt into. Your call history never leaves your account unless you deliberately grant that scope, and you can revoke or re-scope any of this at any time by reconnecting.

Please keep the questions and feedback coming!

–Peter

1 Like

To use this tool, do I have to trust you or another party with API token access?

Given that VoIP.ms has some API access tools, does this MCP server do anything that an advanced model can’t access via CLI and API access?

It looks like I don’t have to trust the model with the token, but I do have to trust you or your server (you), right? I am just confirming.

I still think this is great and can be helpful for people, but also need to understand if there are advantages over API token plus CLI usage.

The visual interface also looks great. I am checking out the site. I don’t know if I have a use case for it yet, but may in the future.

Following up on my note above about per-area access – here’s what it actually looks like in practice.

When you connect, access is granted per capability area on the consent screen. In this example we grant everything except “View call records” (the CDR / call-history area), which we’ve deliberately left unchecked:

Then, in a normal chat, we ask for exactly that:

Show me my call history from the last 7 days.

Because that area was never granted, the model never receives the data. Rather than quietly returning nothing – or making something up – the connector stops the call and prompts you to grant just that one area before it will run:

Grant it and call history works; leave it unchecked and that area stays off-limits while everything else you did grant keeps working. The same opt-in applies to SMS, voicemail, billing, E911, and the rest, with view-only vs. manage as a separate choice for each.

1 Like

Let me answer each point in turn:

On trust: There are two parties.

First, the server: to use the hosted version you’re trusting that it holds your VoIP.ms API credential and handles it as described – encrypted at rest, only ever used server-side, never handed to the model. That’s the tradeoff of a hosted service. What the design does is shrink what you’re trusting it with: the credential never touches the AI or the AI vendor, and you can revoke the server’s access at any time.

Second, the AI agent (Claude, ChatGPT, etc.): it holds the OAuth tokens the server issues, so you’re trusting your MCP client to store those. But those tokens are short-lived, scoped to only the areas you granted, and revocable, so even in the worst case a leaked token is bounded in what it can do and how long it works, and it’s never your actual VoIP.ms credential. That’s a very different exposure from handing the agent the real key.

So the trust is required, but it’s split, bounded, and inspectable rather than “hand over the keys and hope.”

If even that bounded trust is more than you want, that’s completely fair, and it’s exactly why we’re considering a local MCP server version, where your voip.ms API credentials never touch our infrastructure.

On “what does this do that a model with CLI + API access can’t?” – here’s the key difference: to give a model CLI or direct API access, you have to put your VoIP.ms API credential somewhere the model can read it – a shell config, an env var, a file it can cat, or pasted straight into the prompt. At that point the model (and its vendor) has your full-access, long-lived credential, with no scoping and nothing to revoke short of rotating the key. That’s the thing the MCP server is designed to avoid: the credential lives server-side and the model only ever sees short-lived, scoped, revocable tokens – it never handles the key itself.

On top of that, the server packages the plumbing you’d otherwise build and maintain yourself: the auth/consent layer, per-area scoping and revocation, human-readable resolution of raw codes (POP numbers, routing strings, plan IDs), guardrails and confirmations on destructive or money-moving actions, and one consistent tool contract across Claude, ChatGPT, and other MCP clients without per-client glue.

1 Like

Thanks for the excellent explanation! Looks great.