Skip to main content
Glama
NilsTv8

TeamViewer MCP Server

by NilsTv8

TeamViewer MCP Server (no-DCR)

A Model Context Protocol (MCP) server that exposes the TeamViewer Web API as tools for AI assistants — specifically for MCP clients that don't support Dynamic Client Registration (RFC 7591), such as Microsoft Copilot Studio / Power Platform custom connectors.

The server is an OAuth 2.0 authorization server + resource server that brokers access to TeamViewer. It never hands MCP clients a real TeamViewer token: it issues its own opaque, audience-bound tokens, holds TeamViewer credentials encrypted server-side, and resolves a live TeamViewer token internally on every tool call.

MCP client (Copilot Studio)
    ↕ OAuth via /authorize, /token (this server)
MCP server (this repo)
    ↕ OAuth via account.teamviewer.com + webapi.teamviewer.com
TeamViewer

Two deployment variants

This project ships as two parallel repos, because the target MCP clients speak OAuth client registration differently:

Variant

Repo

Use for

DCR

NilsTv8/TV_ONE_MCP_Anthropic

Clients that support Dynamic Client Registration (e.g. Claude.ai connectors)

No-DCR (this repo)

NilsTv8/TV_ONE_MCP_Anthropic_noDCR

Clients that don't (e.g. Microsoft Copilot Studio / Power Platform)

This repo accepts any client_id (no registration step), but still strictly validates redirect_uri — either an exact match against MCP_ALLOWED_REDIRECT_URIS, or a trusted domain (and its subdomains) via MCP_ALLOWED_REDIRECT_HOSTS. At least one of the two must be set, or every /authorize request is rejected (fail closed).


Requirements


Setup

1. Register a TeamViewer OAuth app

  1. Go to login.teamviewer.com → Integrations → Apps and sign in.

  2. Create an app and set its Callback URL to {TEAMVIEWER_MCP_URL}/callback (the public URL this server will run at, plus /callback — see Step 3).

  3. Copy the Client ID and Client Secret.

2. Install and build

git clone https://github.com/NilsTv8/TV_ONE_MCP_Anthropic_noDCR.git
cd TV_ONE_MCP_Anthropic_noDCR
npm install
npm run build

3. Configure environment variables

Variable

Required

Description

TEAMVIEWER_CLIENT_ID

Yes

TV OAuth app client ID (from Step 1)

TEAMVIEWER_CLIENT_SECRET

Yes

TV OAuth app client secret

MCP_ALLOWED_REDIRECT_URIS

No*

Comma-separated list of exact, trusted MCP-client callback URLs

MCP_ALLOWED_REDIRECT_HOSTS

No*

