@teamso/teamso-mcp 0.0.0-stage → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +136 -0
- package/LICENSE +21 -0
- package/README.md +506 -2
- package/dist/client.d.ts +215 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +797 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/index.d.ts +12 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +58 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/server.d.ts +28 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +58 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/account.d.ts +4 -0
- package/dist/tools/account.d.ts.map +1 -0
- package/dist/tools/account.js +34 -0
- package/dist/tools/account.js.map +1 -0
- package/dist/tools/api.d.ts +13 -0
- package/dist/tools/api.d.ts.map +1 -0
- package/dist/tools/api.js +982 -0
- package/dist/tools/api.js.map +1 -0
- package/dist/tools/approvals.d.ts +5 -0
- package/dist/tools/approvals.d.ts.map +1 -0
- package/dist/tools/approvals.js +120 -0
- package/dist/tools/approvals.js.map +1 -0
- package/dist/tools/communication.d.ts +4 -0
- package/dist/tools/communication.d.ts.map +1 -0
- package/dist/tools/communication.js +39 -0
- package/dist/tools/communication.js.map +1 -0
- package/dist/tools/employees.d.ts +5 -0
- package/dist/tools/employees.d.ts.map +1 -0
- package/dist/tools/employees.js +113 -0
- package/dist/tools/employees.js.map +1 -0
- package/dist/tools/help.d.ts +6 -0
- package/dist/tools/help.d.ts.map +1 -0
- package/dist/tools/help.js +171 -0
- package/dist/tools/help.js.map +1 -0
- package/dist/tools/index.d.ts +86 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +118 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/leave-support.d.ts +60 -0
- package/dist/tools/leave-support.d.ts.map +1 -0
- package/dist/tools/leave-support.js +185 -0
- package/dist/tools/leave-support.js.map +1 -0
- package/dist/tools/leave.d.ts +14 -0
- package/dist/tools/leave.d.ts.map +1 -0
- package/dist/tools/leave.js +388 -0
- package/dist/tools/leave.js.map +1 -0
- package/dist/tools/payroll.d.ts +5 -0
- package/dist/tools/payroll.d.ts.map +1 -0
- package/dist/tools/payroll.js +101 -0
- package/dist/tools/payroll.js.map +1 -0
- package/dist/tools/performance.d.ts +13 -0
- package/dist/tools/performance.d.ts.map +1 -0
- package/dist/tools/performance.js +592 -0
- package/dist/tools/performance.js.map +1 -0
- package/dist/tools/schemas.d.ts +2079 -0
- package/dist/tools/schemas.d.ts.map +1 -0
- package/dist/tools/schemas.js +460 -0
- package/dist/tools/schemas.js.map +1 -0
- package/dist/tools/shared.d.ts +20 -0
- package/dist/tools/shared.d.ts.map +1 -0
- package/dist/tools/shared.js +64 -0
- package/dist/tools/shared.js.map +1 -0
- package/dist/types.d.ts +545 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/api-endpoints.d.ts +130 -0
- package/dist/utils/api-endpoints.d.ts.map +1 -0
- package/dist/utils/api-endpoints.js +459 -0
- package/dist/utils/api-endpoints.js.map +1 -0
- package/dist/utils/dates.d.ts +27 -0
- package/dist/utils/dates.d.ts.map +1 -0
- package/dist/utils/dates.js +102 -0
- package/dist/utils/dates.js.map +1 -0
- package/dist/utils/format.d.ts +8 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +26 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/help-search.d.ts +25 -0
- package/dist/utils/help-search.d.ts.map +1 -0
- package/dist/utils/help-search.js +93 -0
- package/dist/utils/help-search.js.map +1 -0
- package/dist/utils/json-schema-dialect.d.ts +12 -0
- package/dist/utils/json-schema-dialect.d.ts.map +1 -0
- package/dist/utils/json-schema-dialect.js +146 -0
- package/dist/utils/json-schema-dialect.js.map +1 -0
- package/dist/utils/results.d.ts +27 -0
- package/dist/utils/results.d.ts.map +1 -0
- package/dist/utils/results.js +88 -0
- package/dist/utils/results.js.map +1 -0
- package/dist/utils/structured.d.ts +89 -0
- package/dist/utils/structured.d.ts.map +1 -0
- package/dist/utils/structured.js +307 -0
- package/dist/utils/structured.js.map +1 -0
- package/dist/utils/text.d.ts +12 -0
- package/dist/utils/text.d.ts.map +1 -0
- package/dist/utils/text.js +46 -0
- package/dist/utils/text.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +6 -0
- package/dist/version.js.map +1 -0
- package/package.json +86 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.2.1
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- When the user types the code of an older SMS, Teamso answers `a newer code was sent`. The leave and
|
|
8
|
+
generic API tools now tell the assistant to ask for the code in the latest SMS, instead of treating
|
|
9
|
+
it as a not-found error and pointing at `path_params`.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- README for the npm package page: Teamso logo, library install from npm instead of GitHub, the
|
|
14
|
+
generic-tools section renamed to "Reaching every module" (it repeated a heading), and the release
|
|
15
|
+
steps moved to `CONTRIBUTING.md`.
|
|
16
|
+
- CI uses `actions/checkout` and `actions/setup-node` v7.
|
|
17
|
+
|
|
18
|
+
## 1.2.0
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- Generic API tools that make every Teamso module usable through MCP, always with the token owner's own
|
|
23
|
+
Teamso permissions. They are built on the API's per-user catalog (`/mcp-catalog`), which lists only the
|
|
24
|
+
endpoints the caller may call:
|
|
25
|
+
- `find_api_endpoints` (keywords, module, HTTP method, side effect, paging), `list_api_modules` and
|
|
26
|
+
`describe_api_endpoint` (parameters, body JSON Schema, response kind, SMS-code and side-effect notes,
|
|
27
|
+
example arguments).
|
|
28
|
+
- `call_api_read`: runs only `read` endpoints and sends `X-Teamso-Mcp-Intent: read`, so the API refuses
|
|
29
|
+
anything that writes. JSON results over 40,000 characters are cut with `truncated: true` and paging
|
|
30
|
+
hints; files come back as embedded resources (up to 8 MB).
|
|
31
|
+
- `call_api_write`: returns a preview (resolved request, body validated against the endpoint's JSON Schema
|
|
32
|
+
with ajv 2020-12, delete/SMS warnings, one-line summary) and runs only with `confirm: true`. Handles the
|
|
33
|
+
SMS-code flow (`always`, `conditional`, `preVerify`), plain-text bodies and multipart uploads
|
|
34
|
+
(`files`, base64, 10 MB in total). Ids the catalog does not list for the caller are refused; there are
|
|
35
|
+
no free-form URLs.
|
|
36
|
+
- `request_sms_code`: the generic SMS-code tool (`request_leave_otp` stays as the leave alias).
|
|
37
|
+
- Toolsets: `TEAMSO_TOOLSETS` / the `toolsets` option of `createMcpServer` and `registerTools`
|
|
38
|
+
(`core`, `help`, `leave`, `approvals`, `employees`, `performance`, `communication`, `payroll`, `api`;
|
|
39
|
+
default all). New exports `TOOLSETS`, `TOOLSET_NAMES`, `resolveToolsets`. `TOOL_NAMES` keeps every
|
|
40
|
+
earlier name in the same order; the six new tools are appended.
|
|
41
|
+
- `TeamsoClient`: `listApiEndpoints`, `getApiEndpoint` (cached for a minute), `listApiModules` and
|
|
42
|
+
`callApi`; `MCP_INTENT_HEADER` and `TeamsoResponseTooLargeError` exports.
|
|
43
|
+
- Server instructions explain when to use the generic tools, the preview-then-confirm rule, SMS codes and
|
|
44
|
+
files.
|
|
45
|
+
|
|
46
|
+
### Changed
|
|
47
|
+
|
|
48
|
+
- `ajv` is now a runtime dependency (request body validation).
|
|
49
|
+
|
|
50
|
+
### Fixed (found by the local end-to-end run against the real catalog)
|
|
51
|
+
|
|
52
|
+
- Catalog paths with a trailing slash (30 endpoints, e.g. `GET /document/savedQueryListByMe/`,
|
|
53
|
+
`POST /inventory/`, `GET /dashboard-shortcut/`) were refused as "invalid API path". One trailing slash
|
|
54
|
+
is now kept; empty middle segments and dot segments are still refused.
|
|
55
|
+
- Exports sent as `application/octet-stream` (payroll Excel, PDKS records, templates) now carry the type
|
|
56
|
+
of their file name (`.xlsx`, `.pdf`, `.csv`, ...), so clients can open them.
|
|
57
|
+
- `call_api_read` explains Teamso's empty-list answers (`GET_ERROR` / `ITEM_NOT_FOUND` with HTTP 200 and no
|
|
58
|
+
data, e.g. `GET /demand/list` with no demands) as "no matching records" instead of a bare failure.
|
|
59
|
+
- Server instructions map the Turkish words users say to modules ("talep" = the user's own demands, not
|
|
60
|
+
approvals; "masraf"/"harcama" = expenses; "demirbaş"/"zimmet" = inventory, ...).
|
|
61
|
+
|
|
62
|
+
### Security (review of the generic API tools)
|
|
63
|
+
|
|
64
|
+
- Generic API calls no longer follow HTTP redirects. A 3xx answer is reported as `REDIRECT_NOT_FOLLOWED`
|
|
65
|
+
instead of being fetched, so a redirect can never pull a file from another host (internal addresses
|
|
66
|
+
included) into the conversation. The specific tools are unchanged.
|
|
67
|
+
- Server instructions say that text inside Teamso records is data written by other people, never
|
|
68
|
+
instructions, and that data is changed only for what the user asked.
|
|
69
|
+
- A clear hint for Teamso's new "too many wrong SMS codes" answer: the code is cancelled and a new one is needed.
|
|
70
|
+
|
|
71
|
+
## 1.1.3
|
|
72
|
+
|
|
73
|
+
### Fixed
|
|
74
|
+
|
|
75
|
+
- `create_leave_request` said "sent for approval" even when Teamso approved the leave on the spot (no
|
|
76
|
+
approval step for the user); the message now follows the new leave's status.
|
|
77
|
+
|
|
78
|
+
### Added
|
|
79
|
+
|
|
80
|
+
- `createHelpCache()` and the `helpCache` client option: servers that create a client per request share
|
|
81
|
+
one help bundle cache instead of downloading the bundle on every help tool call.
|
|
82
|
+
|
|
83
|
+
## 1.1.2
|
|
84
|
+
|
|
85
|
+
### Added
|
|
86
|
+
|
|
87
|
+
- `TeamsoClient` option `helpPublicUrl` (stdio: `TEAMSO_HELP_PUBLIC_URL`): the public
|
|
88
|
+
site used for every help link and image in tool output. It defaults to
|
|
89
|
+
`helpBaseUrl`, which stays the address the help bundle is downloaded from, so a
|
|
90
|
+
hosted server can download the bundle from an internal mirror (e.g. a loopback
|
|
91
|
+
URL) without that address reaching users.
|
|
92
|
+
|
|
93
|
+
## 1.1.1
|
|
94
|
+
|
|
95
|
+
### Fixed
|
|
96
|
+
|
|
97
|
+
- Goal tools showed no evaluation result: `score` was read from the API's legacy
|
|
98
|
+
`score` column, which Teamso leaves empty. Goals now carry `score` (from
|
|
99
|
+
`scoreValue`), `weightedScore`, `finalScore` and `finalScoreText`; goal lists add
|
|
100
|
+
a Score column and the period score (marked "pending approval" until every goal
|
|
101
|
+
of the employee is COMPLETED).
|
|
102
|
+
|
|
103
|
+
## 1.1.0
|
|
104
|
+
|
|
105
|
+
### Added
|
|
106
|
+
|
|
107
|
+
- MCP prompts `request_leave` (optional `start`, `end`, `leave_type`, `note`;
|
|
108
|
+
walks `list_leave_types → calculate_leave_days →` confirm `→ request_leave_otp
|
|
109
|
+
→ create_leave_request`) and `review_pending_approvals` (no arguments;
|
|
110
|
+
`list_pending_approvals →` ask per request `→ approve_or_reject_leave`).
|
|
111
|
+
- `PROMPT_NAMES` and `registerPrompts` exports, also on the
|
|
112
|
+
`@teamso/teamso-mcp/prompts` subpath; `createMcpServer` registers the prompts.
|
|
113
|
+
|
|
114
|
+
### Fixed
|
|
115
|
+
|
|
116
|
+
- `list_my_leaves`, `cancel_leave_request` and `create_leave_request` now find
|
|
117
|
+
the caller's leaves: the API puts the owner in `user.id` and leaves `userId`
|
|
118
|
+
null.
|
|
119
|
+
- Goal summaries show the manager's value and the achievement.
|
|
120
|
+
|
|
121
|
+
## 1.0.0
|
|
122
|
+
|
|
123
|
+
First release.
|
|
124
|
+
|
|
125
|
+
- 28 tools: help center (3), account (1), leave (7), approvals (2), employees (2),
|
|
126
|
+
performance (10), communication (1) and payroll (2).
|
|
127
|
+
- `TeamsoClient` with personal access token auth, Teamso envelope handling
|
|
128
|
+
(HTTP 200 failures become `TeamsoApiError`) and optional trusted-proxy
|
|
129
|
+
caller-IP signing.
|
|
130
|
+
- Typed input and output schemas, annotations, `structuredContent` and
|
|
131
|
+
`nextAction` hints on every tool; JSON Schema 2020-12 on `tools/list`.
|
|
132
|
+
- Write safeguards the API does not enforce on its own: leave decisions only at
|
|
133
|
+
the caller's approval step, goals for others only for direct reports (or
|
|
134
|
+
performance admins), never `approveAndContinue`.
|
|
135
|
+
- Dates stay on Turkey wall clock; API instants are shown in `Europe/Istanbul`.
|
|
136
|
+
- Stdio binary `teamso-mcp`.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Teamso
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,507 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<img src="https://teamso.com/logo/teamso-logo.png" alt="Teamso" width="220" />
|
|
4
|
+
|
|
5
|
+
# Teamso MCP Server
|
|
6
|
+
|
|
7
|
+
**Official [MCP](https://modelcontextprotocol.io/) server for [Teamso](https://teamso.com/)**: request leave, handle approvals, find colleagues, manage performance goals, read payslips, search the Teamso help center and reach every other Teamso module through permission-checked generic API tools, from Cursor, Claude, Windsurf, and any MCP-compatible AI assistant.
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/@teamso/teamso-mcp)
|
|
10
|
+
[](https://modelcontextprotocol.io/)
|
|
11
|
+
[](./LICENSE)
|
|
12
|
+
|
|
13
|
+
[Official MCP Server](https://teamso.com/docs/teamso-mcp-server) · [Self-Hosted MCP](https://teamso.com/docs/mcp-self-hosted) · [Access Tokens](https://teamso.com/dashboard/mcp-access) · [Help Center](https://help.teamso.com/) · [Teamso](https://teamso.com/)
|
|
14
|
+
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
Local `npx` and library usage require Node.js 20 or later. The hosted MCP
|
|
20
|
+
endpoint does not require a local Node.js installation.
|
|
21
|
+
|
|
22
|
+
### 1. Create an Access Token
|
|
23
|
+
|
|
24
|
+
Sign in to Teamso and create a personal access token at
|
|
25
|
+
[teamso.com/dashboard/mcp-access](https://teamso.com/dashboard/mcp-access).
|
|
26
|
+
The token starts with `tms_pat_` and is shown only once.
|
|
27
|
+
|
|
28
|
+
### 2. Add to Your AI Assistant
|
|
29
|
+
|
|
30
|
+
**Cursor**: open MCP settings (`Cmd+Shift+P` → "Open MCP settings") and add:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"mcpServers": {
|
|
35
|
+
"teamso": {
|
|
36
|
+
"command": "npx",
|
|
37
|
+
"args": ["-y", "@teamso/teamso-mcp"],
|
|
38
|
+
"env": {
|
|
39
|
+
"TEAMSO_ACCESS_TOKEN": "tms_pat_your-token"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Claude Code:**
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
claude mcp add teamso -e TEAMSO_ACCESS_TOKEN=tms_pat_your-token -- npx -y @teamso/teamso-mcp
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Or connect to the hosted server without installing anything:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
claude mcp add --transport http teamso https://mcp.teamso.com/v1 \
|
|
56
|
+
--header "Authorization: Bearer tms_pat_your-token"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Claude Desktop**: add to `claude_desktop_config.json`:
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"mcpServers": {
|
|
64
|
+
"teamso": {
|
|
65
|
+
"type": "stdio",
|
|
66
|
+
"command": "npx",
|
|
67
|
+
"args": ["-y", "@teamso/teamso-mcp"],
|
|
68
|
+
"env": {
|
|
69
|
+
"TEAMSO_ACCESS_TOKEN": "tms_pat_your-token"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Windsurf**: add to `~/.codeium/windsurf/mcp_config.json`:
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"mcpServers": {
|
|
81
|
+
"teamso": {
|
|
82
|
+
"command": "npx",
|
|
83
|
+
"args": ["-y", "@teamso/teamso-mcp"],
|
|
84
|
+
"env": {
|
|
85
|
+
"TEAMSO_ACCESS_TOKEN": "tms_pat_your-token"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Other clients**: any client that supports Streamable HTTP can use the hosted
|
|
93
|
+
server with a bearer header:
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"mcpServers": {
|
|
98
|
+
"teamso": {
|
|
99
|
+
"url": "https://mcp.teamso.com/v1",
|
|
100
|
+
"headers": {
|
|
101
|
+
"Authorization": "Bearer tms_pat_your-token"
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Stdio-only clients can run `npx -y @teamso/teamso-mcp` with
|
|
109
|
+
`TEAMSO_ACCESS_TOKEN` in its environment.
|
|
110
|
+
|
|
111
|
+
### 3. Start Using
|
|
112
|
+
|
|
113
|
+
Ask your AI assistant:
|
|
114
|
+
|
|
115
|
+
- *"How many leave days do I have left?"*
|
|
116
|
+
- *"Request annual leave from 2 to 4 November"*
|
|
117
|
+
- *"Which leave requests are waiting for my approval?"*
|
|
118
|
+
- *"Who is Can Öztürk's manager?"*
|
|
119
|
+
- *"Show my goals for Q4 2026 and send the drafts for approval"*
|
|
120
|
+
- *"Open my September payslip"*
|
|
121
|
+
- *"Teamso'da performans hedefi nasıl girilir?"*
|
|
122
|
+
|
|
123
|
+
## Authentication
|
|
124
|
+
|
|
125
|
+
Every tool runs as the owner of the personal access token, with exactly the
|
|
126
|
+
roles and permissions that user has in Teamso. A tool the user may not use in
|
|
127
|
+
the web app fails with a clear permission message here too.
|
|
128
|
+
|
|
129
|
+
- Create, list and revoke tokens at [teamso.com/dashboard/mcp-access](https://teamso.com/dashboard/mcp-access).
|
|
130
|
+
- Tokens of deactivated users stop working immediately; revoked or expired tokens return `401`.
|
|
131
|
+
- If your company restricts Teamso to an IP allowlist, requests from `npx`
|
|
132
|
+
come from your own IP address and must be allowed.
|
|
133
|
+
- Creating or cancelling a leave request needs an SMS code, exactly like the
|
|
134
|
+
web app: `request_leave_otp` sends it, and the user reads it back to the
|
|
135
|
+
assistant. Each SMS uses company digital credit.
|
|
136
|
+
- Token management, password, security settings and API key endpoints cannot
|
|
137
|
+
be called with a personal access token.
|
|
138
|
+
- The generic API tools only list and call the endpoints the token owner's own
|
|
139
|
+
Teamso permissions allow: a user without the leave-add permission cannot add
|
|
140
|
+
leave through MCP either.
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
TEAMSO_ACCESS_TOKEN=tms_pat_your-token
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Available Tools
|
|
147
|
+
|
|
148
|
+
### Help center
|
|
149
|
+
|
|
150
|
+
| Tool | Description |
|
|
151
|
+
|------|-------------|
|
|
152
|
+
| `search_help_articles` | Search the Teamso user guides (Turkish-insensitive, Turkish suffixes stripped) by query, language, module and role |
|
|
153
|
+
| `get_help_article` | Read one guide as Markdown with steps, common problems and related articles |
|
|
154
|
+
| `list_help_modules` | Browse the modules that have guides and their article ids |
|
|
155
|
+
|
|
156
|
+
### Account
|
|
157
|
+
|
|
158
|
+
| Tool | Description |
|
|
159
|
+
|------|-------------|
|
|
160
|
+
| `get_me` | Your profile: name, email, company, department, position, manager, roles and permission codes |
|
|
161
|
+
|
|
162
|
+
### Leave
|
|
163
|
+
|
|
164
|
+
| Tool | Description |
|
|
165
|
+
|------|-------------|
|
|
166
|
+
| `list_leave_types` | Leave types you can request, with remaining days and per-type rules |
|
|
167
|
+
| `get_my_leave_balance` | Remaining leave days per type |
|
|
168
|
+
| `calculate_leave_days` | Working days, return-to-work date and Teamso's pre-check for a planned leave |
|
|
169
|
+
| `request_leave_otp` | Send the SMS code needed to create or cancel a leave request (valid 3 minutes) |
|
|
170
|
+
| `create_leave_request` | Create a leave request with the SMS code and send it for approval |
|
|
171
|
+
| `list_my_leaves` | Your leave requests with status, filterable by dates and status |
|
|
172
|
+
| `cancel_leave_request` | Cancel one of your leave requests with the SMS code |
|
|
173
|
+
|
|
174
|
+
### Approvals
|
|
175
|
+
|
|
176
|
+
| Tool | Description |
|
|
177
|
+
|------|-------------|
|
|
178
|
+
| `list_pending_approvals` | Leave requests waiting for your decision |
|
|
179
|
+
| `approve_or_reject_leave` | Approve, or reject with a reason, a leave request at your approval step |
|
|
180
|
+
|
|
181
|
+
### Employees
|
|
182
|
+
|
|
183
|
+
| Tool | Description |
|
|
184
|
+
|------|-------------|
|
|
185
|
+
| `search_employees` | Find active colleagues by name or email |
|
|
186
|
+
| `get_employee_profile` | A colleague's branch, department, position, manager and contact details |
|
|
187
|
+
|
|
188
|
+
### Performance
|
|
189
|
+
|
|
190
|
+
| Tool | Description |
|
|
191
|
+
|------|-------------|
|
|
192
|
+
| `list_performance_periods` | Periods with dates, target-entry window and evaluation scale |
|
|
193
|
+
| `list_my_goals` | Your goals in a period and whether you can add more |
|
|
194
|
+
| `list_team_goals` | Goals of the employees you manage, with what you can approve |
|
|
195
|
+
| `create_user_goal` | Create a personal goal for yourself or a direct report (performance admins: anyone) |
|
|
196
|
+
| `send_goals_to_approval` | Send your draft goals to your manager |
|
|
197
|
+
| `approve_goal` | Approve a goal waiting for you |
|
|
198
|
+
| `revise_and_approve_goal` | Change a goal's title, details, weight or target and approve it |
|
|
199
|
+
| `update_goal_actual_value` | Enter the achieved value of your goal during evaluation |
|
|
200
|
+
| `update_manager_actual_value` | Enter your assessment of an employee's goal as their manager |
|
|
201
|
+
| `approve_goal_evaluation` | Approve an employee's evaluation for a period |
|
|
202
|
+
|
|
203
|
+
### Communication
|
|
204
|
+
|
|
205
|
+
| Tool | Description |
|
|
206
|
+
|------|-------------|
|
|
207
|
+
| `list_announcements` | Latest company and shuttle announcements |
|
|
208
|
+
|
|
209
|
+
### Payroll
|
|
210
|
+
|
|
211
|
+
| Tool | Description |
|
|
212
|
+
|------|-------------|
|
|
213
|
+
| `list_my_payslips` | Your e-payslips by term with status |
|
|
214
|
+
| `get_payslip_pdf` | One payslip as an embedded `application/pdf` resource |
|
|
215
|
+
|
|
216
|
+
### Generic API tools
|
|
217
|
+
|
|
218
|
+
| Tool | Description |
|
|
219
|
+
|------|-------------|
|
|
220
|
+
| `list_api_modules` | Teamso modules with how many API endpoints you can call in each |
|
|
221
|
+
| `find_api_endpoints` | Search the endpoints you may call by keywords, module, HTTP method or side effect |
|
|
222
|
+
| `describe_api_endpoint` | Parameters, body JSON Schema, response kind, SMS-code and side-effect notes, example arguments |
|
|
223
|
+
| `call_api_read` | Run a read-only endpoint; returns JSON (long lists are cut with `truncated: true`) or a file |
|
|
224
|
+
| `call_api_write` | Preview, then (with `confirm: true`) run an endpoint that creates, changes or deletes data |
|
|
225
|
+
| `request_sms_code` | Send the SMS code an endpoint needs (`request_leave_otp` is the leave-specific alias) |
|
|
226
|
+
|
|
227
|
+
Leave chain:
|
|
228
|
+
`list_leave_types → calculate_leave_days → request_leave_otp → create_leave_request`
|
|
229
|
+
|
|
230
|
+
Approval chain:
|
|
231
|
+
`list_pending_approvals → approve_or_reject_leave`
|
|
232
|
+
|
|
233
|
+
Goal chain:
|
|
234
|
+
`list_performance_periods → list_my_goals → create_user_goal → send_goals_to_approval`
|
|
235
|
+
|
|
236
|
+
Everything else (expenses, overtime, time tracking, payroll, recruiting,
|
|
237
|
+
inventory, documents, settings...):
|
|
238
|
+
`find_api_endpoints → describe_api_endpoint → call_api_read` or
|
|
239
|
+
`call_api_write (preview) → user confirms → call_api_write confirm: true`
|
|
240
|
+
|
|
241
|
+
## Reaching every module
|
|
242
|
+
|
|
243
|
+
The specific tools above cover the most common tasks. Every other Teamso
|
|
244
|
+
module is reachable through six generic tools built on the Teamso API's
|
|
245
|
+
per-user catalog (`GET /mcp-catalog/endpoints`, `/endpoint`, `/modules`):
|
|
246
|
+
|
|
247
|
+
- **Only what you may use.** The catalog evaluates each endpoint's permission
|
|
248
|
+
rule for the token owner, so `find_api_endpoints` lists only endpoints the
|
|
249
|
+
user may call, and `describe_api_endpoint` / `call_api_*` refuse every id the
|
|
250
|
+
catalog does not list for that user. There are no free-form URLs: a call is
|
|
251
|
+
always an endpoint id (`"POST /expense-form"`) plus `path_params`, `query`
|
|
252
|
+
and `body`, and the real request still passes Teamso's own permission checks.
|
|
253
|
+
Login, password, token, security-setting, payment and SMS endpoints are never
|
|
254
|
+
listed.
|
|
255
|
+
- **Reads are read-only.** `call_api_read` only runs endpoints whose
|
|
256
|
+
`sideEffect` is `read` and sends `X-Teamso-Mcp-Intent: read`, with which the
|
|
257
|
+
API refuses anything that would write (403). `GET` endpoints that do change
|
|
258
|
+
data (`read_with_writes`) must go through `call_api_write`.
|
|
259
|
+
- **Writes preview first.** `call_api_write` without `confirm` sends nothing:
|
|
260
|
+
it returns the resolved request, the body checked against the endpoint's JSON
|
|
261
|
+
Schema (ajv, 2020-12; errors listed), delete and SMS warnings and a one-line
|
|
262
|
+
summary. The assistant shows it to the user and repeats the call with
|
|
263
|
+
`confirm: true` only after the user agrees. Invalid requests are never sent.
|
|
264
|
+
- **SMS codes.** Endpoints with `smsCodeRequired: always` (or `preVerify`) need
|
|
265
|
+
`otp_code` (`request_sms_code` sends it; the code is verified immediately
|
|
266
|
+
before the call). `conditional` endpoints are called first; when Teamso
|
|
267
|
+
answers `OTP_NOT_DONE` the given `otp_code` is verified and the call retried
|
|
268
|
+
once, otherwise the tool asks for `request_sms_code`.
|
|
269
|
+
- **Files.** File responses (PDF, Excel, CSV, images) come back as an embedded
|
|
270
|
+
resource with `mimeType` and file name, up to 8 MB; larger files fail with a
|
|
271
|
+
clear message. Multipart endpoints take `files: [{field, filename,
|
|
272
|
+
content_type, base64}]`, up to 10 files and 10 MB in total.
|
|
273
|
+
- **Large results.** JSON results above 40,000 characters are cut to the
|
|
274
|
+
items that fit, with `truncated: true` and a `truncation` object (original
|
|
275
|
+
and returned item counts, how to page). Results are never cut silently.
|
|
276
|
+
- **Errors.** Teamso failures, including HTTP 200 responses with a failure
|
|
277
|
+
`message_code`, come back as `isError` results naming the `message_code`.
|
|
278
|
+
|
|
279
|
+
```text
|
|
280
|
+
find_api_endpoints { "query": "masraf", "side_effect": "write" }
|
|
281
|
+
describe_api_endpoint { "id": "POST /expense-form/{expenseFormId}/finalize" }
|
|
282
|
+
call_api_write { "id": "POST /expense-form/{expenseFormId}/finalize", "path_params": { "expenseFormId": "…" } } → preview
|
|
283
|
+
request_sms_code {} → user reads the code
|
|
284
|
+
call_api_write { …same arguments…, "confirm": true, "otp_code": "123456" } → runs it
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Toolsets
|
|
288
|
+
|
|
289
|
+
`TEAMSO_TOOLSETS` (or the `toolsets` option of `createMcpServer`) limits the
|
|
290
|
+
tools a server offers, as a comma-separated list. Default: all tools.
|
|
291
|
+
|
|
292
|
+
| Toolset | Tools |
|
|
293
|
+
|---------|-------|
|
|
294
|
+
| `core` | `get_me` |
|
|
295
|
+
| `help` | `search_help_articles`, `get_help_article`, `list_help_modules` |
|
|
296
|
+
| `leave` | `list_leave_types`, `get_my_leave_balance`, `calculate_leave_days`, `request_leave_otp`, `create_leave_request`, `list_my_leaves`, `cancel_leave_request` |
|
|
297
|
+
| `approvals` | `list_pending_approvals`, `approve_or_reject_leave` |
|
|
298
|
+
| `employees` | `search_employees`, `get_employee_profile` |
|
|
299
|
+
| `performance` | the ten goal and evaluation tools |
|
|
300
|
+
| `communication` | `list_announcements` |
|
|
301
|
+
| `payroll` | `list_my_payslips`, `get_payslip_pdf` |
|
|
302
|
+
| `api` | `find_api_endpoints`, `list_api_modules`, `describe_api_endpoint`, `call_api_read`, `call_api_write`, `request_sms_code` |
|
|
303
|
+
|
|
304
|
+
An unknown toolset name stops the server with the list of valid names.
|
|
305
|
+
|
|
306
|
+
```json
|
|
307
|
+
"env": {
|
|
308
|
+
"TEAMSO_ACCESS_TOKEN": "tms_pat_...",
|
|
309
|
+
"TEAMSO_TOOLSETS": "core,leave,approvals,api"
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
## Prompts
|
|
314
|
+
|
|
315
|
+
The server also publishes MCP prompts: ready-made starting points that clients
|
|
316
|
+
show as slash commands or prompt pickers (`prompts/list`, `prompts/get`). A
|
|
317
|
+
prompt only steers the assistant through the tools above; every write still
|
|
318
|
+
needs the user's confirmation and, for leave requests, the SMS code.
|
|
319
|
+
|
|
320
|
+
| Prompt | Arguments | Description |
|
|
321
|
+
|--------|-----------|-------------|
|
|
322
|
+
| `request_leave` | `start`, `end`, `leave_type`, `note` (all optional) | Create a leave request: `list_leave_types → calculate_leave_days →` confirm with the user `→ request_leave_otp → create_leave_request`. Missing dates are asked for; `end` defaults to `start`, `leave_type` to annual leave |
|
|
323
|
+
| `review_pending_approvals` | none | Go through the leave requests waiting for your approval: `list_pending_approvals →` ask the user about each request `→ approve_or_reject_leave` |
|
|
324
|
+
|
|
325
|
+
Relative dates such as *"tomorrow"* / *"yarın"* are resolved in Turkey time
|
|
326
|
+
(`Europe/Istanbul`).
|
|
327
|
+
|
|
328
|
+
### LLM-friendly responses
|
|
329
|
+
|
|
330
|
+
All tools publish typed MCP input and output schemas (JSON Schema 2020-12) and
|
|
331
|
+
annotations (`readOnlyHint`, `destructiveHint`, `idempotentHint`,
|
|
332
|
+
`openWorldHint`). Successful calls return `structuredContent` for reliable
|
|
333
|
+
chaining and concise Markdown `content` for clients that only render text.
|
|
334
|
+
Failures return `isError: true` with an explanation the assistant can act on
|
|
335
|
+
(for example: ask for a new SMS code, or which permission is missing).
|
|
336
|
+
|
|
337
|
+
Teamso reports many failures with HTTP 200 and `code: 1` (for example
|
|
338
|
+
`OTP_NOT_DONE`, `ITEM_NOT_FOUND`, `CREDIT_INSUFFICIENT`). The client checks
|
|
339
|
+
`message_code` and turns those into errors, so a tool never reports success
|
|
340
|
+
for a request Teamso refused.
|
|
341
|
+
|
|
342
|
+
When the next step needs another tool, the response includes an executable
|
|
343
|
+
`nextAction`:
|
|
344
|
+
|
|
345
|
+
```json
|
|
346
|
+
{
|
|
347
|
+
"request": {
|
|
348
|
+
"leaveTypeId": "lt-annual",
|
|
349
|
+
"leaveTypeName": "Yıllık İzin",
|
|
350
|
+
"start": "2026-11-02 09:00",
|
|
351
|
+
"end": "2026-11-04 18:00",
|
|
352
|
+
"workingDays": 3,
|
|
353
|
+
"returnToWorkDate": "2026-11-05 09:00"
|
|
354
|
+
},
|
|
355
|
+
"remainingDays": 14,
|
|
356
|
+
"remainingAfterRequest": 11,
|
|
357
|
+
"canRequest": true,
|
|
358
|
+
"problems": [],
|
|
359
|
+
"nextAction": {
|
|
360
|
+
"tool": "request_leave_otp",
|
|
361
|
+
"arguments": {},
|
|
362
|
+
"reason": "Creating the request needs an SMS code. After the user confirms these days, send the code, then call create_leave_request with the same leave_type_id, start, end and the otp_code."
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
Dates are Turkey local time. Leave dates accept `yyyy-MM-dd` (the leave starts
|
|
368
|
+
at your shift start and ends at your shift end, 09:00–18:00 by default) or
|
|
369
|
+
`yyyy-MM-dd HH:mm`. Goal and filter dates are `yyyy-MM-dd`.
|
|
370
|
+
|
|
371
|
+
Write tools never skip Teamso's approval chain, and `approve_or_reject_leave`
|
|
372
|
+
only decides requests that are at your own approval step. `create_user_goal`
|
|
373
|
+
only creates goals for other people when they report to you directly, or when
|
|
374
|
+
you have the performance administrator permission.
|
|
375
|
+
|
|
376
|
+
The access token is sent only to the Teamso API. It is never written to logs or
|
|
377
|
+
error messages, and the help tools download the public help bundle without it.
|
|
378
|
+
|
|
379
|
+
## Hosted MCP Server
|
|
380
|
+
|
|
381
|
+
Teamso also provides a hosted MCP server at `https://mcp.teamso.com/v1` that
|
|
382
|
+
requires no local installation. It serves the same tools and prompts, plus
|
|
383
|
+
Teamso's content tools that run inside the Teamso API. See the
|
|
384
|
+
[MCP Server documentation](https://teamso.com/docs/teamso-mcp-server) for setup
|
|
385
|
+
instructions.
|
|
386
|
+
|
|
387
|
+
## Documentation
|
|
388
|
+
|
|
389
|
+
- [MCP Server (Hosted)](https://teamso.com/docs/teamso-mcp-server): setup guides for Cursor, Claude Code, Claude Desktop, Windsurf and other clients
|
|
390
|
+
- [Self-Hosted MCP](https://teamso.com/docs/mcp-self-hosted): run locally with npx, environment variables, library usage
|
|
391
|
+
- [Access Tokens](https://teamso.com/dashboard/mcp-access): create and revoke personal access tokens
|
|
392
|
+
- [Help Center](https://help.teamso.com/): the user guides behind the help tools
|
|
393
|
+
|
|
394
|
+
## Using as a Library
|
|
395
|
+
|
|
396
|
+
This package exports its core components for use in custom MCP servers:
|
|
397
|
+
|
|
398
|
+
```typescript
|
|
399
|
+
import { TeamsoClient } from '@teamso/teamso-mcp/client';
|
|
400
|
+
import { createMcpServer } from '@teamso/teamso-mcp/server';
|
|
401
|
+
|
|
402
|
+
const client = new TeamsoClient('tms_pat_your-token');
|
|
403
|
+
const server = createMcpServer(client);
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
A server that forwards end users' requests can sign the caller's IP so Teamso
|
|
407
|
+
applies the company IP allowlist and audit log to the real caller. The secret
|
|
408
|
+
must match the API's `security.mcp-proxy.shared-secret`:
|
|
409
|
+
|
|
410
|
+
```typescript
|
|
411
|
+
const client = new TeamsoClient(userToken, 'https://api.teamso.com/v1', {
|
|
412
|
+
trustedProxy: { clientIp: request.ip, sharedSecret: process.env.TEAMSO_MCP_PROXY_SECRET! },
|
|
413
|
+
});
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Exports
|
|
417
|
+
|
|
418
|
+
| Export | Description |
|
|
419
|
+
|--------|-------------|
|
|
420
|
+
| `createMcpServer(client, options?)` | Creates an McpServer with all 34 tools and both prompts registered; `options` sets `name`, `version`, `instructions` and `toolsets` |
|
|
421
|
+
| `TeamsoClient` | Teamso REST client (personal access token, envelope handling, optional trusted-proxy signing) |
|
|
422
|
+
| `TeamsoApiError` | Error with `status`, `messageCode`, `apiMessage` and the response `body` |
|
|
423
|
+
| `registerTools(server, client, options?)` | Register the tools (optionally only some `toolsets`) on an existing McpServer |
|
|
424
|
+
| `TOOL_NAMES` | Names of the tools this package serves, for routing other names elsewhere |
|
|
425
|
+
| `TOOLSETS`, `TOOLSET_NAMES`, `resolveToolsets(selection)` | Tool groups for `TEAMSO_TOOLSETS` and the tools a selection serves |
|
|
426
|
+
| `MCP_INTENT_HEADER` | `X-Teamso-Mcp-Intent`; with value `read` the API refuses requests that would write |
|
|
427
|
+
| `TeamsoResponseTooLargeError` | Thrown by `TeamsoClient.callApi` when a response exceeds its size limit |
|
|
428
|
+
| `registerPrompts(server)` | Register the prompts on an existing McpServer |
|
|
429
|
+
| `PROMPT_NAMES` | Names of the prompts this package serves (`request_leave`, `review_pending_approvals`) |
|
|
430
|
+
| `withJsonSchema2020_12(transport)` | Rewrites `tools/list` schemas to JSON Schema 2020-12 on any transport |
|
|
431
|
+
| `signProxyRequest(input)` | The trusted-proxy signature, for verifiers and tests |
|
|
432
|
+
| `VERSION` | Package version |
|
|
433
|
+
|
|
434
|
+
```typescript
|
|
435
|
+
// Import specific components
|
|
436
|
+
import { TeamsoClient, TeamsoApiError } from '@teamso/teamso-mcp/client';
|
|
437
|
+
import { registerTools, TOOL_NAMES } from '@teamso/teamso-mcp/tools';
|
|
438
|
+
import { registerPrompts, PROMPT_NAMES } from '@teamso/teamso-mcp/prompts';
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
## Environment Variables
|
|
442
|
+
|
|
443
|
+
| Variable | Required | Description |
|
|
444
|
+
|----------|----------|-------------|
|
|
445
|
+
| `TEAMSO_ACCESS_TOKEN` | Yes | Your personal access token (`tms_pat_...`) |
|
|
446
|
+
| `TEAMSO_API_BASE_URL` | No | Override the API base URL (default: `https://api.teamso.com/v1`) |
|
|
447
|
+
| `TEAMSO_HELP_BASE_URL` | No | Site the help articles are downloaded from (default: `https://teamso.com`) |
|
|
448
|
+
| `TEAMSO_HELP_PUBLIC_URL` | No | Public site used for help links and images in tool output (default: `TEAMSO_HELP_BASE_URL`). Set it when the download address is internal |
|
|
449
|
+
| `TEAMSO_TOOLSETS` | No | Comma-separated toolsets to serve: `core`, `help`, `leave`, `approvals`, `employees`, `performance`, `communication`, `payroll`, `api` (default: all) |
|
|
450
|
+
|
|
451
|
+
## Self-hosting from source
|
|
452
|
+
|
|
453
|
+
```bash
|
|
454
|
+
git clone https://github.com/Teamsocom/Teamso-MCP.git
|
|
455
|
+
cd Teamso-MCP
|
|
456
|
+
npm ci
|
|
457
|
+
npm run build
|
|
458
|
+
TEAMSO_ACCESS_TOKEN=tms_pat_your-token node dist/index.js
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
Point your client at the build instead of `npx`:
|
|
462
|
+
|
|
463
|
+
```json
|
|
464
|
+
{
|
|
465
|
+
"mcpServers": {
|
|
466
|
+
"teamso": {
|
|
467
|
+
"command": "node",
|
|
468
|
+
"args": ["/absolute/path/to/Teamso-MCP/dist/index.js"],
|
|
469
|
+
"env": {
|
|
470
|
+
"TEAMSO_ACCESS_TOKEN": "tms_pat_your-token"
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
To use it as a library instead, install it from npm: `npm install @teamso/teamso-mcp`.
|
|
478
|
+
|
|
479
|
+
Run the tests (mocked API, no network) with `npm test`.
|
|
480
|
+
|
|
481
|
+
## Links
|
|
482
|
+
|
|
483
|
+
- [Teamso](https://teamso.com)
|
|
484
|
+
- [MCP Server documentation](https://teamso.com/docs/teamso-mcp-server)
|
|
485
|
+
- [Self-hosted MCP documentation](https://teamso.com/docs/mcp-self-hosted)
|
|
486
|
+
- [npm package](https://www.npmjs.com/package/@teamso/teamso-mcp)
|
|
487
|
+
- [GitHub repository](https://github.com/Teamsocom/Teamso-MCP)
|
|
488
|
+
- [Changelog](./CHANGELOG.md)
|
|
489
|
+
|
|
490
|
+
## Contributing
|
|
491
|
+
|
|
492
|
+
Issues and pull requests are welcome: see [CONTRIBUTING.md](CONTRIBUTING.md). Report security problems
|
|
493
|
+
privately as described in [SECURITY.md](SECURITY.md).
|
|
494
|
+
|
|
495
|
+
## License
|
|
496
|
+
|
|
497
|
+
MIT. See [LICENSE](./LICENSE) for details.
|
|
498
|
+
|
|
499
|
+
---
|
|
500
|
+
|
|
501
|
+
<div align="center">
|
|
502
|
+
|
|
503
|
+
**Built with ❤️ by the Teamso team**
|
|
504
|
+
|
|
505
|
+
[teamso.com](https://teamso.com) · [GitHub @Teamsocom](https://github.com/Teamsocom)
|
|
506
|
+
|
|
507
|
+
</div>
|