Lightweight, dependency-free Microsoft Graph Teams and chats fake for local tests with @microsoft/microsoft-graph-client.
Defaults
Setting
Value
Service name
teams
Default port
4621
Protocol
HTTP, Microsoft Graph REST-style JSON
Healthcheck
GET /_parlel/health
Reset
POST /_parlel/reset
Base URL
http://127.0.0.1:4621/v1.0
Quick Start
import { TeamsServer } from "./services/teams/src/server.js";
import { Client } from "@microsoft/microsoft-graph-client";
const server = new TeamsServer(4621);
await server.start();
const client = Client.init({
baseUrl: "http://127.0.0.1:4621/v1.0",
authProvider: (done) => done(null, "local-token"),
});
const team = await client.api("/teams").post({
displayName: "Local Team",
description: "No Microsoft tenant required",
});
const channel = await client.api(`/teams/${team.id}/channels`).post({
displayName: "agents",
});
await client.api(`/teams/${team.id}/channels/${channel.id}/messages`).post({
body: { contentType: "text", content: "Hello from parlel" },
});
const messages = await client.api(`/teams/${team.id}/channels/${channel.id}/messages`).get();
await server.stop();
Implemented Operations
Collection responses support a lightweight OData subset: $top, $skip, $count, $filter, $search, $orderby, and $select. Single resource reads support $select where practical. Both /v1.0 and /beta prefixes route to the same implementation.
Emulator
Method
Endpoint
Notes
GET
/_parlel/health
Returns service status and object counts.
POST
/_parlel/reset
Clears ephemeral state and restores seeded users, team, channel, and chat.
GET
/, /v1.0, /beta
Lightweight metadata response.
Users
Method
Endpoint
Notes
GET
/v1.0/me
Returns the current local user.
GET
/v1.0/users/{userId}
Returns a seeded local user by id or mail.
GET
/v1.0/me/joinedTeams
Lists teams where the current user is a member.
GET
/v1.0/users/{userId}/joinedTeams
Lists teams where a user is a member.
GET
/v1.0/me/chats
Lists chats where the current user is a member.
Teams
Method
Endpoint
Notes
GET
/v1.0/teams
Lists teams.
POST
/v1.0/teams
Creates a team and returns 202 with the created team.
GET
/v1.0/teams/{teamId}
Gets a team.
PATCH
/v1.0/teams/{teamId}
Updates displayName, description, classification, visibility, or isArchived.
DELETE
/v1.0/teams/{teamId}
Deletes a team and its in-memory child resources.
POST
/v1.0/teams/{teamId}/archive
Marks the team archived and returns 202.
POST
/v1.0/teams/{teamId}/unarchive
Marks the team unarchived and returns 202.
POST
/v1.0/teams/{teamId}/sendActivityNotification
Accepts the notification payload and returns 202; no outbound notification is sent.
PUT
/v1.0/groups/{groupId}/team
Creates a team using the group id.
GET
/v1.0/groups/{groupId}/team
Gets the team created for a group id.
Team Members
Method
Endpoint
Notes
GET
/v1.0/teams/{teamId}/members
Lists team conversation members.
POST
/v1.0/teams/{teamId}/members
Creates an #microsoft.graph.aadUserConversationMember.
Lists hosted content metadata stored on the message.
Subscriptions and Batch
Method
Endpoint
Notes
GET
/v1.0/subscriptions
Lists subscriptions.
POST
/v1.0/subscriptions
Creates a subscription. Requires changeType, notificationUrl, and resource.
GET
/v1.0/subscriptions/{id}
Gets a subscription.
PATCH
/v1.0/subscriptions/{id}
Updates a subscription.
DELETE
/v1.0/subscriptions/{id}
Deletes a subscription.
POST
/v1.0/$batch
Executes JSON batch requests against the in-process router.
Surface coverage
This emulator faithfully replicates the API surface most application code and agents exercise. Anything below the supported lines is either an intentional design choice for a fast, zero-cost local emulator (✓ By design) or a candidate for a future release (⟳ Roadmap) — never a silent inaccuracy.
Legend: ✅ fully supported · ◐ accepted (stored, not strictly enforced) · ✓ by design · ⟳ on the roadmap.
Feature
Status
Notes
@microsoft/microsoft-graph-client REST calls
Supported
Use Client.init({ baseUrl, authProvider }). Auth tokens are accepted but ignored.
Microsoft Graph v1.0 and beta prefixes
Supported
Both route to the same fake implementation.
In-memory users, teams, channels, messages, replies, tabs, apps, chats, members
Supported
State is ephemeral and resettable.
OData paging/filter/search/order/select/count
Supported
Lightweight common subset for local tests.
Delta links for team channel messages and chat messages
Supported
Returns current state plus a synthetic @odata.deltaLink.
Webhook subscription CRUD
Supported
Stored locally. No outbound HTTP notifications are sent.
Copy these into your test.env (used by the bridge sidecar flow). Tokens are Parlel's seeded test credentials — any non-empty value is accepted by the emulator, so you rarely need to change them. Swap in real credentials only when pointing at the live service in prod.env.