@walkeros/mcp 4.7.2-next-1791147139360 → 4.7.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/README.md +10 -5
- package/dist/index.d.ts +28 -3
- package/dist/index.js +153 -96
- package/dist/index.js.map +1 -1
- package/dist/stdio.js +97 -40
- package/dist/stdio.js.map +1 -1
- package/package.json +4 -4
package/dist/stdio.js
CHANGED
|
@@ -826,7 +826,7 @@ var NPM_SEARCH_URL = "https://registry.npmjs.org/-/v1/search";
|
|
|
826
826
|
var JSDELIVR_BASE = "https://cdn.jsdelivr.net/npm";
|
|
827
827
|
var WALKEROS_JSON_PATH = "dist/walkerOS.json";
|
|
828
828
|
var CACHE_TTL = 5 * 60 * 1e3;
|
|
829
|
-
var CLIENT_HEADER = "walkeros-mcp/4.7.2
|
|
829
|
+
var CLIENT_HEADER = "walkeros-mcp/4.7.2";
|
|
830
830
|
function getPackageBaseUrl() {
|
|
831
831
|
return process.env.WALKEROS_APP_URL || void 0;
|
|
832
832
|
}
|
|
@@ -1432,6 +1432,21 @@ function wrapUserData(s) {
|
|
|
1432
1432
|
const neutralised = s.replace(/<\/user_data>/g, "</user_data_>");
|
|
1433
1433
|
return `<user_data>${neutralised}</user_data>`;
|
|
1434
1434
|
}
|
|
1435
|
+
var DISPLAY_TEXT_KEYS = /* @__PURE__ */ new Set([
|
|
1436
|
+
"name",
|
|
1437
|
+
"flowName",
|
|
1438
|
+
"summary"
|
|
1439
|
+
]);
|
|
1440
|
+
function wrapListedRecord(value) {
|
|
1441
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
1442
|
+
return value;
|
|
1443
|
+
const fields = Object.entries(value);
|
|
1444
|
+
const out = {};
|
|
1445
|
+
for (const [key, field] of fields) {
|
|
1446
|
+
out[key] = DISPLAY_TEXT_KEYS.has(key) && typeof field === "string" ? wrapUserData(field) : field;
|
|
1447
|
+
}
|
|
1448
|
+
return out;
|
|
1449
|
+
}
|
|
1435
1450
|
var STRUCTURAL_KEYS = /* @__PURE__ */ new Set([
|
|
1436
1451
|
"id",
|
|
1437
1452
|
"flowId",
|
|
@@ -1450,7 +1465,6 @@ var keepStructural = (key) => STRUCTURAL_KEYS.has(key);
|
|
|
1450
1465
|
function redactNestedStrings(value, opts) {
|
|
1451
1466
|
return walk(value, opts);
|
|
1452
1467
|
}
|
|
1453
|
-
var DISPLAY_NAME_KEYS = /* @__PURE__ */ new Set(["name", "flowName"]);
|
|
1454
1468
|
function redactDisplayNames(value) {
|
|
1455
1469
|
return walkDisplay(value);
|
|
1456
1470
|
}
|
|
@@ -1459,7 +1473,7 @@ function walkDisplay(value) {
|
|
|
1459
1473
|
if (value && typeof value === "object") {
|
|
1460
1474
|
const out = {};
|
|
1461
1475
|
for (const [k, v] of Object.entries(value)) {
|
|
1462
|
-
if (
|
|
1476
|
+
if (DISPLAY_TEXT_KEYS.has(k) && typeof v === "string") {
|
|
1463
1477
|
out[k] = wrapUserData(v);
|
|
1464
1478
|
} else {
|
|
1465
1479
|
out[k] = walkDisplay(v);
|
|
@@ -1666,7 +1680,7 @@ async function feedbackHandlerBody(client, input) {
|
|
|
1666
1680
|
const isAnonymous = explicitAnonymous ?? anonymous ?? true;
|
|
1667
1681
|
await client.submitFeedback(text, {
|
|
1668
1682
|
anonymous: isAnonymous,
|
|
1669
|
-
version: "4.7.2
|
|
1683
|
+
version: "4.7.2"
|
|
1670
1684
|
});
|
|
1671
1685
|
return mcpResult8({ ok: true });
|
|
1672
1686
|
} catch (error) {
|
|
@@ -1816,6 +1830,13 @@ import { z as z9 } from "zod";
|
|
|
1816
1830
|
import { mcpResult as mcpResult10, mcpError as mcpError11 } from "@walkeros/core";
|
|
1817
1831
|
var TITLE9 = "Authentication";
|
|
1818
1832
|
var DESCRIPTION8 = "Manage walkerOS authentication. Check login status, log in via the device authorization grant, or log out. No terminal or browser required, the MCP client handles the authorization URL.";
|
|
1833
|
+
var HOST_LOGIN_MESSAGE = "This connection is already authenticated by the host; no login needed.";
|
|
1834
|
+
var HOST_LOGOUT_MESSAGE = "This connection is authorized by the host, so there is no session here to log out of. To end it, disconnect walkerOS in your MCP client, or revoke it in the walkerOS app under Account, Connected apps.";
|
|
1835
|
+
var STILL_AUTHENTICATED = {
|
|
1836
|
+
config: "A newer session was stored while logging out and was kept. Call auth logout again to remove it.",
|
|
1837
|
+
env: "WALKEROS_TOKEN is still set for this server process, so calls stay authenticated. Remove it from the MCP server configuration.",
|
|
1838
|
+
host: HOST_LOGOUT_MESSAGE
|
|
1839
|
+
};
|
|
1819
1840
|
var inputSchema9 = {
|
|
1820
1841
|
action: z9.enum(["status", "login", "logout"]).describe("Authentication action to perform"),
|
|
1821
1842
|
deviceCode: z9.string().optional().describe(
|
|
@@ -1854,10 +1875,20 @@ async function authHandlerBody(client, input) {
|
|
|
1854
1875
|
const user = await client.whoami();
|
|
1855
1876
|
return mcpResult10({
|
|
1856
1877
|
authenticated: true,
|
|
1857
|
-
...fieldsOf(user)
|
|
1878
|
+
...redactDisplayNames(fieldsOf(user))
|
|
1858
1879
|
});
|
|
1859
1880
|
}
|
|
1860
1881
|
case "login": {
|
|
1882
|
+
if (client.credentialSource() === "host") {
|
|
1883
|
+
return mcpResult10(
|
|
1884
|
+
{ authenticated: true, message: HOST_LOGIN_MESSAGE },
|
|
1885
|
+
{
|
|
1886
|
+
next: [
|
|
1887
|
+
'Use auth with action "status" to see which account you are on'
|
|
1888
|
+
]
|
|
1889
|
+
}
|
|
1890
|
+
);
|
|
1891
|
+
}
|
|
1861
1892
|
if (deviceCode) {
|
|
1862
1893
|
const poll = await client.pollForToken(deviceCode, {
|
|
1863
1894
|
timeoutMs: 6e4
|
|
@@ -1902,15 +1933,23 @@ async function authHandlerBody(client, input) {
|
|
|
1902
1933
|
});
|
|
1903
1934
|
}
|
|
1904
1935
|
case "logout": {
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1936
|
+
if (client.credentialSource() === "host") {
|
|
1937
|
+
return mcpError11(new Error(HOST_LOGOUT_MESSAGE));
|
|
1938
|
+
}
|
|
1939
|
+
const { deleted, envCleared } = await client.logout();
|
|
1940
|
+
const remaining = client.credentialSource();
|
|
1941
|
+
if (remaining !== null) {
|
|
1942
|
+
return mcpResult10({
|
|
1943
|
+
loggedOut: false,
|
|
1944
|
+
message: STILL_AUTHENTICATED[remaining]
|
|
1945
|
+
});
|
|
1946
|
+
}
|
|
1908
1947
|
let message;
|
|
1909
|
-
if (deleted &&
|
|
1948
|
+
if (deleted && envCleared) {
|
|
1910
1949
|
message = "Logged out. Config removed and WALKEROS_TOKEN cleared from process environment.";
|
|
1911
1950
|
} else if (deleted) {
|
|
1912
1951
|
message = "Logged out and config removed.";
|
|
1913
|
-
} else if (
|
|
1952
|
+
} else if (envCleared) {
|
|
1914
1953
|
message = "No config found. WALKEROS_TOKEN cleared from process environment.";
|
|
1915
1954
|
} else {
|
|
1916
1955
|
message = "No config found, already logged out.";
|
|
@@ -2066,10 +2105,6 @@ var FRAME_MANAGE_REQUIREMENTS = {
|
|
|
2066
2105
|
};
|
|
2067
2106
|
|
|
2068
2107
|
// src/tools/project-manage.ts
|
|
2069
|
-
function wrapProjectName(project) {
|
|
2070
|
-
const name = stringField(project, "name");
|
|
2071
|
-
return isRecord(project) && name !== void 0 ? { ...project, name: wrapUserData(name) } : project;
|
|
2072
|
-
}
|
|
2073
2108
|
var TITLE10 = "Project Management";
|
|
2074
2109
|
var DESCRIPTION9 = "Manage walkerOS projects. List, create, update, delete projects, or set a default project for CLI operations.";
|
|
2075
2110
|
var inputSchema10 = {
|
|
@@ -2127,17 +2162,19 @@ async function projectManageHandlerBody(client, input) {
|
|
|
2127
2162
|
}
|
|
2128
2163
|
);
|
|
2129
2164
|
}
|
|
2130
|
-
|
|
2131
|
-
|
|
2165
|
+
return mcpResult11({
|
|
2166
|
+
...fieldsOf(projects),
|
|
2167
|
+
projects: items.map(wrapListedRecord)
|
|
2168
|
+
});
|
|
2132
2169
|
}
|
|
2133
2170
|
case "get": {
|
|
2134
2171
|
const project = await client.getProject({ projectId });
|
|
2135
|
-
return mcpResult11(
|
|
2172
|
+
return mcpResult11(wrapListedRecord(project));
|
|
2136
2173
|
}
|
|
2137
2174
|
case "create": {
|
|
2138
2175
|
assertParam(name, "name", "create");
|
|
2139
2176
|
const created = await client.createProject({ name });
|
|
2140
|
-
return mcpResult11(
|
|
2177
|
+
return mcpResult11(wrapListedRecord(created), {
|
|
2141
2178
|
next: [
|
|
2142
2179
|
'Use project_manage with action "set_default" to make this your active project'
|
|
2143
2180
|
]
|
|
@@ -2146,7 +2183,7 @@ async function projectManageHandlerBody(client, input) {
|
|
|
2146
2183
|
case "update": {
|
|
2147
2184
|
assertParam(name, "name", "update");
|
|
2148
2185
|
const updated = await client.updateProject({ projectId, name });
|
|
2149
|
-
return mcpResult11(
|
|
2186
|
+
return mcpResult11(wrapListedRecord(updated));
|
|
2150
2187
|
}
|
|
2151
2188
|
case "delete": {
|
|
2152
2189
|
const deleted = await client.deleteProject({ projectId });
|
|
@@ -2308,9 +2345,20 @@ function flowPageUrl(client, projectId, flowId) {
|
|
|
2308
2345
|
if (flowId === void 0) return void 0;
|
|
2309
2346
|
return links.flow({ baseUrl: client.appBaseUrl(), projectId, flowId });
|
|
2310
2347
|
}
|
|
2311
|
-
function
|
|
2312
|
-
|
|
2313
|
-
|
|
2348
|
+
function safeFlowPage(data) {
|
|
2349
|
+
if (Array.isArray(data)) return { flows: data.map(wrapListedRecord) };
|
|
2350
|
+
const flows = isRecord(data) ? data.flows : void 0;
|
|
2351
|
+
return isRecord(data) && Array.isArray(flows) ? { ...data, flows: flows.map(wrapListedRecord) } : redactDisplayNames(data);
|
|
2352
|
+
}
|
|
2353
|
+
function safeFlowGroup(group) {
|
|
2354
|
+
const safe = wrapListedRecord(group);
|
|
2355
|
+
if (!isRecord(safe)) return safe;
|
|
2356
|
+
const { project, flows } = safe;
|
|
2357
|
+
return {
|
|
2358
|
+
...safe,
|
|
2359
|
+
...project !== void 0 && { project: wrapListedRecord(project) },
|
|
2360
|
+
...Array.isArray(flows) && { flows: flows.map(wrapListedRecord) }
|
|
2361
|
+
};
|
|
2314
2362
|
}
|
|
2315
2363
|
function safeDetail(flow) {
|
|
2316
2364
|
const fields = { ...fieldsOf(flow) };
|
|
@@ -2495,9 +2543,7 @@ async function flowManageHandlerBody(client, input) {
|
|
|
2495
2543
|
cursor,
|
|
2496
2544
|
limit
|
|
2497
2545
|
});
|
|
2498
|
-
|
|
2499
|
-
const safe2 = isRecord(data2) && Array.isArray(flows) ? { ...data2, flows: flows.map(safeSummary) } : data2;
|
|
2500
|
-
return mcpResult12(safe2);
|
|
2546
|
+
return mcpResult12(safeFlowPage(data2));
|
|
2501
2547
|
}
|
|
2502
2548
|
const data = await client.listAllFlows({
|
|
2503
2549
|
sort,
|
|
@@ -2506,7 +2552,7 @@ async function flowManageHandlerBody(client, input) {
|
|
|
2506
2552
|
cursor,
|
|
2507
2553
|
limit
|
|
2508
2554
|
});
|
|
2509
|
-
const safe = Array.isArray(data) ? data.map(
|
|
2555
|
+
const safe = Array.isArray(data) ? data.map(safeFlowGroup) : redactDisplayNames(data);
|
|
2510
2556
|
return mcpResult12(
|
|
2511
2557
|
{ projects: safe },
|
|
2512
2558
|
{
|
|
@@ -3466,10 +3512,6 @@ async function resolveSessionId(client, options) {
|
|
|
3466
3512
|
);
|
|
3467
3513
|
}
|
|
3468
3514
|
}
|
|
3469
|
-
function resolveProjectId(client, projectId) {
|
|
3470
|
-
return projectId ?? client.getDefaultProject();
|
|
3471
|
-
}
|
|
3472
|
-
var NO_DEFAULT_PROJECT_ERROR2 = "No project ID given and no default project set. Pass projectId or set one with project_manage set_default.";
|
|
3473
3515
|
function createObserveSessionToolSpec(client) {
|
|
3474
3516
|
return {
|
|
3475
3517
|
name: "observe_session",
|
|
@@ -3496,9 +3538,9 @@ async function observeSessionHandlerBody(client, input) {
|
|
|
3496
3538
|
if (!flowId) {
|
|
3497
3539
|
return mcpError17(new Error("flowId is required for observe_session."));
|
|
3498
3540
|
}
|
|
3499
|
-
const resolvedProjectId =
|
|
3541
|
+
const resolvedProjectId = resolveDefaultProject(client, projectId);
|
|
3500
3542
|
if (!resolvedProjectId) {
|
|
3501
|
-
return mcpError17(new Error(
|
|
3543
|
+
return mcpError17(new Error(NO_DEFAULT_PROJECT_ERROR));
|
|
3502
3544
|
}
|
|
3503
3545
|
try {
|
|
3504
3546
|
switch (action) {
|
|
@@ -4922,7 +4964,7 @@ Every component in a flow is a **step**: sources capture events, transformers pr
|
|
|
4922
4964
|
- **Consent** gates destinations (\`config.consent\`) and individual fields (a value's \`consent\`). A mapping rule's \`consent\` is not enforced yet. Privacy-first by design.
|
|
4923
4965
|
- **Routing** uses one grammar in every chain field (\`source.before\`, \`source.next\`, \`transformer.before\`, \`transformer.next\`, \`collector.next\`, \`destination.before\`, \`destination.next\`). A route is a string ID, a sequence (\`["a", "b"]\`), or a RouteConfig: \`{ match?, next }\`, \`{ match?, one: [...] }\` (first match wins), \`{ match?, many: [...] }\` (every match becomes its own copy of the event with its own id and finishes the rest of the path on its own, never merged), or \`{ match?, stop: true }\` (ends that copy). In a sequence, a member's own \`next\` runs right after it, then the sequence continues. \`match\` reads \`{ ingest, event }\` and each route is evaluated when the event reaches it. A \`stop\` in \`collector.next\` drops the event for every destination; per-destination filtering belongs in \`destination.before\`. An array of only route configs is an implicit \`one\`. The optional \`match\` field is omitted to mean always-match (no wildcard literal).
|
|
4924
4966
|
- **Pass-through steps** are transformer entries with no \`code\` and no \`package\`. The runtime synthesizes the push for them automatically. Three flavors share this shape: a \`before\` / \`next\`-only step (named hop reusable across destinations), a \`cache\`-only step (dedup, rate-limit), and a \`mapping\`-only step (declarative event-to-event transform). A pass-through must declare at least one of \`before\`, \`next\`, \`cache\`, or \`mapping\`.
|
|
4925
|
-
- **Mapping at the transformer position** uses the same \`Mapping.Config\` shape as destinations, but the semantic is event-to-event: \`policy\` and
|
|
4967
|
+
- **Mapping at the transformer position** uses the same \`Mapping.Config\` shape as destinations, but the semantic is event-to-event: only config-level \`policy\` and a rule's \`condition\`, \`policy\`, \`name\` (rename) and \`ignore\` (drop from chain) apply. Everything that shapes a vendor payload or gates a destination is a no-op there: config-level \`consent\`, \`include\`, \`data\`, and a rule's \`consent\`, \`include\`, \`remove\`, \`batch\`, \`settings\`, \`extend\`, \`data\`, \`silent\`; validation warns about them (\`TRANSFORMER_MAPPING_NO_OP\`). A \`config.mapping\` wins over a step-level \`mapping\`.
|
|
4926
4968
|
- **Closed-schema rule on transformer entries:** known keys only. Operative keys are \`code\`, \`package\`, \`before\`, \`next\`, \`cache\`, \`mapping\`. Combined with structural keys (\`config\`, \`env\`, \`validate\`, \`disabled\`, \`id\`, etc.). Unknown top-level keys on a transformer step are errors (catches typos like \`dedup: {}\` instead of nested under \`cache\`). \`code\` + \`package\` together is a conflict.
|
|
4927
4969
|
- **Cache** memoizes step output on a configured store. Set \`cache.stop: true\` to short-circuit the chain on HIT (sources default to stop-on-HIT); in a source chain or \`collector.next\` that halts the event for all destinations. Set \`cache.namespace\` to prefix keys; omit it to write keys directly. \`CacheRule.match\` is optional, omit for always-match.
|
|
4928
4970
|
|
|
@@ -5131,7 +5173,7 @@ import {
|
|
|
5131
5173
|
updateProject,
|
|
5132
5174
|
deleteProject,
|
|
5133
5175
|
setDefaultProject,
|
|
5134
|
-
|
|
5176
|
+
resolveProjectId,
|
|
5135
5177
|
listAllFlows,
|
|
5136
5178
|
listFlows,
|
|
5137
5179
|
getFlow,
|
|
@@ -5196,11 +5238,18 @@ var HttpToolClient = class {
|
|
|
5196
5238
|
async deleteProject(options) {
|
|
5197
5239
|
return deleteProject(options);
|
|
5198
5240
|
}
|
|
5241
|
+
/** Refuses while `WALKEROS_PROJECT_ID` names another project (see the CLI). */
|
|
5199
5242
|
setDefaultProject(projectId) {
|
|
5200
5243
|
setDefaultProject(projectId);
|
|
5201
5244
|
}
|
|
5245
|
+
/**
|
|
5246
|
+
* `WALKEROS_PROJECT_ID`, then the CLI config's default, through the same
|
|
5247
|
+
* resolution the CLI's own commands use. Read here, at the door that owns
|
|
5248
|
+
* this process's environment, never in the shared tool layer: a hosted door
|
|
5249
|
+
* runs in a server process whose variables are no person's selection.
|
|
5250
|
+
*/
|
|
5202
5251
|
getDefaultProject() {
|
|
5203
|
-
return
|
|
5252
|
+
return resolveProjectId();
|
|
5204
5253
|
}
|
|
5205
5254
|
async listAllFlows(options) {
|
|
5206
5255
|
return listAllFlows(options);
|
|
@@ -5325,8 +5374,16 @@ var HttpToolClient = class {
|
|
|
5325
5374
|
credentialSource() {
|
|
5326
5375
|
return credentialSource();
|
|
5327
5376
|
}
|
|
5377
|
+
/**
|
|
5378
|
+
* Revoke and drop the stored session, then clear a `WALKEROS_TOKEN` from
|
|
5379
|
+
* this process: the local door owns its environment, so a later call in the
|
|
5380
|
+
* same session no longer authenticates with it.
|
|
5381
|
+
*/
|
|
5328
5382
|
async logout() {
|
|
5329
|
-
|
|
5383
|
+
const result = await logout();
|
|
5384
|
+
const envCleared = Boolean(process.env.WALKEROS_TOKEN);
|
|
5385
|
+
delete process.env.WALKEROS_TOKEN;
|
|
5386
|
+
return { ...result, envCleared };
|
|
5330
5387
|
}
|
|
5331
5388
|
/**
|
|
5332
5389
|
* The app this local door talks to: `WALKEROS_APP_URL`, then the CLI config
|
|
@@ -5360,7 +5417,7 @@ var HttpToolClient = class {
|
|
|
5360
5417
|
async checkContract() {
|
|
5361
5418
|
return compareContract({
|
|
5362
5419
|
baseUrl: this.appBaseUrl(),
|
|
5363
|
-
client: { type: "mcp", version: "4.7.2
|
|
5420
|
+
client: { type: "mcp", version: "4.7.2" }
|
|
5364
5421
|
});
|
|
5365
5422
|
}
|
|
5366
5423
|
/** The live public OpenAPI document of `appBaseUrl()`, without a credential. */
|
|
@@ -5571,7 +5628,7 @@ function parseJson(content) {
|
|
|
5571
5628
|
}
|
|
5572
5629
|
|
|
5573
5630
|
// src/stdio.ts
|
|
5574
|
-
setClientContext({ type: "mcp", version: "4.7.2
|
|
5631
|
+
setClientContext({ type: "mcp", version: "4.7.2" });
|
|
5575
5632
|
process.on("uncaughtException", (err) => {
|
|
5576
5633
|
const emitter = getMcpEmitterSingleton();
|
|
5577
5634
|
if (emitter) {
|
|
@@ -5591,7 +5648,7 @@ process.on("unhandledRejection", (reason) => {
|
|
|
5591
5648
|
async function main() {
|
|
5592
5649
|
const server = createWalkerOSMcpServer({
|
|
5593
5650
|
client: new HttpToolClient(),
|
|
5594
|
-
version: "4.7.2
|
|
5651
|
+
version: "4.7.2",
|
|
5595
5652
|
runtime: createLocalRuntime()
|
|
5596
5653
|
});
|
|
5597
5654
|
const transport = new StdioServerTransport();
|
|
@@ -5602,7 +5659,7 @@ main().catch(async (error) => {
|
|
|
5602
5659
|
try {
|
|
5603
5660
|
const emitter = await createMcpEmitter({
|
|
5604
5661
|
clientInfo: void 0,
|
|
5605
|
-
packageVersion: "4.7.2
|
|
5662
|
+
packageVersion: "4.7.2"
|
|
5606
5663
|
});
|
|
5607
5664
|
await emitter.emitError("startup");
|
|
5608
5665
|
} catch {
|