yarooms-mcp 1.0.0 → 1.0.2
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/dist/client.d.ts +20 -0
- package/dist/client.js +128 -0
- package/dist/client.js.map +1 -0
- package/dist/http.d.ts +2 -0
- package/dist/http.js +121 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +77 -0
- package/{src/index.ts → dist/index.js} +41 -53
- package/dist/index.js.map +1 -0
- package/dist/resources/catalogs.d.ts +3 -0
- package/dist/resources/catalogs.js +33 -0
- package/dist/resources/catalogs.js.map +1 -0
- package/dist/stdio.d.ts +2 -0
- package/{src/stdio.ts → dist/stdio.js} +8 -7
- package/dist/stdio.js.map +1 -0
- package/dist/tools/approvals.d.ts +3 -0
- package/dist/tools/approvals.js +104 -0
- package/dist/tools/approvals.js.map +1 -0
- package/dist/tools/bookings.d.ts +3 -0
- package/dist/tools/bookings.js +334 -0
- package/dist/tools/bookings.js.map +1 -0
- package/dist/tools/people.d.ts +3 -0
- package/dist/tools/people.js +184 -0
- package/dist/tools/people.js.map +1 -0
- package/dist/tools/visitors.d.ts +3 -0
- package/dist/tools/visitors.js +114 -0
- package/dist/tools/visitors.js.map +1 -0
- package/dist/tools/work-status.d.ts +3 -0
- package/dist/tools/work-status.js +77 -0
- package/dist/tools/work-status.js.map +1 -0
- package/dist/tools/workplace.d.ts +3 -0
- package/dist/tools/workplace.js +288 -0
- package/dist/tools/workplace.js.map +1 -0
- package/dist/types.d.ts +81 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +15 -2
- package/.env.example +0 -2
- package/docs/2026-04-14-001-feat-yarooms-mcp-server-plan.md +0 -599
- package/src/client.ts +0 -172
- package/src/resources/catalogs.ts +0 -40
- package/src/tools/approvals.ts +0 -115
- package/src/tools/bookings.ts +0 -351
- package/src/tools/people.ts +0 -212
- package/src/tools/visitors.ts +0 -124
- package/src/tools/work-status.ts +0 -90
- package/src/tools/workplace.ts +0 -314
- package/src/types.ts +0 -83
- package/test/client.test.ts +0 -165
- package/test/helpers.ts +0 -13
- package/test/integration/smoke.test.ts +0 -49
- package/test/resources/catalogs.test.ts +0 -49
- package/test/tools/bookings.test.ts +0 -181
- package/test/tools/visitors.test.ts +0 -110
- package/test/tools/work-status.test.ts +0 -86
- package/test/tools/workplace.test.ts +0 -113
- package/tsconfig.json +0 -16
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AccountInfo, PaginatedResponse } from './types.js';
|
|
2
|
+
export declare class YaroomsApiError extends Error {
|
|
3
|
+
statusCode?: number | undefined;
|
|
4
|
+
constructor(message: string, statusCode?: number | undefined);
|
|
5
|
+
}
|
|
6
|
+
export declare class YaroomsClient {
|
|
7
|
+
private baseUrl;
|
|
8
|
+
private apiToken;
|
|
9
|
+
constructor(baseUrl: string, apiToken: string);
|
|
10
|
+
private request;
|
|
11
|
+
get(path: string): Promise<unknown>;
|
|
12
|
+
post(path: string, body?: URLSearchParams): Promise<unknown>;
|
|
13
|
+
put(path: string, body?: URLSearchParams): Promise<unknown>;
|
|
14
|
+
del(path: string): Promise<unknown>;
|
|
15
|
+
list<T = unknown>(path: string, params?: {
|
|
16
|
+
page?: number;
|
|
17
|
+
perPage?: number;
|
|
18
|
+
}): Promise<PaginatedResponse<T>>;
|
|
19
|
+
validateToken(): Promise<AccountInfo>;
|
|
20
|
+
}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
export class YaroomsApiError extends Error {
|
|
2
|
+
statusCode;
|
|
3
|
+
constructor(message, statusCode) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.statusCode = statusCode;
|
|
6
|
+
this.name = 'YaroomsApiError';
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export class YaroomsClient {
|
|
10
|
+
baseUrl;
|
|
11
|
+
apiToken;
|
|
12
|
+
constructor(baseUrl, apiToken) {
|
|
13
|
+
this.baseUrl = baseUrl;
|
|
14
|
+
this.apiToken = apiToken;
|
|
15
|
+
// Strip trailing slash for consistent URL building
|
|
16
|
+
this.baseUrl = baseUrl.replace(/\/+$/, '');
|
|
17
|
+
}
|
|
18
|
+
async request(method, path, body) {
|
|
19
|
+
const url = `${this.baseUrl}${path}`;
|
|
20
|
+
const headers = {
|
|
21
|
+
'X-Token': this.apiToken,
|
|
22
|
+
};
|
|
23
|
+
let fetchBody;
|
|
24
|
+
if (body) {
|
|
25
|
+
headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
|
26
|
+
fetchBody = body.toString();
|
|
27
|
+
}
|
|
28
|
+
let res;
|
|
29
|
+
try {
|
|
30
|
+
res = await fetch(url, {
|
|
31
|
+
method,
|
|
32
|
+
headers,
|
|
33
|
+
body: fetchBody,
|
|
34
|
+
signal: AbortSignal.timeout(15_000),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
if (err instanceof DOMException && err.name === 'TimeoutError') {
|
|
39
|
+
throw new YaroomsApiError(`Request to YAROOMS timed out after 15s. The server may be overloaded or unreachable.`);
|
|
40
|
+
}
|
|
41
|
+
if (err instanceof TypeError) {
|
|
42
|
+
throw new YaroomsApiError(`Could not connect to ${this.baseUrl}. Check that the URL is correct and the server is reachable.`);
|
|
43
|
+
}
|
|
44
|
+
throw err;
|
|
45
|
+
}
|
|
46
|
+
if (res.status === 401 || res.status === 403) {
|
|
47
|
+
throw new YaroomsApiError(`Your YAROOMS account does not have access (${res.status}). The API token may be invalid, expired, or lack the required permissions.`, res.status);
|
|
48
|
+
}
|
|
49
|
+
if (res.status === 429) {
|
|
50
|
+
const retryAfter = res.headers.get('Retry-After');
|
|
51
|
+
throw new YaroomsApiError(`YAROOMS API rate limit exceeded. ${retryAfter ? `Retry after ${retryAfter}s.` : 'Try again in a few seconds.'}`, 429);
|
|
52
|
+
}
|
|
53
|
+
if (!res.ok) {
|
|
54
|
+
const raw = await res.text();
|
|
55
|
+
const text = raw.replace(/[^\x20-\x7E]/g, '').slice(0, 500);
|
|
56
|
+
throw new YaroomsApiError(`YAROOMS API ${method} ${path} failed (${res.status}): ${text}`, res.status);
|
|
57
|
+
}
|
|
58
|
+
let json;
|
|
59
|
+
try {
|
|
60
|
+
json = (await res.json());
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
throw new YaroomsApiError(`YAROOMS API ${method} ${path} returned non-JSON response (${res.status}). The server may be down for maintenance.`, res.status);
|
|
64
|
+
}
|
|
65
|
+
// Dual envelope handling:
|
|
66
|
+
// GET responses: {status: 1, data: <payload>} → return <payload>
|
|
67
|
+
// Error responses: {status: 0, error: "..."} → throw
|
|
68
|
+
// Mutation responses: {success: 1, message: "..."} → return as-is
|
|
69
|
+
if ('status' in json && json.status === 0) {
|
|
70
|
+
throw new YaroomsApiError(json.error || json.message || 'Unknown API error');
|
|
71
|
+
}
|
|
72
|
+
if ('data' in json)
|
|
73
|
+
return json.data;
|
|
74
|
+
return json;
|
|
75
|
+
}
|
|
76
|
+
async get(path) {
|
|
77
|
+
return this.request('GET', path);
|
|
78
|
+
}
|
|
79
|
+
async post(path, body) {
|
|
80
|
+
return this.request('POST', path, body);
|
|
81
|
+
}
|
|
82
|
+
async put(path, body) {
|
|
83
|
+
return this.request('PUT', path, body);
|
|
84
|
+
}
|
|
85
|
+
async del(path) {
|
|
86
|
+
return this.request('DELETE', path);
|
|
87
|
+
}
|
|
88
|
+
async list(path, params) {
|
|
89
|
+
const searchParams = new URLSearchParams();
|
|
90
|
+
if (params?.page)
|
|
91
|
+
searchParams.set('page', String(params.page));
|
|
92
|
+
if (params?.perPage)
|
|
93
|
+
searchParams.set('perPage', String(params.perPage));
|
|
94
|
+
const separator = path.includes('?') ? '&' : '?';
|
|
95
|
+
const fullPath = searchParams.toString() ? `${path}${separator}${searchParams}` : path;
|
|
96
|
+
const data = (await this.get(fullPath));
|
|
97
|
+
// Handle both paginated and raw array responses
|
|
98
|
+
if (Array.isArray(data)) {
|
|
99
|
+
return {
|
|
100
|
+
items: data,
|
|
101
|
+
total: data.length,
|
|
102
|
+
page: 1,
|
|
103
|
+
totalPages: 1,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
items: data.list ?? [],
|
|
108
|
+
total: data.total ?? (data.list?.length ?? 0),
|
|
109
|
+
page: data.page ?? 1,
|
|
110
|
+
totalPages: data.totalPages ?? 1,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
async validateToken() {
|
|
114
|
+
const data = (await this.get('/token'));
|
|
115
|
+
const accountId = data.account_id;
|
|
116
|
+
if (typeof accountId !== 'number' || isNaN(accountId)) {
|
|
117
|
+
throw new YaroomsApiError('Invalid token response: missing or invalid account_id');
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
account_id: accountId,
|
|
121
|
+
company: data.company,
|
|
122
|
+
admin: data.admin,
|
|
123
|
+
workday: data.workday,
|
|
124
|
+
location_id: data.location_id,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/http.d.ts
ADDED
package/dist/http.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import express from 'express';
|
|
4
|
+
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
5
|
+
import { isInitializeRequest } from '@modelcontextprotocol/sdk/types.js';
|
|
6
|
+
import createServer from './index.js';
|
|
7
|
+
const apiToken = process.env.YAROOMS_API_TOKEN;
|
|
8
|
+
const baseUrl = process.env.YAROOMS_BASE_URL;
|
|
9
|
+
const port = parseInt(process.env.PORT || '3000', 10);
|
|
10
|
+
if (!apiToken || !baseUrl) {
|
|
11
|
+
console.error('Missing required environment variables:');
|
|
12
|
+
if (!apiToken)
|
|
13
|
+
console.error(' YAROOMS_API_TOKEN - Your YAROOMS API token');
|
|
14
|
+
if (!baseUrl)
|
|
15
|
+
console.error(' YAROOMS_BASE_URL - API base URL (e.g. https://your-tenant.yarooms.com/api)');
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
const app = express();
|
|
19
|
+
app.use(express.json());
|
|
20
|
+
// Session management
|
|
21
|
+
const transports = {};
|
|
22
|
+
// MCP endpoint — handles POST (messages), GET (SSE stream), DELETE (session termination)
|
|
23
|
+
app.post('/mcp', async (req, res) => {
|
|
24
|
+
const sessionId = req.headers['mcp-session-id'];
|
|
25
|
+
try {
|
|
26
|
+
if (sessionId && transports[sessionId]) {
|
|
27
|
+
await transports[sessionId].handleRequest(req, res, req.body);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (!sessionId && isInitializeRequest(req.body)) {
|
|
31
|
+
const transport = new StreamableHTTPServerTransport({
|
|
32
|
+
sessionIdGenerator: () => randomUUID(),
|
|
33
|
+
onsessioninitialized: (id) => {
|
|
34
|
+
transports[id] = transport;
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
transport.onclose = () => {
|
|
38
|
+
const id = transport.sessionId;
|
|
39
|
+
if (id)
|
|
40
|
+
delete transports[id];
|
|
41
|
+
};
|
|
42
|
+
const server = await createServer({ config: { apiToken, baseUrl } });
|
|
43
|
+
await server.connect(transport);
|
|
44
|
+
await transport.handleRequest(req, res, req.body);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
res.status(400).json({
|
|
48
|
+
jsonrpc: '2.0',
|
|
49
|
+
error: { code: -32000, message: 'Bad Request: No valid session ID provided' },
|
|
50
|
+
id: null,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
console.error('Error handling MCP request:', error);
|
|
55
|
+
if (!res.headersSent) {
|
|
56
|
+
res.status(500).json({
|
|
57
|
+
jsonrpc: '2.0',
|
|
58
|
+
error: { code: -32603, message: 'Internal server error' },
|
|
59
|
+
id: null,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
app.get('/mcp', async (req, res) => {
|
|
65
|
+
const sessionId = req.headers['mcp-session-id'];
|
|
66
|
+
if (!sessionId || !transports[sessionId]) {
|
|
67
|
+
res.status(400).send('Invalid or missing session ID');
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
await transports[sessionId].handleRequest(req, res);
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
console.error('Error handling MCP GET:', error);
|
|
75
|
+
if (!res.headersSent) {
|
|
76
|
+
res.status(500).json({
|
|
77
|
+
jsonrpc: '2.0',
|
|
78
|
+
error: { code: -32603, message: 'Internal server error' },
|
|
79
|
+
id: null,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
app.delete('/mcp', async (req, res) => {
|
|
85
|
+
const sessionId = req.headers['mcp-session-id'];
|
|
86
|
+
if (!sessionId || !transports[sessionId]) {
|
|
87
|
+
res.status(400).send('Invalid or missing session ID');
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
await transports[sessionId].handleRequest(req, res);
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
console.error('Error handling MCP DELETE:', error);
|
|
95
|
+
if (!res.headersSent) {
|
|
96
|
+
res.status(500).json({
|
|
97
|
+
jsonrpc: '2.0',
|
|
98
|
+
error: { code: -32603, message: 'Internal server error' },
|
|
99
|
+
id: null,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
// Health check
|
|
105
|
+
app.get('/health', (_req, res) => {
|
|
106
|
+
res.json({ status: 'ok' });
|
|
107
|
+
});
|
|
108
|
+
app.listen(port, () => {
|
|
109
|
+
console.log(`YAROOMS MCP server running on http://localhost:${port}/mcp`);
|
|
110
|
+
});
|
|
111
|
+
// Graceful shutdown
|
|
112
|
+
async function shutdown() {
|
|
113
|
+
for (const id of Object.keys(transports)) {
|
|
114
|
+
await transports[id].close();
|
|
115
|
+
delete transports[id];
|
|
116
|
+
}
|
|
117
|
+
process.exit(0);
|
|
118
|
+
}
|
|
119
|
+
process.on('SIGINT', shutdown);
|
|
120
|
+
process.on('SIGTERM', shutdown);
|
|
121
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const configSchema: z.ZodObject<{
|
|
3
|
+
apiToken: z.ZodString;
|
|
4
|
+
baseUrl: z.ZodString;
|
|
5
|
+
}, z.core.$strip>;
|
|
6
|
+
type Config = z.infer<typeof configSchema>;
|
|
7
|
+
export default function createServer({ config }: {
|
|
8
|
+
config: Config;
|
|
9
|
+
}): Promise<import("@modelcontextprotocol/sdk/server").Server<{
|
|
10
|
+
method: string;
|
|
11
|
+
params?: {
|
|
12
|
+
[x: string]: unknown;
|
|
13
|
+
_meta?: {
|
|
14
|
+
[x: string]: unknown;
|
|
15
|
+
progressToken?: string | number | undefined;
|
|
16
|
+
"io.modelcontextprotocol/related-task"?: {
|
|
17
|
+
taskId: string;
|
|
18
|
+
} | undefined;
|
|
19
|
+
} | undefined;
|
|
20
|
+
} | undefined;
|
|
21
|
+
}, {
|
|
22
|
+
method: string;
|
|
23
|
+
params?: {
|
|
24
|
+
[x: string]: unknown;
|
|
25
|
+
_meta?: {
|
|
26
|
+
[x: string]: unknown;
|
|
27
|
+
progressToken?: string | number | undefined;
|
|
28
|
+
"io.modelcontextprotocol/related-task"?: {
|
|
29
|
+
taskId: string;
|
|
30
|
+
} | undefined;
|
|
31
|
+
} | undefined;
|
|
32
|
+
} | undefined;
|
|
33
|
+
}, {
|
|
34
|
+
[x: string]: unknown;
|
|
35
|
+
_meta?: {
|
|
36
|
+
[x: string]: unknown;
|
|
37
|
+
progressToken?: string | number | undefined;
|
|
38
|
+
"io.modelcontextprotocol/related-task"?: {
|
|
39
|
+
taskId: string;
|
|
40
|
+
} | undefined;
|
|
41
|
+
} | undefined;
|
|
42
|
+
}>>;
|
|
43
|
+
export declare function createSandboxServer(): import("@modelcontextprotocol/sdk/server").Server<{
|
|
44
|
+
method: string;
|
|
45
|
+
params?: {
|
|
46
|
+
[x: string]: unknown;
|
|
47
|
+
_meta?: {
|
|
48
|
+
[x: string]: unknown;
|
|
49
|
+
progressToken?: string | number | undefined;
|
|
50
|
+
"io.modelcontextprotocol/related-task"?: {
|
|
51
|
+
taskId: string;
|
|
52
|
+
} | undefined;
|
|
53
|
+
} | undefined;
|
|
54
|
+
} | undefined;
|
|
55
|
+
}, {
|
|
56
|
+
method: string;
|
|
57
|
+
params?: {
|
|
58
|
+
[x: string]: unknown;
|
|
59
|
+
_meta?: {
|
|
60
|
+
[x: string]: unknown;
|
|
61
|
+
progressToken?: string | number | undefined;
|
|
62
|
+
"io.modelcontextprotocol/related-task"?: {
|
|
63
|
+
taskId: string;
|
|
64
|
+
} | undefined;
|
|
65
|
+
} | undefined;
|
|
66
|
+
} | undefined;
|
|
67
|
+
}, {
|
|
68
|
+
[x: string]: unknown;
|
|
69
|
+
_meta?: {
|
|
70
|
+
[x: string]: unknown;
|
|
71
|
+
progressToken?: string | number | undefined;
|
|
72
|
+
"io.modelcontextprotocol/related-task"?: {
|
|
73
|
+
taskId: string;
|
|
74
|
+
} | undefined;
|
|
75
|
+
} | undefined;
|
|
76
|
+
}>;
|
|
77
|
+
export {};
|
|
@@ -8,32 +8,25 @@ import { registerVisitorTools } from './tools/visitors.js';
|
|
|
8
8
|
import { registerPeopleTools } from './tools/people.js';
|
|
9
9
|
import { registerApprovalTools } from './tools/approvals.js';
|
|
10
10
|
import { registerResources } from './resources/catalogs.js';
|
|
11
|
-
|
|
12
11
|
export const configSchema = z.object({
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
apiToken: z.string().describe('YAROOMS API token (X-Token)'),
|
|
13
|
+
baseUrl: z.string().url().refine(u => u.startsWith('https://'), { message: 'baseUrl must use HTTPS to protect the API token' }).describe('YAROOMS API base URL (e.g. https://your-tenant.yarooms.com/api)'),
|
|
15
14
|
});
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const server = new McpServer({
|
|
33
|
-
name: 'yarooms',
|
|
34
|
-
version: '1.0.0',
|
|
35
|
-
}, {
|
|
36
|
-
instructions: `YAROOMS workplace management MCP server. Connected as account #${account.account_id}${account.company ? ` (${account.company})` : ''}.
|
|
15
|
+
export default async function createServer({ config }) {
|
|
16
|
+
const client = new YaroomsClient(config.baseUrl, config.apiToken);
|
|
17
|
+
// Validate token and get account context
|
|
18
|
+
let account;
|
|
19
|
+
try {
|
|
20
|
+
account = await client.validateToken();
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
throw new Error(`YAROOMS MCP: Cannot connect to ${config.baseUrl} — ${err instanceof Error ? err.message : String(err)}. Check YAROOMS_API_TOKEN and YAROOMS_BASE_URL.`);
|
|
24
|
+
}
|
|
25
|
+
const server = new McpServer({
|
|
26
|
+
name: 'yarooms',
|
|
27
|
+
version: '1.0.0',
|
|
28
|
+
}, {
|
|
29
|
+
instructions: `YAROOMS workplace management MCP server. Connected as account #${account.account_id}${account.company ? ` (${account.company})` : ''}.
|
|
37
30
|
|
|
38
31
|
Use these tools to help users manage their workplace — book rooms and desks, check availability, set work status, and register visitors.
|
|
39
32
|
|
|
@@ -56,35 +49,30 @@ Other tips:
|
|
|
56
49
|
- Use the yarooms://work-status-options resource to discover valid status IDs before set_work_status
|
|
57
50
|
- Dates use YYYY-MM-DD format, times use HH:mm (24h) format
|
|
58
51
|
- All booking times are in the location's timezone`,
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
return server.server;
|
|
52
|
+
});
|
|
53
|
+
// Register all tools and resources
|
|
54
|
+
registerBookingTools(server, client, account.account_id, config.baseUrl);
|
|
55
|
+
registerWorkplaceTools(server, client);
|
|
56
|
+
registerWorkStatusTools(server, client, account.account_id);
|
|
57
|
+
registerVisitorTools(server, client);
|
|
58
|
+
registerPeopleTools(server, client, account.account_id, config.baseUrl);
|
|
59
|
+
registerApprovalTools(server, client);
|
|
60
|
+
registerResources(server, client);
|
|
61
|
+
return server.server;
|
|
71
62
|
}
|
|
72
|
-
|
|
73
63
|
export function createSandboxServer() {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
registerResources(server, client);
|
|
88
|
-
|
|
89
|
-
return server.server;
|
|
64
|
+
const client = new YaroomsClient('https://sandbox.yarooms.com/api', 'sandbox-token');
|
|
65
|
+
const server = new McpServer({
|
|
66
|
+
name: 'yarooms',
|
|
67
|
+
version: '1.0.0',
|
|
68
|
+
});
|
|
69
|
+
registerBookingTools(server, client, 0, 'https://sandbox.yarooms.com/api');
|
|
70
|
+
registerWorkplaceTools(server, client);
|
|
71
|
+
registerWorkStatusTools(server, client, 0);
|
|
72
|
+
registerVisitorTools(server, client);
|
|
73
|
+
registerPeopleTools(server, client, 0, 'https://sandbox.yarooms.com/api');
|
|
74
|
+
registerApprovalTools(server, client);
|
|
75
|
+
registerResources(server, client);
|
|
76
|
+
return server.server;
|
|
90
77
|
}
|
|
78
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export function registerResources(server, client) {
|
|
2
|
+
server.registerResource('work-status-options', 'yarooms://work-status-options', {
|
|
3
|
+
description: 'Available work status options (e.g., In Office, WFH, Away) with their IDs. Use these IDs with the set_work_status tool.',
|
|
4
|
+
mimeType: 'application/json',
|
|
5
|
+
}, async () => {
|
|
6
|
+
try {
|
|
7
|
+
const data = await client.get('/work-status-options');
|
|
8
|
+
const list = Array.isArray(data) ? data : (data?.list || []);
|
|
9
|
+
const options = list.map((o) => ({
|
|
10
|
+
id: o.id,
|
|
11
|
+
name: o.name,
|
|
12
|
+
color: o.color,
|
|
13
|
+
}));
|
|
14
|
+
return {
|
|
15
|
+
contents: [{
|
|
16
|
+
uri: 'yarooms://work-status-options',
|
|
17
|
+
mimeType: 'application/json',
|
|
18
|
+
text: JSON.stringify(options, null, 2),
|
|
19
|
+
}],
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
return {
|
|
24
|
+
contents: [{
|
|
25
|
+
uri: 'yarooms://work-status-options',
|
|
26
|
+
mimeType: 'application/json',
|
|
27
|
+
text: JSON.stringify({ error: `Failed to fetch work status options: ${err instanceof Error ? err.message : String(err)}` }),
|
|
28
|
+
}],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=catalogs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalogs.js","sourceRoot":"","sources":["../../src/resources/catalogs.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,iBAAiB,CAC/B,MAAiB,EACjB,MAAqB;IAErB,MAAM,CAAC,gBAAgB,CAAC,qBAAqB,EAAE,+BAA+B,EAAE;QAC9E,WAAW,EAAE,yHAAyH;QACtI,QAAQ,EAAE,kBAAkB;KAC7B,EAAE,KAAK,IAAI,EAAE;QACZ,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,sBAAsB,CACwB,CAAC;YAC7E,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;YAE7D,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAA0B,EAAE,EAAE,CAAC,CAAC;gBACxD,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,KAAK,EAAE,CAAC,CAAC,KAAK;aACf,CAAC,CAAC,CAAC;YAEJ,OAAO;gBACL,QAAQ,EAAE,CAAC;wBACT,GAAG,EAAE,+BAA+B;wBACpC,QAAQ,EAAE,kBAAkB;wBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;qBACvC,CAAC;aACH,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL,QAAQ,EAAE,CAAC;wBACT,GAAG,EAAE,+BAA+B;wBACpC,QAAQ,EAAE,kBAAkB;wBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,wCAAwC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;qBAC5H,CAAC;aACH,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/stdio.d.ts
ADDED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
1
2
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
2
3
|
import createServer from './index.js';
|
|
3
|
-
|
|
4
4
|
const apiToken = process.env.YAROOMS_API_TOKEN;
|
|
5
5
|
const baseUrl = process.env.YAROOMS_BASE_URL;
|
|
6
|
-
|
|
7
6
|
if (!apiToken || !baseUrl) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
console.error('Missing required environment variables:');
|
|
8
|
+
if (!apiToken)
|
|
9
|
+
console.error(' YAROOMS_API_TOKEN - Your YAROOMS API token');
|
|
10
|
+
if (!baseUrl)
|
|
11
|
+
console.error(' YAROOMS_BASE_URL - API base URL (e.g. https://your-tenant.yarooms.com/api)');
|
|
12
|
+
process.exit(1);
|
|
12
13
|
}
|
|
13
|
-
|
|
14
14
|
const server = await createServer({ config: { apiToken, baseUrl } });
|
|
15
15
|
const transport = new StdioServerTransport();
|
|
16
16
|
await server.connect(transport);
|
|
17
17
|
console.error('YAROOMS MCP server running on stdio');
|
|
18
|
+
//# sourceMappingURL=stdio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio.js","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,YAAY,MAAM,YAAY,CAAC;AAEtC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;AAC/C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;AAE7C,IAAI,CAAC,QAAQ,IAAI,CAAC,OAAO,EAAE,CAAC;IAC1B,OAAO,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;IACzD,IAAI,CAAC,QAAQ;QAAE,OAAO,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAC7E,IAAI,CAAC,OAAO;QAAE,OAAO,CAAC,KAAK,CAAC,+EAA+E,CAAC,CAAC;IAC7G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;AACrE,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAChC,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC"}
|