PHPackages                             vielhuber/exchangehelper - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. vielhuber/exchangehelper

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

vielhuber/exchangehelper
========================

Exchange/Outlook/Microsoft Graph helper for contacts, calendar events and To Do tasks with an MCP server.

1.0.6(2w ago)018MITPHPPHP ^8.3

Since May 21Pushed 2w agoCompare

[ Source](https://github.com/vielhuber/exchangehelper)[ Packagist](https://packagist.org/packages/vielhuber/exchangehelper)[ RSS](/packages/vielhuber-exchangehelper/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (2)Versions (8)Used By (0)

[![build status](https://github.com/vielhuber/exchangehelper/actions/workflows/ci.yml/badge.svg)](https://github.com/vielhuber/exchangehelper/actions)[![GitHub Tag](https://camo.githubusercontent.com/b6b1e702b9b462a19f5d096ee2b48f8529d4ba6cd66d756605ed0b188b616e84/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f7461672f7669656c68756265722f65786368616e676568656c706572)](https://github.com/vielhuber/exchangehelper/tags)[![Code Style](https://camo.githubusercontent.com/1540f8ce219727155ab62506c77b818b720421c22c4cf0b18a5f160942132e2d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f64655f7374796c652d7073722d2d31322d6666363962342e737667)](https://www.php-fig.org/psr/psr-12/)[![License](https://camo.githubusercontent.com/0fc18f3376c1f28d489bf90d47f4d3e7501125d84cac65bbdd5ec50d6215e39f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f7669656c68756265722f65786368616e676568656c706572)](https://github.com/vielhuber/exchangehelper/blob/main/LICENSE.md)[![Last Commit](https://camo.githubusercontent.com/4c0bcc2196529c78f7b95665a352bd21cf7bf33b7cbe464e75f397ba64dd3a44/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6173742d636f6d6d69742f7669656c68756265722f65786368616e676568656c706572)](https://github.com/vielhuber/exchangehelper/commits)[![PHP Version Support](https://camo.githubusercontent.com/94d9a7fbeac657bab693563437d284853e99cda0664a8bbb370d26ac392c8ec7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f7669656c68756265722f65786368616e676568656c706572)](https://packagist.org/packages/vielhuber/exchangehelper)[![Packagist Downloads](https://camo.githubusercontent.com/431d362deccaeab4088f6684d2de965dfa50e8b69417a96c8d0b2ca879b631c6/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7669656c68756265722f65786368616e676568656c706572)](https://packagist.org/packages/vielhuber/exchangehelper)

📇 exchangehelper 📇
==================

[](#-exchangehelper-)

exchangehelper is a helper for Exchange, Outlook and Microsoft 365.

it focuses on contacts, calendar events and Microsoft To Do lists/tasks. mail stays outside this package because it is already covered by mailhelper.

installation
------------

[](#installation)

install once with [composer](https://getcomposer.org/):

```
composer require vielhuber/exchangehelper

```

then add this to your files:

```
require __DIR__ . '/vendor/autoload.php';
use vielhuber\exchangehelper\exchangehelper;
```

setup
-----

[](#setup)

exchangehelper always reads Microsoft credentials from the `.env` in your project root. do not pass secrets in php.

create or extend your existing project `.env`:

```
EXCHANGEHELPER_GRAPH_TENANT_ID=example.onmicrosoft.com
EXCHANGEHELPER_GRAPH_CLIENT_ID=00000000-0000-0000-0000-000000000000
EXCHANGEHELPER_GRAPH_CLIENT_SECRET=secret
EXCHANGEHELPER_GRAPH_USER_ID=user@example.com
```

exchangehelper uses Microsoft Graph application permissions. this is the server-to-server flow:

1. open [entra app registrations](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade) and create a new app registration.
2. copy **application (client) id** to `EXCHANGEHELPER_GRAPH_CLIENT_ID` and **directory (tenant) id** to `EXCHANGEHELPER_GRAPH_TENANT_ID`.
3. create a client secret under **certificates &amp; secrets** and copy its value to `EXCHANGEHELPER_GRAPH_CLIENT_SECRET`.
4. open **api permissions**, click **add a permission**, choose **Microsoft Graph**, then choose **application permissions**.
5. search and add these permissions:
    - `Contacts.ReadWrite`
    - `Calendars.ReadWrite`
    - `Tasks.Read.All`
    - `Tasks.ReadWrite.All`
6. click **grant admin consent** for the tenant and confirm the prompt. the status column should show a green checkmark for every permission.
7. set `EXCHANGEHELPER_GRAPH_USER_ID` to the mailbox user, for example `user@example.com`.

```
EXCHANGEHELPER_GRAPH_TENANT_ID=example.onmicrosoft.com
EXCHANGEHELPER_GRAPH_CLIENT_ID=00000000-0000-0000-0000-000000000000
EXCHANGEHELPER_GRAPH_CLIENT_SECRET=secret
EXCHANGEHELPER_GRAPH_USER_ID=user@example.com
```

```
$exchange = new exchangehelper();
```

usage
-----

[](#usage)

### contacts

[](#contacts)

```
$contacts = $exchange->getContacts(query: 'David', limit: 10);
$contact = $exchange->getContact(id: $contacts[0]['id']);

$created = $exchange->addContact([
    'display_name' => 'Ada Lovelace',
    'emails' => ['ada@example.com'],
    'phones' => [
        'mobile' => '+491701234567'
    ],
    'company_name' => 'Analytical Engines Ltd.'
]);

$updated = $exchange->updateContact(id: $created['id'], data: [
    'job_title' => 'Mathematician'
]);

$exchange->removeContact(id: $created['id']);
```

### calendar

[](#calendar)

```
$events = $exchange->getCalendarEvents(
    start: '2026-05-01T00:00:00Z',
    end: '2026-05-31T23:59:59Z',
    limit: 50
);

$event = $exchange->addCalendarEvent([
    'subject' => 'Project sync',
    'start' => '2026-05-21T10:00:00',
    'end' => '2026-05-21T10:30:00',
    'timezone' => 'Europe/Berlin',
    'location' => 'Teams',
    'attendees' => ['ada@example.com']
]);

$exchange->removeCalendarEvent(id: $event['id']);
```

### to do

[](#to-do)

```
$lists = $exchange->getTodoLists();
$tasks = $exchange->getTodoTasks(list_id: $lists[0]['id']);

$task = $exchange->addTodoTask(list_id: $lists[0]['id'], data: [
    'title' => 'Prepare meeting',
    'body' => 'Collect notes',
    'due' => '2026-05-21T18:00:00',
    'timezone' => 'Europe/Berlin'
]);

$exchange->updateTodoTask(list_id: $lists[0]['id'], id: $task['id'], data: [
    'status' => 'completed'
]);
```

mcp server
----------

[](#mcp-server)

exchangehelper ships as a standalone [mcp](https://modelcontextprotocol.io/) server for ai-agent workflows.

```
# run this from your project root where .env lives
vendor/bin/mcp-server.php

```

the server speaks both stdio (CLI invocation) and HTTP via [simplemcp](https://github.com/vielhuber/simplemcp). `auth: 'static'` mode expects the bearer token in `MCP_TOKEN` from your project `.env`.

available tools:

- `contacts_search(query?, limit?)`
- `contacts_get(id)`
- `calendar_list_events(start?, end?, limit?)`
- `todo_list_lists()`
- `todo_list_tasks(list_id?)`
- `todo_create_task(list_id, title, body?, due?)`

tests
-----

[](#tests)

the test suite reads the project `.env`. if Microsoft Graph credentials are present, it runs one live test against that server; otherwise the live test is skipped. the live test only creates/update/deletes its own `exchangehelper integration ...` test entries:

```
vendor/bin/phpunit
```

###  Health Score

44

—

FairBetter than 90% of packages

Maintenance97

Actively maintained with recent releases

Popularity9

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

7

Last Release

17d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/3183737?v=4)[David Vielhuber](/maintainers/vielhuber)[@vielhuber](https://github.com/vielhuber)

---

Top Contributors

[![vielhuber](https://avatars.githubusercontent.com/u/3183737?v=4)](https://github.com/vielhuber "vielhuber (8 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/vielhuber-exchangehelper/health.svg)

```
[![Health](https://phpackages.com/badges/vielhuber-exchangehelper/health.svg)](https://phpackages.com/packages/vielhuber-exchangehelper)
```

###  Alternatives

[nunomaduro/curryable

An elegant and simple curry(f) implementation in PHP.

1752.3k](/packages/nunomaduro-curryable)[elgentos/vat-switcher

Vat switcher to let customer decide on how to show their prices

1512.0k](/packages/elgentos-vat-switcher)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