Comma-separated list of trusted domains — matches that host exactly or any subdomain of it (e.g. consent.azure-apim.net covers Copilot Studio's global.consent.azure-apim.net, unitedstates.consent.azure-apim.net, etc.)

TEAMVIEWER_MCP_URL

Yes

Public base URL of this server (no trailing slash)

TEAMVIEWER_CALLBACK_URL

No

OAuth callback URL — defaults to {TEAMVIEWER_MCP_URL}/callback

PORT

No

HTTP port (default 3000)

* At least one of MCP_ALLOWED_REDIRECT_URIS / MCP_ALLOWED_REDIRECT_HOSTS must be set.

No encryption-key variable is needed — TeamViewer tokens are encrypted server-side with a key generated fresh in memory on every boot (see Security design below).

4. Run

TEAMVIEWER_CLIENT_ID=<id> \
TEAMVIEWER_CLIENT_SECRET=<secret> \
MCP_ALLOWED_REDIRECT_HOSTS=consent.azure-apim.net \
TEAMVIEWER_MCP_URL=https://<your-public-domain> \
PORT=3000 node dist/index.js

5. Connect Copilot Studio (or another non-DCR client)

Create a custom connector with OAuth 2.0 "Generic" authentication:

Field

Value

Authorization URL

https://<your-public-domain>/authorize

Token URL

https://<your-public-domain>/token

Refresh URL

same as Token URL

Client ID / secret

from Step 1

Scope

see Available scopes below

Power Platform generates its own redirect URL per connector after you save it (https://<region>.consent.azure-apim.net/redirect/<connector-id>) — that's exactly what MCP_ALLOWED_REDIRECT_HOSTS=consent.azure-apim.net is for; you don't need to copy the generated URL anywhere.


OAuth endpoints (auto-served)

Endpoint

Purpose

GET /.well-known/oauth-protected-resource (and /mcp suffix)

RFC 9728 protected resource metadata

GET /.well-known/oauth-authorization-server

RFC 8414 authorization server metadata

GET /authorize

Starts the OAuth flow → redirects to TeamViewer

POST /token

Exchanges an authorization code or refresh token

POST /revoke

Revokes a token

GET /callback

TeamViewer redirects here after the user logs in

(POST /register / Dynamic Client Registration is intentionally not offered in this variant — see the DCR repo instead.)


Available tools

27 action-based tools (each multi-action tool takes a single action parameter plus action-specific fields):

Group

Tools

Account & Company

tv_account, tv_company

Users & Access Management

tv_users, tv_deactivate_user_tfa, tv_get_user_effective_permissions, tv_get_user_roles, tv_respond_to_join_company_request, tv_user_roles, tv_user_role_assignments, tv_user_groups, tv_user_group_members

Contacts

tv_contacts

Devices & Device Groups

tv_device_groups, tv_managed_devices, tv_managed_device_managers, tv_managed_groups, tv_managed_group_managers

Policies

tv_teamviewer_policies, tv_monitoring_policies, tv_patch_policies

Monitoring

tv_monitoring

Sessions & Remote Control

tv_sessions, tv_connect_device

Reports & Event Logs

tv_connection_reports, tv_list_device_reports, tv_get_event_logs

Tokens

tv_tokens (permanent, non-expiring TeamViewer API tokens — separate from this server's own OAuth tokens)

Each tool's description (visible via tools/list) documents its exact action values and parameters.

Available scopes

Requested during the OAuth flow; map to TeamViewer's own API permission scopes:

UserInfo.View · Computers.View · Computers.Edit · Computers.Delete · Groups.View · Groups.Create · Groups.Edit · Groups.Delete · Contacts.View · Contacts.Create · Contacts.Edit · Contacts.Delete · Partners.View · Sessions.ManualCreation


Docker

docker build -t teamviewer-mcp-nodcr .
docker run -p 3000:3000 \
  -e TEAMVIEWER_CLIENT_ID=<id> \
  -e TEAMVIEWER_CLIENT_SECRET=<secret> \
  -e MCP_ALLOWED_REDIRECT_HOSTS=consent.azure-apim.net \
  -e TEAMVIEWER_MCP_URL=https://<your-public-domain> \
  teamviewer-mcp-nodcr

The image is a pinned, multi-stage, non-root build (compiles with dev dependencies in a build stage, ships only dist/ and production dependencies in the runtime stage) with a container HEALTHCHECK against /.well-known/oauth-authorization-server.

Production

Hosted on Azure App Service with this Docker image. Azure terminates TLS; the server always runs plain HTTP internally. Deploys automatically on every push to master.


Security design

  • No TeamViewer token pass-through — this server issues its own opaque, audience-bound tokens; TeamViewer access/refresh tokens are held server-side, AES-256-GCM encrypted, and only ever resolved internally right before a WebAPI call.

  • Refresh-token rotation with reuse detection — replaying a consumed refresh token revokes the whole session.

  • redirect_uri allow-list, not a rubber stamp — since any client_id is accepted, the allow-list (MCP_ALLOWED_REDIRECT_URIS / MCP_ALLOWED_REDIRECT_HOSTS) is the only check on where an authorization code can be sent; it's enforced so a mismatch gets a direct (non-redirecting) rejection, never a redirect to an unvalidated target.

  • No raw upstream error text in tool results — a failed TeamViewer API call is logged in full server-side; only the HTTP status is surfaced to the calling tool/LLM.

See CLAUDE.md in this repo for full architectural detail, local dev setup, and environment specifics.


License

MIT