@snokam/mcp-api 0.5.1 → 0.6.0

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.
Files changed (2) hide show
  1. package/dist/index.js +79 -14
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -12,9 +12,39 @@ import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSche
12
12
  import { fetchSpecs } from "./openapi-loader.js";
13
13
  import { getAccessToken } from "./auth.js";
14
14
  // ---------------------------------------------------------------------------
15
- // Config
15
+ // State
16
16
  // ---------------------------------------------------------------------------
17
- const ENVIRONMENT = process.env.SNOKAM_ENVIRONMENT ?? "production";
17
+ let currentEnvironment = process.env.SNOKAM_ENVIRONMENT ?? "production";
18
+ let endpoints = [];
19
+ let endpointsByTool = new Map();
20
+ async function loadEndpoints(environment) {
21
+ currentEnvironment = environment;
22
+ endpoints = await fetchSpecs(environment);
23
+ endpointsByTool = new Map();
24
+ for (const ep of endpoints) {
25
+ endpointsByTool.set(ep.toolName, ep);
26
+ }
27
+ }
28
+ // ---------------------------------------------------------------------------
29
+ // Built-in tool: SwitchEnvironment
30
+ // ---------------------------------------------------------------------------
31
+ const SWITCH_TOOL_NAME = "SwitchEnvironment";
32
+ const VALID_ENVIRONMENTS = ["production", "test"];
33
+ const switchToolDef = {
34
+ name: SWITCH_TOOL_NAME,
35
+ description: "Switch the Snokam MCP server between environments (production/test). Reloads all API specs for the new environment.",
36
+ inputSchema: {
37
+ type: "object",
38
+ properties: {
39
+ environment: {
40
+ type: "string",
41
+ enum: VALID_ENVIRONMENTS,
42
+ description: "The environment to switch to",
43
+ },
44
+ },
45
+ required: ["environment"],
46
+ },
47
+ };
18
48
  // ---------------------------------------------------------------------------
19
49
  // JSON Schema builder for tool inputs
20
50
  // ---------------------------------------------------------------------------
@@ -112,17 +142,13 @@ async function executeCall(endpoint, args) {
112
142
  // Server setup
113
143
  // ---------------------------------------------------------------------------
114
144
  async function main() {
115
- const endpoints = await fetchSpecs(ENVIRONMENT);
145
+ await loadEndpoints(currentEnvironment);
116
146
  if (endpoints.length === 0) {
117
147
  console.error("[snokam-mcp] No endpoints loaded. Ensure specs/*.json files exist.");
118
148
  }
119
- const endpointsByTool = new Map();
120
- for (const ep of endpoints) {
121
- endpointsByTool.set(ep.toolName, ep);
122
- }
123
149
  const server = new Server({
124
150
  name: "snokam",
125
- version: "0.2.0",
151
+ version: "0.3.0",
126
152
  }, {
127
153
  capabilities: {
128
154
  tools: {},
@@ -170,7 +196,7 @@ async function main() {
170
196
 
171
197
  ## Environment
172
198
 
173
- Currently connected to: **${ENVIRONMENT}**
199
+ Currently connected to: **${currentEnvironment}**
174
200
 
175
201
  ## Available Services
176
202
 
@@ -218,15 +244,54 @@ Controls: Sonos speakers, lights, YouTube queue
218
244
  });
219
245
  // List tools
220
246
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
221
- tools: endpoints.map((ep) => ({
222
- name: ep.toolName,
223
- description: ep.description || ep.summary || `${ep.method} ${ep.path}`,
224
- inputSchema: buildInputSchema(ep),
225
- })),
247
+ tools: [
248
+ switchToolDef,
249
+ ...endpoints.map((ep) => ({
250
+ name: ep.toolName,
251
+ description: ep.description || ep.summary || `${ep.method} ${ep.path}`,
252
+ inputSchema: buildInputSchema(ep),
253
+ })),
254
+ ],
226
255
  }));
227
256
  // Call tool
228
257
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
229
258
  const { name, arguments: args = {} } = request.params;
259
+ // Handle SwitchEnvironment
260
+ if (name === SWITCH_TOOL_NAME) {
261
+ const env = String(args.environment ?? "");
262
+ if (!VALID_ENVIRONMENTS.includes(env)) {
263
+ return {
264
+ content: [
265
+ {
266
+ type: "text",
267
+ text: `Invalid environment: ${env}. Must be one of: ${VALID_ENVIRONMENTS.join(", ")}`,
268
+ },
269
+ ],
270
+ isError: true,
271
+ };
272
+ }
273
+ if (env === currentEnvironment) {
274
+ return {
275
+ content: [
276
+ {
277
+ type: "text",
278
+ text: `Already connected to ${env} (${endpoints.length} endpoints)`,
279
+ },
280
+ ],
281
+ };
282
+ }
283
+ await loadEndpoints(env);
284
+ // Notify client that the tool list has changed
285
+ await server.sendToolListChanged();
286
+ return {
287
+ content: [
288
+ {
289
+ type: "text",
290
+ text: `Switched to ${env} environment. Loaded ${endpoints.length} endpoints.`,
291
+ },
292
+ ],
293
+ };
294
+ }
230
295
  const endpoint = endpointsByTool.get(name);
231
296
  if (!endpoint) {
232
297
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snokam/mcp-api",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "description": "MCP server exposing Snokam backend APIs as tools for Claude Code and other MCP clients",
5
5
  "type": "module",
6
6
  "bin": {