@agentworkforce/mcp-workforce 0.0.0 → 3.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.
Files changed (49) hide show
  1. package/dist/bin.d.ts +3 -0
  2. package/dist/bin.d.ts.map +1 -0
  3. package/dist/bin.js +7 -0
  4. package/dist/bin.js.map +1 -0
  5. package/dist/config.d.ts +42 -0
  6. package/dist/config.d.ts.map +1 -0
  7. package/dist/config.js +39 -0
  8. package/dist/config.js.map +1 -0
  9. package/dist/config.test.d.ts +2 -0
  10. package/dist/config.test.d.ts.map +1 -0
  11. package/dist/config.test.js +47 -0
  12. package/dist/config.test.js.map +1 -0
  13. package/dist/index.d.ts +6 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +6 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/server.d.ts +32 -0
  18. package/dist/server.d.ts.map +1 -0
  19. package/dist/server.js +167 -0
  20. package/dist/server.js.map +1 -0
  21. package/dist/server.test.d.ts +2 -0
  22. package/dist/server.test.d.ts.map +1 -0
  23. package/dist/server.test.js +48 -0
  24. package/dist/server.test.js.map +1 -0
  25. package/dist/tools/integrations.d.ts +30 -0
  26. package/dist/tools/integrations.d.ts.map +1 -0
  27. package/dist/tools/integrations.js +133 -0
  28. package/dist/tools/integrations.js.map +1 -0
  29. package/dist/tools/integrations.test.d.ts +2 -0
  30. package/dist/tools/integrations.test.d.ts.map +1 -0
  31. package/dist/tools/integrations.test.js +77 -0
  32. package/dist/tools/integrations.test.js.map +1 -0
  33. package/dist/tools/memory.d.ts +36 -0
  34. package/dist/tools/memory.d.ts.map +1 -0
  35. package/dist/tools/memory.js +129 -0
  36. package/dist/tools/memory.js.map +1 -0
  37. package/dist/tools/memory.test.d.ts +2 -0
  38. package/dist/tools/memory.test.d.ts.map +1 -0
  39. package/dist/tools/memory.test.js +100 -0
  40. package/dist/tools/memory.test.js.map +1 -0
  41. package/dist/tools/workflow.d.ts +31 -0
  42. package/dist/tools/workflow.d.ts.map +1 -0
  43. package/dist/tools/workflow.js +58 -0
  44. package/dist/tools/workflow.js.map +1 -0
  45. package/dist/tools/workflow.test.d.ts +2 -0
  46. package/dist/tools/workflow.test.d.ts.map +1 -0
  47. package/dist/tools/workflow.test.js +74 -0
  48. package/dist/tools/workflow.test.js.map +1 -0
  49. package/package.json +8 -8
