@apicircle/mcp-server 1.0.7 → 1.0.8
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/bin/mcp-server.cjs +59 -28
- package/dist/bin/mcp-server.cjs.map +1 -1
- package/dist/index.cjs +58 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -6
- package/dist/index.d.ts +20 -6
- package/dist/index.js +58 -27
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.d.cts
CHANGED
|
@@ -173,16 +173,29 @@ declare class FileBackedWorkspaceProvider implements WorkspaceProvider {
|
|
|
173
173
|
|
|
174
174
|
declare class MultiWorkspaceProvider implements Workspaces {
|
|
175
175
|
private readonly registryRoot;
|
|
176
|
-
|
|
176
|
+
/** Last-known active workspace id. Refreshed every time the lazy
|
|
177
|
+
* provider resolves; reflects what the most recent operation saw on
|
|
178
|
+
* disk, not a stale boot-time snapshot. */
|
|
177
179
|
private activeWorkspaceId;
|
|
180
|
+
/** The lazy provider tool handlers consume as `ctx.workspace`. Holds a
|
|
181
|
+
* reference back to this instance so each call updates
|
|
182
|
+
* `activeWorkspaceId` for `activeId()` callers + diagnostic logs. */
|
|
183
|
+
private readonly lazyProvider;
|
|
178
184
|
constructor(registryRoot: string);
|
|
179
185
|
/**
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
* registry
|
|
186
|
+
* Read the registry from disk so the host can log a boot banner. Does
|
|
187
|
+
* NOT cache a per-id provider — each `activeProvider()` call re-reads
|
|
188
|
+
* the registry, so a workspace switch in the desktop is picked up by
|
|
189
|
+
* the next tool call without restarting the MCP server.
|
|
183
190
|
*/
|
|
184
191
|
init(): Promise<WorkspaceRegistry>;
|
|
185
|
-
/**
|
|
192
|
+
/**
|
|
193
|
+
* The provider tool handlers see as `ctx.workspace`. Returns a lazy
|
|
194
|
+
* provider whose `read` / `apply` / `write` calls re-read
|
|
195
|
+
* `registry.json` so the right active workspace is always targeted
|
|
196
|
+
* even if the desktop switched workspaces since this MCP process
|
|
197
|
+
* started.
|
|
198
|
+
*/
|
|
186
199
|
activeProvider(): WorkspaceProvider;
|
|
187
200
|
list(): Promise<WorkspaceSummary[]>;
|
|
188
201
|
for(workspaceId: string): WorkspaceProvider;
|
|
@@ -190,7 +203,8 @@ declare class MultiWorkspaceProvider implements Workspaces {
|
|
|
190
203
|
setActive(workspaceId: string): Promise<void>;
|
|
191
204
|
/**
|
|
192
205
|
* Idempotent registry write — used by tests / tools that need to
|
|
193
|
-
* persist registry updates that didn't go through `setActive`.
|
|
206
|
+
* persist registry updates that didn't go through `setActive`. The
|
|
207
|
+
* lazy active provider picks the new id up on its next operation.
|
|
194
208
|
*/
|
|
195
209
|
writeRegistry(registry: WorkspaceRegistry): Promise<void>;
|
|
196
210
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -173,16 +173,29 @@ declare class FileBackedWorkspaceProvider implements WorkspaceProvider {
|
|
|
173
173
|
|
|
174
174
|
declare class MultiWorkspaceProvider implements Workspaces {
|
|
175
175
|
private readonly registryRoot;
|
|
176
|
-
|
|
176
|
+
/** Last-known active workspace id. Refreshed every time the lazy
|
|
177
|
+
* provider resolves; reflects what the most recent operation saw on
|
|
178
|
+
* disk, not a stale boot-time snapshot. */
|
|
177
179
|
private activeWorkspaceId;
|
|
180
|
+
/** The lazy provider tool handlers consume as `ctx.workspace`. Holds a
|
|
181
|
+
* reference back to this instance so each call updates
|
|
182
|
+
* `activeWorkspaceId` for `activeId()` callers + diagnostic logs. */
|
|
183
|
+
private readonly lazyProvider;
|
|
178
184
|
constructor(registryRoot: string);
|
|
179
185
|
/**
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
* registry
|
|
186
|
+
* Read the registry from disk so the host can log a boot banner. Does
|
|
187
|
+
* NOT cache a per-id provider — each `activeProvider()` call re-reads
|
|
188
|
+
* the registry, so a workspace switch in the desktop is picked up by
|
|
189
|
+
* the next tool call without restarting the MCP server.
|
|
183
190
|
*/
|
|
184
191
|
init(): Promise<WorkspaceRegistry>;
|
|
185
|
-
/**
|
|
192
|
+
/**
|
|
193
|
+
* The provider tool handlers see as `ctx.workspace`. Returns a lazy
|
|
194
|
+
* provider whose `read` / `apply` / `write` calls re-read
|
|
195
|
+
* `registry.json` so the right active workspace is always targeted
|
|
196
|
+
* even if the desktop switched workspaces since this MCP process
|
|
197
|
+
* started.
|
|
198
|
+
*/
|
|
186
199
|
activeProvider(): WorkspaceProvider;
|
|
187
200
|
list(): Promise<WorkspaceSummary[]>;
|
|
188
201
|
for(workspaceId: string): WorkspaceProvider;
|
|
@@ -190,7 +203,8 @@ declare class MultiWorkspaceProvider implements Workspaces {
|
|
|
190
203
|
setActive(workspaceId: string): Promise<void>;
|
|
191
204
|
/**
|
|
192
205
|
* Idempotent registry write — used by tests / tools that need to
|
|
193
|
-
* persist registry updates that didn't go through `setActive`.
|
|
206
|
+
* persist registry updates that didn't go through `setActive`. The
|
|
207
|
+
* lazy active provider picks the new id up on its next operation.
|
|
194
208
|
*/
|
|
195
209
|
writeRegistry(registry: WorkspaceRegistry): Promise<void>;
|
|
196
210
|
}
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { z } from "zod";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "@apicircle/mcp-server",
|
|
9
|
-
version: "1.0.
|
|
9
|
+
version: "1.0.8",
|
|
10
10
|
private: false,
|
|
11
11
|
type: "module",
|
|
12
12
|
description: "Model Context Protocol server exposing API Circle Studio's workspace as a tool catalog. Used by Claude Desktop, ChatGPT, Cursor, GitHub Copilot, and any other MCP-compatible AI client.",
|
|
@@ -2832,17 +2832,58 @@ import {
|
|
|
2832
2832
|
setActiveWorkspace as setActiveWorkspaceOnDisk,
|
|
2833
2833
|
workspaceDirFor
|
|
2834
2834
|
} from "@apicircle/core/workspace/registry";
|
|
2835
|
+
var LazyActiveWorkspaceProvider = class {
|
|
2836
|
+
constructor(registryRoot, onActiveResolved) {
|
|
2837
|
+
this.registryRoot = registryRoot;
|
|
2838
|
+
this.onActiveResolved = onActiveResolved;
|
|
2839
|
+
}
|
|
2840
|
+
registryRoot;
|
|
2841
|
+
onActiveResolved;
|
|
2842
|
+
async resolveActive() {
|
|
2843
|
+
const registry = await loadRegistry(this.registryRoot);
|
|
2844
|
+
const activeId = registry?.activeWorkspaceId ?? null;
|
|
2845
|
+
if (!activeId) {
|
|
2846
|
+
throw new Error(
|
|
2847
|
+
"No active workspace. Open the desktop app at least once, or run `apicircle workspaces create <name>`."
|
|
2848
|
+
);
|
|
2849
|
+
}
|
|
2850
|
+
this.onActiveResolved(activeId);
|
|
2851
|
+
return new FileBackedWorkspaceProvider(workspaceDirFor(this.registryRoot, activeId));
|
|
2852
|
+
}
|
|
2853
|
+
async read() {
|
|
2854
|
+
const provider = await this.resolveActive();
|
|
2855
|
+
return provider.read();
|
|
2856
|
+
}
|
|
2857
|
+
async apply(patch) {
|
|
2858
|
+
const provider = await this.resolveActive();
|
|
2859
|
+
return provider.apply(patch);
|
|
2860
|
+
}
|
|
2861
|
+
async write(next) {
|
|
2862
|
+
const provider = await this.resolveActive();
|
|
2863
|
+
return provider.write(next);
|
|
2864
|
+
}
|
|
2865
|
+
};
|
|
2835
2866
|
var MultiWorkspaceProvider = class {
|
|
2836
2867
|
constructor(registryRoot) {
|
|
2837
2868
|
this.registryRoot = registryRoot;
|
|
2869
|
+
this.lazyProvider = new LazyActiveWorkspaceProvider(this.registryRoot, (id) => {
|
|
2870
|
+
this.activeWorkspaceId = id;
|
|
2871
|
+
});
|
|
2838
2872
|
}
|
|
2839
2873
|
registryRoot;
|
|
2840
|
-
active
|
|
2874
|
+
/** Last-known active workspace id. Refreshed every time the lazy
|
|
2875
|
+
* provider resolves; reflects what the most recent operation saw on
|
|
2876
|
+
* disk, not a stale boot-time snapshot. */
|
|
2841
2877
|
activeWorkspaceId = null;
|
|
2878
|
+
/** The lazy provider tool handlers consume as `ctx.workspace`. Holds a
|
|
2879
|
+
* reference back to this instance so each call updates
|
|
2880
|
+
* `activeWorkspaceId` for `activeId()` callers + diagnostic logs. */
|
|
2881
|
+
lazyProvider;
|
|
2842
2882
|
/**
|
|
2843
|
-
*
|
|
2844
|
-
*
|
|
2845
|
-
* registry
|
|
2883
|
+
* Read the registry from disk so the host can log a boot banner. Does
|
|
2884
|
+
* NOT cache a per-id provider — each `activeProvider()` call re-reads
|
|
2885
|
+
* the registry, so a workspace switch in the desktop is picked up by
|
|
2886
|
+
* the next tool call without restarting the MCP server.
|
|
2846
2887
|
*/
|
|
2847
2888
|
async init() {
|
|
2848
2889
|
const registry = await loadRegistry(this.registryRoot) ?? {
|
|
@@ -2850,22 +2891,18 @@ var MultiWorkspaceProvider = class {
|
|
|
2850
2891
|
activeWorkspaceId: null,
|
|
2851
2892
|
workspaces: []
|
|
2852
2893
|
};
|
|
2853
|
-
|
|
2854
|
-
this.activeWorkspaceId = registry.activeWorkspaceId;
|
|
2855
|
-
this.active = new FileBackedWorkspaceProvider(
|
|
2856
|
-
workspaceDirFor(this.registryRoot, registry.activeWorkspaceId)
|
|
2857
|
-
);
|
|
2858
|
-
}
|
|
2894
|
+
this.activeWorkspaceId = registry.activeWorkspaceId;
|
|
2859
2895
|
return registry;
|
|
2860
2896
|
}
|
|
2861
|
-
/**
|
|
2897
|
+
/**
|
|
2898
|
+
* The provider tool handlers see as `ctx.workspace`. Returns a lazy
|
|
2899
|
+
* provider whose `read` / `apply` / `write` calls re-read
|
|
2900
|
+
* `registry.json` so the right active workspace is always targeted
|
|
2901
|
+
* even if the desktop switched workspaces since this MCP process
|
|
2902
|
+
* started.
|
|
2903
|
+
*/
|
|
2862
2904
|
activeProvider() {
|
|
2863
|
-
|
|
2864
|
-
throw new Error(
|
|
2865
|
-
"No active workspace. Open the desktop app at least once, or run `apicircle workspaces create <name>`."
|
|
2866
|
-
);
|
|
2867
|
-
}
|
|
2868
|
-
return this.active;
|
|
2905
|
+
return this.lazyProvider;
|
|
2869
2906
|
}
|
|
2870
2907
|
// ─── Workspaces interface ──────────────────────────────────────────────────
|
|
2871
2908
|
async list() {
|
|
@@ -2913,23 +2950,17 @@ var MultiWorkspaceProvider = class {
|
|
|
2913
2950
|
if (!registry || !registry.workspaces.some((w) => w.id === workspaceId)) {
|
|
2914
2951
|
throw new WorkspaceNotFoundError(workspaceId);
|
|
2915
2952
|
}
|
|
2916
|
-
|
|
2917
|
-
void next;
|
|
2953
|
+
await setActiveWorkspaceOnDisk(this.registryRoot, workspaceId);
|
|
2918
2954
|
this.activeWorkspaceId = workspaceId;
|
|
2919
|
-
this.active = new FileBackedWorkspaceProvider(workspaceDirFor(this.registryRoot, workspaceId));
|
|
2920
2955
|
}
|
|
2921
2956
|
/**
|
|
2922
2957
|
* Idempotent registry write — used by tests / tools that need to
|
|
2923
|
-
* persist registry updates that didn't go through `setActive`.
|
|
2958
|
+
* persist registry updates that didn't go through `setActive`. The
|
|
2959
|
+
* lazy active provider picks the new id up on its next operation.
|
|
2924
2960
|
*/
|
|
2925
2961
|
async writeRegistry(registry) {
|
|
2926
2962
|
await saveRegistry(this.registryRoot, registry);
|
|
2927
2963
|
this.activeWorkspaceId = registry.activeWorkspaceId;
|
|
2928
|
-
if (registry.activeWorkspaceId) {
|
|
2929
|
-
this.active = new FileBackedWorkspaceProvider(
|
|
2930
|
-
workspaceDirFor(this.registryRoot, registry.activeWorkspaceId)
|
|
2931
|
-
);
|
|
2932
|
-
}
|
|
2933
2964
|
}
|
|
2934
2965
|
};
|
|
2935
2966
|
|