@agentworkforce/mcp-workforce 0.0.0 → 3.0.3
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.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +7 -0
- package/dist/bin.js.map +1 -0
- package/dist/config.d.ts +42 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +39 -0
- package/dist/config.js.map +1 -0
- package/dist/config.test.d.ts +2 -0
- package/dist/config.test.d.ts.map +1 -0
- package/dist/config.test.js +47 -0
- package/dist/config.test.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +32 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +167 -0
- package/dist/server.js.map +1 -0
- package/dist/server.test.d.ts +2 -0
- package/dist/server.test.d.ts.map +1 -0
- package/dist/server.test.js +48 -0
- package/dist/server.test.js.map +1 -0
- package/dist/tools/integrations.d.ts +30 -0
- package/dist/tools/integrations.d.ts.map +1 -0
- package/dist/tools/integrations.js +133 -0
- package/dist/tools/integrations.js.map +1 -0
- package/dist/tools/integrations.test.d.ts +2 -0
- package/dist/tools/integrations.test.d.ts.map +1 -0
- package/dist/tools/integrations.test.js +77 -0
- package/dist/tools/integrations.test.js.map +1 -0
- package/dist/tools/memory.d.ts +36 -0
- package/dist/tools/memory.d.ts.map +1 -0
- package/dist/tools/memory.js +129 -0
- package/dist/tools/memory.js.map +1 -0
- package/dist/tools/memory.test.d.ts +2 -0
- package/dist/tools/memory.test.d.ts.map +1 -0
- package/dist/tools/memory.test.js +100 -0
- package/dist/tools/memory.test.js.map +1 -0
- package/dist/tools/workflow.d.ts +31 -0
- package/dist/tools/workflow.d.ts.map +1 -0
- package/dist/tools/workflow.js +58 -0
- package/dist/tools/workflow.js.map +1 -0
- package/dist/tools/workflow.test.d.ts +2 -0
- package/dist/tools/workflow.test.d.ts.map +1 -0
- package/dist/tools/workflow.test.js +74 -0
- package/dist/tools/workflow.test.js.map +1 -0
- package/package.json +8 -8
package/dist/bin.d.ts
ADDED
|
@@ -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
|
package/dist/bin.js.map
ADDED
|
@@ -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"}
|
package/dist/config.d.ts
ADDED
|
@@ -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 @@
|
|
|
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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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"}
|
package/dist/server.d.ts
ADDED
|
@@ -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 @@
|
|
|
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"}
|