package/dist/bin.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":""}
package/dist/bin.js ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ import { runStdioServer } from './server.js';
3
+ runStdioServer().catch((err) => {
4
+ process.stderr.write(`[workforce-mcp] fatal: ${err instanceof Error ? err.stack ?? err.message : String(err)}\n`);
5
+ process.exit(1);
6
+ });
7
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,cAAc,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IACtC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,0BAA0B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAC5F,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Resolved configuration for a running MCP-workforce server. The runtime
3
+ * sets these env vars when it spawns the harness via `ctx.harness.run`;
4
+ * a stand-alone `npx @agentworkforce/mcp-workforce` invocation reads
5
+ * them from the user's shell.
6
+ */
7
+ export interface WorkforceMcpConfig {
8
+ /** Workspace this server is bound to. Required. */
9
+ workspaceId: string;
10
+ /** Persona id the harness is currently running under. Optional. */
11
+ personaId?: string;
12
+ /** Workspace-scoped token used for workflow + cloud API calls. */
13
+ runtimeToken?: string;
14
+ /** Workforce cloud base URL. */
15
+ cloudUrl: string;
16
+ /** Supermemory API key (memory tools). */
17
+ supermemoryApiKey?: string;
18
+ /** Supermemory endpoint override. */
19
+ supermemoryEndpoint?: string;
20
+ /**
21
+ * Relayfile mount root. Integration clients read/write canonical
22
+ * JSON files under this path; Relayfile's writeback worker turns
23
+ * those file operations into the real provider API calls. Required
24
+ * for any `integration.*` tool to function.
25
+ */
26
+ relayfileMountRoot?: string;
27
+ /**
28
+ * Default writeback timeout for integration calls that block on a
29
+ * receipt (createIssue, comment, etc.). Defaults to 30s; the
30
+ * runtime overrides this via `WORKFORCE_WRITEBACK_TIMEOUT_MS` when
31
+ * a persona configures it.
32
+ */
33
+ writebackTimeoutMs: number;
34
+ }
35
+ /**
36
+ * Build the config from a snapshot of the env. `loadConfig()` reads from
37
+ * `process.env` by default; tests pass a fixture object. Returns an
38
+ * object with the workspaceId guaranteed; everything else is optional and
39
+ * tool implementations check at call time.
40
+ */
41
+ export declare function loadConfig(env?: NodeJS.ProcessEnv): WorkforceMcpConfig;
42
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gCAAgC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,0CAA0C;IAC1C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qCAAqC;IACrC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;OAKG;IACH,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAKD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,kBAAkB,CAiCnF"}
package/dist/config.js ADDED
@@ -0,0 +1,39 @@
1
+ const DEFAULT_CLOUD_URL = 'https://cloud.agentworkforce.com';
2
+ const DEFAULT_WRITEBACK_TIMEOUT_MS = 30_000;
3
+ /**
4
+ * Build the config from a snapshot of the env. `loadConfig()` reads from
5
+ * `process.env` by default; tests pass a fixture object. Returns an
6
+ * object with the workspaceId guaranteed; everything else is optional and
7
+ * tool implementations check at call time.
8
+ */
9
+ export function loadConfig(env = process.env) {
10
+ const workspaceId = (env.WORKFORCE_WORKSPACE_ID ?? '').trim();
11
+ if (!workspaceId) {
12
+ throw new Error('WORKFORCE_WORKSPACE_ID is required to start the workforce MCP server. The workforce runtime sets this automatically when spawning the harness; if you are running the server stand-alone, export it before invoking workforce-mcp.');
13
+ }
14
+ const writebackRaw = (env.WORKFORCE_WRITEBACK_TIMEOUT_MS ?? '').trim();
15
+ const writebackTimeoutMs = writebackRaw
16
+ ? Math.max(0, Number.parseInt(writebackRaw, 10) || DEFAULT_WRITEBACK_TIMEOUT_MS)
17
+ : DEFAULT_WRITEBACK_TIMEOUT_MS;
18
+ return {
19
+ workspaceId,
20
+ ...(env.WORKFORCE_PERSONA_ID?.trim() ? { personaId: env.WORKFORCE_PERSONA_ID.trim() } : {}),
21
+ ...(env.WORKFORCE_RUNTIME_TOKEN?.trim()
22
+ ? { runtimeToken: env.WORKFORCE_RUNTIME_TOKEN.trim() }
23
+ : {}),
24
+ cloudUrl: (env.WORKFORCE_CLOUD_URL?.trim() || DEFAULT_CLOUD_URL).replace(/\/$/, ''),
25
+ ...(env.SUPERMEMORY_API_KEY?.trim()
26
+ ? { supermemoryApiKey: env.SUPERMEMORY_API_KEY.trim() }
27
+ : {}),
28
+ ...(env.SUPERMEMORY_ENDPOINT?.trim()
29
+ ? { supermemoryEndpoint: env.SUPERMEMORY_ENDPOINT.trim() }
30
+ : {}),
31
+ ...(env.RELAYFILE_MOUNT_ROOT?.trim()
32
+ ? { relayfileMountRoot: env.RELAYFILE_MOUNT_ROOT.trim() }
33
+ : env.RELAYFILE_ROOT?.trim()
34
+ ? { relayfileMountRoot: env.RELAYFILE_ROOT.trim() }
35
+ : {}),
36
+ writebackTimeoutMs
37
+ };
38
+ }
39
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAmCA,MAAM,iBAAiB,GAAG,kCAAkC,CAAC;AAC7D,MAAM,4BAA4B,GAAG,MAAM,CAAC;AAE5C;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC7D,MAAM,WAAW,GAAG,CAAC,GAAG,CAAC,sBAAsB,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9D,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,oOAAoO,CACrO,CAAC;IACJ,CAAC;IAED,MAAM,YAAY,GAAG,CAAC,GAAG,CAAC,8BAA8B,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACvE,MAAM,kBAAkB,GAAG,YAAY;QACrC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,EAAE,CAAC,IAAI,4BAA4B,CAAC;QAChF,CAAC,CAAC,4BAA4B,CAAC;IAEjC,OAAO;QACL,WAAW;QACX,GAAG,CAAC,GAAG,CAAC,oBAAoB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,oBAAoB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3F,GAAG,CAAC,GAAG,CAAC,uBAAuB,EAAE,IAAI,EAAE;YACrC,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,CAAC,uBAAuB,CAAC,IAAI,EAAE,EAAE;YACtD,CAAC,CAAC,EAAE,CAAC;QACP,QAAQ,EAAE,CAAC,GAAG,CAAC,mBAAmB,EAAE,IAAI,EAAE,IAAI,iBAAiB,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;QACnF,GAAG,CAAC,GAAG,CAAC,mBAAmB,EAAE,IAAI,EAAE;YACjC,CAAC,CAAC,EAAE,iBAAiB,EAAE,GAAG,CAAC,mBAAmB,CAAC,IAAI,EAAE,EAAE;YACvD,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,GAAG,CAAC,oBAAoB,EAAE,IAAI,EAAE;YAClC,CAAC,CAAC,EAAE,mBAAmB,EAAE,GAAG,CAAC,oBAAoB,CAAC,IAAI,EAAE,EAAE;YAC1D,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,GAAG,CAAC,oBAAoB,EAAE,IAAI,EAAE;YAClC,CAAC,CAAC,EAAE,kBAAkB,EAAE,GAAG,CAAC,oBAAoB,CAAC,IAAI,EAAE,EAAE;YACzD,CAAC,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE;gBAC1B,CAAC,CAAC,EAAE,kBAAkB,EAAE,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,EAAE;gBACnD,CAAC,CAAC,EAAE,CAAC;QACT,kBAAkB;KACnB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=config.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.test.d.ts","sourceRoot":"","sources":["../src/config.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,47 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { loadConfig } from './config.js';
4
+ test('loadConfig requires WORKFORCE_WORKSPACE_ID', () => {
5
+ assert.throws(() => loadConfig({}), /WORKFORCE_WORKSPACE_ID is required/);
6
+ assert.throws(() => loadConfig({ WORKFORCE_WORKSPACE_ID: ' ' }), /WORKFORCE_WORKSPACE_ID is required/);
7
+ });
8
+ test('loadConfig trims env values and applies sensible defaults', () => {
9
+ const config = loadConfig({
10
+ WORKFORCE_WORKSPACE_ID: ' ws-demo ',
11
+ WORKFORCE_PERSONA_ID: ' reviewer ',
12
+ WORKFORCE_RUNTIME_TOKEN: ' tok '
13
+ });
14
+ assert.equal(config.workspaceId, 'ws-demo');
15
+ assert.equal(config.personaId, 'reviewer');
16
+ assert.equal(config.runtimeToken, 'tok');
17
+ assert.equal(config.cloudUrl, 'https://cloud.agentworkforce.com');
18
+ assert.equal(config.writebackTimeoutMs, 30_000);
19
+ assert.equal(config.relayfileMountRoot, undefined);
20
+ });
21
+ test('loadConfig picks up RELAYFILE_MOUNT_ROOT (and RELAYFILE_ROOT as a fallback)', () => {
22
+ const fromMountRoot = loadConfig({
23
+ WORKFORCE_WORKSPACE_ID: 'ws',
24
+ RELAYFILE_MOUNT_ROOT: ' /mnt/relayfile '
25
+ });
26
+ assert.equal(fromMountRoot.relayfileMountRoot, '/mnt/relayfile');
27
+ const fromLegacyAlias = loadConfig({
28
+ WORKFORCE_WORKSPACE_ID: 'ws',
29
+ RELAYFILE_ROOT: '/mnt/legacy'
30
+ });
31
+ assert.equal(fromLegacyAlias.relayfileMountRoot, '/mnt/legacy');
32
+ });
33
+ test('loadConfig honors WORKFORCE_WRITEBACK_TIMEOUT_MS', () => {
34
+ const config = loadConfig({
35
+ WORKFORCE_WORKSPACE_ID: 'ws',
36
+ WORKFORCE_WRITEBACK_TIMEOUT_MS: '5000'
37
+ });
38
+ assert.equal(config.writebackTimeoutMs, 5000);
39
+ });
40
+ test('loadConfig normalizes the cloudUrl by stripping a trailing slash', () => {
41
+ const config = loadConfig({
42
+ WORKFORCE_WORKSPACE_ID: 'ws',
43
+ WORKFORCE_CLOUD_URL: 'https://cloud.example.com/'
44
+ });
45
+ assert.equal(config.cloudUrl, 'https://cloud.example.com');
46
+ });
47
+ //# sourceMappingURL=config.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.test.js","sourceRoot":"","sources":["../src/config.test.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,IAAI,CAAC,4CAA4C,EAAE,GAAG,EAAE;IACtD,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,oCAAoC,CAAC,CAAC;IAC1E,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,EAAE,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAE,oCAAoC,CAAC,CAAC;AAC3G,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,2DAA2D,EAAE,GAAG,EAAE;IACrE,MAAM,MAAM,GAAG,UAAU,CAAC;QACxB,sBAAsB,EAAE,aAAa;QACrC,oBAAoB,EAAE,YAAY;QAClC,uBAAuB,EAAE,OAAO;KACjC,CAAC,CAAC;IACH,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAC5C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAC3C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IACzC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,kCAAkC,CAAC,CAAC;IAClE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;IAChD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,kBAAkB,EAAE,SAAS,CAAC,CAAC;AACrD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,6EAA6E,EAAE,GAAG,EAAE;IACvF,MAAM,aAAa,GAAG,UAAU,CAAC;QAC/B,sBAAsB,EAAE,IAAI;QAC5B,oBAAoB,EAAE,oBAAoB;KAC3C,CAAC,CAAC;IACH,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,CAAC;IAEjE,MAAM,eAAe,GAAG,UAAU,CAAC;QACjC,sBAAsB,EAAE,IAAI;QAC5B,cAAc,EAAE,aAAa;KAC9B,CAAC,CAAC;IACH,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,kBAAkB,EAAE,aAAa,CAAC,CAAC;AAClE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kDAAkD,EAAE,GAAG,EAAE;IAC5D,MAAM,MAAM,GAAG,UAAU,CAAC;QACxB,sBAAsB,EAAE,IAAI;QAC5B,8BAA8B,EAAE,MAAM;KACvC,CAAC,CAAC;IACH,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;AAChD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kEAAkE,EAAE,GAAG,EAAE;IAC5E,MAAM,MAAM,GAAG,UAAU,CAAC;QACxB,sBAAsB,EAAE,IAAI;QAC5B,mBAAmB,EAAE,4BAA4B;KAClD,CAAC,CAAC;IACH,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,2BAA2B,CAAC,CAAC;AAC7D,CAAC,CAAC,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { loadConfig, type WorkforceMcpConfig } from './config.js';
2
+ export { createWorkforceMcpServer, runStdioServer } from './server.js';
3
+ export { memorySave, memoryRecall, type MemoryItem, type MemoryRecallArgs, type MemorySaveArgs, type MemoryToolDeps } from './tools/memory.js';
4
+ export { workflowRun, workflowStatus, type WorkflowRunResult, type WorkflowStatusResult, type WorkflowToolDeps } from './tools/workflow.js';
5
+ export { dispatchIntegration, INTEGRATION_TOOL_NAMES, _resetIntegrationCache, type IntegrationToolDeps, type IntegrationToolName } from './tools/integrations.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,EACL,UAAU,EACV,YAAY,EACZ,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,WAAW,EACX,cAAc,EACd,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,sBAAsB,EACtB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACzB,MAAM,yBAAyB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ export { loadConfig } from './config.js';
2
+ export { createWorkforceMcpServer, runStdioServer } from './server.js';
3
+ export { memorySave, memoryRecall } from './tools/memory.js';
4
+ export { workflowRun, workflowStatus } from './tools/workflow.js';
5
+ export { dispatchIntegration, INTEGRATION_TOOL_NAMES, _resetIntegrationCache } from './tools/integrations.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA2B,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,EACL,UAAU,EACV,YAAY,EAKb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,WAAW,EACX,cAAc,EAIf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,sBAAsB,EAGvB,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { type WorkforceMcpConfig } from './config.js';
3
+ import { INTEGRATION_TOOL_NAMES, type IntegrationToolName } from './tools/integrations.js';
4
+ /**
5
+ * Build an `McpServer` with workforce-flavored tools registered. Exposed
6
+ * separately from the bin entry so tests can drive the server in-process
7
+ * without piping stdio.
8
+ */
9
+ export declare function createWorkforceMcpServer(config: WorkforceMcpConfig): McpServer;
10
+ /**
11
+ * Wrap a tool's return value in the MCP `CallToolResult` shape. We use
12
+ * JSON-text encoding so any client can read it; structured-output schemas
13
+ * are a follow-up if real consumers want them.
14
+ *
15
+ * Void-returning tools (e.g. `integration.github.postReview`) must still
16
+ * produce a real text payload — `JSON.stringify(undefined)` returns
17
+ * `undefined`, not a valid JSON string, so the MCP response would fail
18
+ * its content-shape check. Normalize `undefined` to a sentinel `{ ok:
19
+ * true }` so consumers see a stable response.
20
+ */
21
+ export declare function jsonResult(value: unknown): {
22
+ content: Array<{
23
+ type: 'text';
24
+ text: string;
25
+ }>;
26
+ [key: string]: unknown;
27
+ };
28
+ /** Server lifetime helper for the bin entry. */
29
+ export declare function runStdioServer(config?: WorkforceMcpConfig): Promise<void>;
30
+ /** Re-exported for callers wanting the typed integration name list. */
31
+ export { INTEGRATION_TOOL_NAMES, type IntegrationToolName };
32
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,OAAO,EAAc,KAAK,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGlE,OAAO,EAEL,sBAAsB,EACtB,KAAK,mBAAmB,EACzB,MAAM,yBAAyB,CAAC;AAIjC;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,kBAAkB,GAAG,SAAS,CAmF9E;AAwGD;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAUrH;AAED,gDAAgD;AAChD,wBAAsB,cAAc,CAAC,MAAM,GAAE,kBAAiC,GAAG,OAAO,CAAC,IAAI,CAAC,CAI7F;AAED,uEAAuE;AACvE,OAAO,EAAE,sBAAsB,EAAE,KAAK,mBAAmB,EAAE,CAAC"}
package/dist/server.js ADDED
@@ -0,0 +1,167 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { z } from 'zod';
4
+ import { loadConfig } from './config.js';
5
+ import { memoryRecall, memorySave } from './tools/memory.js';
6
+ import { workflowRun, workflowStatus } from './tools/workflow.js';
7
+ import { dispatchIntegration, INTEGRATION_TOOL_NAMES } from './tools/integrations.js';
8
+ const MEMORY_SCOPE_ENUM = z.enum(['workspace', 'user', 'global']);
9
+ /**
10
+ * Build an `McpServer` with workforce-flavored tools registered. Exposed
11
+ * separately from the bin entry so tests can drive the server in-process
12
+ * without piping stdio.
13
+ */
14
+ export function createWorkforceMcpServer(config) {
15
+ const server = new McpServer({ name: '@agentworkforce/mcp-workforce', version: '0.0.0' }, { capabilities: { tools: {} } });
16
+ // ─── workflow.* ──────────────────────────────────────────────────────
17
+ server.registerTool('workflow.run', {
18
+ title: 'Run a workforce cloud workflow',
19
+ description: 'Invoke a named workflow against the active workspace and return the run id + initial status. Long-running workflows are polled via workflow.status.',
20
+ inputSchema: {
21
+ name: z.string().min(1),
22
+ args: z.record(z.string(), z.unknown()).optional()
23
+ }
24
+ }, async (args) => {
25
+ const result = await workflowRun({ name: args.name, args: args.args }, { config });
26
+ return jsonResult(result);
27
+ });
28
+ server.registerTool('workflow.status', {
29
+ title: 'Get workflow run status',
30
+ description: 'Poll a previously-started workflow run for status, output, and error fields.',
31
+ inputSchema: {
32
+ runId: z.string().min(1)
33
+ }
34
+ }, async (args) => {
35
+ const result = await workflowStatus({ runId: args.runId }, { config });
36
+ return jsonResult(result);
37
+ });
38
+ // ─── memory.* ────────────────────────────────────────────────────────
39
+ server.registerTool('memory.save', {
40
+ title: 'Save a memory entry',
41
+ description: 'Persist a memory entry for the active workspace. Scope is one of workspace (default) / user / global, matching @agentworkforce/persona-kit\'s PersonaMemoryScope. Tags are deduped; workspace/scope tags are added automatically.',
42
+ inputSchema: {
43
+ content: z.string().min(1),
44
+ tags: z.array(z.string()).optional(),
45
+ scope: MEMORY_SCOPE_ENUM.optional()
46
+ }
47
+ }, async (args) => {
48
+ const result = await memorySave(args, { config });
49
+ return jsonResult(result);
50
+ });
51
+ server.registerTool('memory.recall', {
52
+ title: 'Search memory',
53
+ description: 'Semantic search over the workspace memory bag. Returns up to `limit` items (default 5, max 50).',
54
+ inputSchema: {
55
+ query: z.string().min(1),
56
+ limit: z.number().int().min(1).max(50).optional()
57
+ }
58
+ }, async (args) => {
59
+ const result = await memoryRecall(args, { config });
60
+ return jsonResult(result);
61
+ });
62
+ // ─── integration.* ───────────────────────────────────────────────────
63
+ // We register a typed schema per integration method instead of a single
64
+ // generic dispatcher so the MCP client gets useful tool descriptions
65
+ // and parameter hints. The runtime delegate is a thin wrapper that
66
+ // dispatches to the per-provider client.
67
+ registerGithubTools(server, config);
68
+ return server;
69
+ }
70
+ function registerGithubTools(server, config) {
71
+ const targetSchema = {
72
+ target: z.object({
73
+ owner: z.string().min(1),
74
+ repo: z.string().min(1),
75
+ number: z.number().int().positive()
76
+ })
77
+ };
78
+ const repoCoordsSchema = {
79
+ owner: z.string().min(1),
80
+ repo: z.string().min(1)
81
+ };
82
+ server.registerTool('integration.github.comment', {
83
+ title: 'Comment on a GitHub issue or PR',
84
+ description: 'Posts a comment on the target issue/PR. Returns the comment URL.',
85
+ inputSchema: {
86
+ ...targetSchema,
87
+ body: z.string().min(1)
88
+ }
89
+ }, async (args) => jsonResult(await dispatchIntegration('integration.github.comment', args, { config })));
90
+ server.registerTool('integration.github.createIssue', {
91
+ title: 'Create a GitHub issue',
92
+ description: 'Creates a new issue in the target repo. Returns { number, url }.',
93
+ inputSchema: {
94
+ ...repoCoordsSchema,
95
+ title: z.string().min(1),
96
+ body: z.string().min(1),
97
+ labels: z.array(z.string()).optional()
98
+ }
99
+ }, async (args) => jsonResult(await dispatchIntegration('integration.github.createIssue', args, { config })));
100
+ server.registerTool('integration.github.upsertIssue', {
101
+ title: 'Upsert a GitHub issue by title match',
102
+ description: 'Updates an open issue matching `matchTitle` if present, otherwise creates one. Returns { number, url, created }.',
103
+ inputSchema: {
104
+ ...repoCoordsSchema,
105
+ title: z.string().min(1),
106
+ body: z.string().min(1),
107
+ matchTitle: z.string().min(1),
108
+ labels: z.array(z.string()).optional()
109
+ }
110
+ }, async (args) => jsonResult(await dispatchIntegration('integration.github.upsertIssue', args, { config })));
111
+ server.registerTool('integration.github.getPr', {
112
+ title: 'Fetch a GitHub PR with diff',
113
+ description: 'Returns title, body, head/base refs, author, and the full unified diff via the canonical API endpoint.',
114
+ inputSchema: {
115
+ ...targetSchema
116
+ }
117
+ }, async (args) => jsonResult(await dispatchIntegration('integration.github.getPr', args, { config })));
118
+ server.registerTool('integration.github.postReview', {
119
+ title: 'Post a PR review',
120
+ description: 'Posts a review with optional inline comments. `event` is one of COMMENT, APPROVE, REQUEST_CHANGES.',
121
+ inputSchema: {
122
+ ...targetSchema,
123
+ review: z.object({
124
+ body: z.string().min(1),
125
+ event: z.enum(['COMMENT', 'APPROVE', 'REQUEST_CHANGES']),
126
+ comments: z
127
+ .array(z.object({
128
+ path: z.string().min(1),
129
+ line: z.number().int().positive(),
130
+ body: z.string().min(1)
131
+ }))
132
+ .optional()
133
+ })
134
+ }
135
+ }, async (args) => jsonResult(await dispatchIntegration('integration.github.postReview', args, { config })));
136
+ }
137
+ /**
138
+ * Wrap a tool's return value in the MCP `CallToolResult` shape. We use
139
+ * JSON-text encoding so any client can read it; structured-output schemas
140
+ * are a follow-up if real consumers want them.
141
+ *
142
+ * Void-returning tools (e.g. `integration.github.postReview`) must still
143
+ * produce a real text payload — `JSON.stringify(undefined)` returns
144
+ * `undefined`, not a valid JSON string, so the MCP response would fail
145
+ * its content-shape check. Normalize `undefined` to a sentinel `{ ok:
146
+ * true }` so consumers see a stable response.
147
+ */
148
+ export function jsonResult(value) {
149
+ const payload = value === undefined ? { ok: true } : value;
150
+ return {
151
+ content: [
152
+ {
153
+ type: 'text',
154
+ text: JSON.stringify(payload)
155
+ }
156
+ ]
157
+ };
158
+ }
159
+ /** Server lifetime helper for the bin entry. */
160
+ export async function runStdioServer(config = loadConfig()) {
161
+ const server = createWorkforceMcpServer(config);
162
+ const transport = new StdioServerTransport();
163
+ await server.connect(transport);
164
+ }
165
+ /** Re-exported for callers wanting the typed integration name list. */
166
+ export { INTEGRATION_TOOL_NAMES };
167
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=server.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.test.d.ts","sourceRoot":"","sources":["../src/server.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,48 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { createWorkforceMcpServer } from './server.js';
4
+ import { loadConfig } from './config.js';
5
+ test('jsonResult normalizes a void return so MCP text content is always valid JSON', async () => {
6
+ const { jsonResult } = await import('./server.js');
7
+ // `JSON.stringify(undefined)` is itself `undefined`, not a string — a
8
+ // CallToolResult with text:undefined fails the MCP content-shape check.
9
+ // jsonResult substitutes a sentinel so void-returning tools (e.g.
10
+ // integration.github.postReview) still emit parseable JSON.
11
+ const fromUndefined = jsonResult(undefined);
12
+ assert.equal(fromUndefined.content[0].type, 'text');
13
+ assert.equal(typeof fromUndefined.content[0].text, 'string');
14
+ assert.deepEqual(JSON.parse(fromUndefined.content[0].text), { ok: true });
15
+ // Non-void values pass through verbatim.
16
+ const fromObject = jsonResult({ runId: 'r1', status: 'pending' });
17
+ assert.deepEqual(JSON.parse(fromObject.content[0].text), {
18
+ runId: 'r1',
19
+ status: 'pending'
20
+ });
21
+ // `null` is a legitimate JSON value and should round-trip as such,
22
+ // not be coerced to the void sentinel.
23
+ const fromNull = jsonResult(null);
24
+ assert.equal(fromNull.content[0].text, 'null');
25
+ });
26
+ test('createWorkforceMcpServer registers the documented tool set', () => {
27
+ const config = loadConfig({
28
+ WORKFORCE_WORKSPACE_ID: 'ws-demo',
29
+ WORKFORCE_RUNTIME_TOKEN: 'tok',
30
+ SUPERMEMORY_API_KEY: 'sm',
31
+ RELAYFILE_MOUNT_ROOT: '/tmp/wf-mcp-server-test'
32
+ });
33
+ const server = createWorkforceMcpServer(config);
34
+ const tools = server._registeredTools ?? {};
35
+ const names = Object.keys(tools).sort();
36
+ assert.deepEqual(names, [
37
+ 'integration.github.comment',
38
+ 'integration.github.createIssue',
39
+ 'integration.github.getPr',
40
+ 'integration.github.postReview',
41
+ 'integration.github.upsertIssue',
42
+ 'memory.recall',
43
+ 'memory.save',
44
+ 'workflow.run',
45
+ 'workflow.status'
46
+ ]);
47
+ });
48
+ //# sourceMappingURL=server.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.test.js","sourceRoot":"","sources":["../src/server.test.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,IAAI,CAAC,8EAA8E,EAAE,KAAK,IAAI,EAAE;IAC9F,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IACnD,sEAAsE;IACtE,wEAAwE;IACxE,kEAAkE;IAClE,4DAA4D;IAC5D,MAAM,aAAa,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IAC5C,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACpD,MAAM,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC7D,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1E,yCAAyC;IACzC,MAAM,UAAU,GAAG,UAAU,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IAClE,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE;QACvD,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,SAAS;KAClB,CAAC,CAAC;IAEH,mEAAmE;IACnE,uCAAuC;IACvC,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AACjD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,4DAA4D,EAAE,GAAG,EAAE;IACtE,MAAM,MAAM,GAAG,UAAU,CAAC;QACxB,sBAAsB,EAAE,SAAS;QACjC,uBAAuB,EAAE,KAAK;QAC9B,mBAAmB,EAAE,IAAI;QACzB,oBAAoB,EAAE,yBAAyB;KAChD,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,wBAAwB,CAAC,MAAM,CAAC,CAAC;IAOhD,MAAM,KAAK,GAAI,MAA8B,CAAC,gBAAgB,IAAI,EAAE,CAAC;IACrE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IACxC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE;QACtB,4BAA4B;QAC5B,gCAAgC;QAChC,0BAA0B;QAC1B,+BAA+B;QAC/B,gCAAgC;QAChC,eAAe;QACf,aAAa;QACb,cAAc;QACd,iBAAiB;KAClB,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { WorkforceMcpConfig } from '../config.js';
2
+ /**
3
+ * Integration tools are flat methods of the form
4
+ * `integration.<provider>.<method>` (e.g. `integration.github.comment`).
5
+ * Each provider is wired lazily — the MCP server constructs the client
6
+ * on first call so harness invocations that never touch GitHub don't
7
+ * pay for the setup.
8
+ *
9
+ * Workforce integration clients are Relayfile-VFS-backed: tools write
10
+ * canonical JSON files inside the Relayfile mount and the writeback
11
+ * worker turns those into real provider API calls. The MCP server
12
+ * picks up the mount root from `RELAYFILE_MOUNT_ROOT` (or
13
+ * `RELAYFILE_ROOT`); the runtime sets this automatically when it
14
+ * spawns the harness via `ctx.harness.run`.
15
+ */
16
+ export interface IntegrationToolDeps {
17
+ config: WorkforceMcpConfig;
18
+ }
19
+ /**
20
+ * Top-level dispatcher. `tool` is a string like `integration.github.comment`;
21
+ * args is whatever JSON the MCP caller sent. Returns the provider client
22
+ * method's return value (or whatever JSON-safe shape it produced).
23
+ */
24
+ export declare function dispatchIntegration(tool: string, args: Record<string, unknown>, deps: IntegrationToolDeps): Promise<unknown>;
25
+ /** Static list of available tool names — used for MCP listTools discovery. */
26
+ export declare const INTEGRATION_TOOL_NAMES: readonly ["integration.github.comment", "integration.github.createIssue", "integration.github.upsertIssue", "integration.github.getPr", "integration.github.postReview"];
27
+ export type IntegrationToolName = (typeof INTEGRATION_TOOL_NAMES)[number];
28
+ /** Reset the lazy client cache. Test-only — production has one server lifetime. */
29
+ export declare function _resetIntegrationCache(): void;
30
+ //# sourceMappingURL=integrations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integrations.d.ts","sourceRoot":"","sources":["../../src/tools/integrations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAWD;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,OAAO,CAAC,CAgBlB;AAED,8EAA8E;AAC9E,eAAO,MAAM,sBAAsB,0KAMzB,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAkH1E,mFAAmF;AACnF,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C"}