@hs-x/mcp 0.2.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/CONTEXT.md ADDED
@@ -0,0 +1,36 @@
1
+ # @hs-x/mcp
2
+
3
+ ## Purpose
4
+
5
+ `@hs-x/mcp` is the public MCP server developers and coding agents use to operate HS-X projects. It mirrors CLI operations with structured tool outputs.
6
+
7
+ ## Contracts
8
+
9
+ - **Produces:** MCP JSON-RPC responses and tool result content for developer-facing HS-X operations.
10
+ - **Consumes:** Project roots and validator output from `@hs-x/validator`.
11
+ - **Depended on by:** Coding agents, local developer workflows, hosted MCP on `api.hs-x.dev/mcp`, and future dashboard/CLI parity checks.
12
+
13
+ ## Key types
14
+
15
+ - `handleMcpRequest()` — JSON-RPC request handler used by stdio and tests.
16
+ - `listMcpTools()` — stable public tool metadata.
17
+ - `callMcpTool()` — dispatches a named MCP tool.
18
+ - `McpToolResult` — text-content result envelope.
19
+
20
+ ## Common edits
21
+
22
+ - **Adding a tool.** Keep the tool name aligned with the CLI operation, define a JSON-schema input shape, return structured JSON text, and add tests.
23
+ - **Changing output.** Treat tool result JSON as a public contract for agents.
24
+ - **Adding hosted transport.** Keep transport separate from `callMcpTool()` so stdio and HTTP share behavior.
25
+
26
+ ## Gotchas
27
+
28
+ - The MCP is not HubSpot Breeze tool invocation. It is the agent-facing control surface for building and operating HS-X.
29
+ - Do not give MCP operations capabilities the CLI does not have.
30
+ - Errors should be returned as JSON-RPC errors, not embedded in success content.
31
+
32
+ ## Pointers
33
+
34
+ - `docs/hs-x-phase-1-plan.md#98-w7--surfaces-studio-mcp-dashboard-cli`
35
+ - `docs/hs-x-sdk-and-dx-spec.md#the-cli-and-the-agent-surface`
36
+ - Related packages: `hs-x`, `@hs-x/validator`, `@hs-x/control-plane`
package/README.md ADDED
@@ -0,0 +1,5 @@
1
+ # @hs-x/mcp
2
+
3
+ Public MCP server for developer-side coding agents.
4
+
5
+ Current scaffold exposes local `hsx.status` and `hsx.check` tools over a transport-independent JSON-RPC handler plus a stdio entrypoint. Additional CLI-equivalent operations should be added behind the same `callMcpTool()` dispatcher.
@@ -0,0 +1,8 @@
1
+ import type { Redacted as RedactedValue } from 'effect/Redacted';
2
+ export interface McpConfig {
3
+ readonly allowedRoots: readonly string[];
4
+ readonly sessionToken?: RedactedValue<string>;
5
+ readonly controlPlaneUrl: URL;
6
+ }
7
+ export declare function loadMcpConfig(env?: NodeJS.ProcessEnv): McpConfig;
8
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEjE,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,YAAY,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC9C,QAAQ,CAAC,eAAe,EAAE,GAAG,CAAC;CAC/B;AAiCD,wBAAgB,aAAa,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,SAAS,CAE7E"}
package/dist/config.js ADDED
@@ -0,0 +1,31 @@
1
+ import { Config, ConfigProvider, Effect, Option } from 'effect';
2
+ const DEFAULT_MCP_CONTROL_PLANE_URL = 'https://api.hs-x.dev';
3
+ const mcpConfig = Config.all({
4
+ allowedRoots: Config.string('ALLOWED_ROOTS').pipe(Config.option, Config.nested('MCP'), Config.nested('HSX')),
5
+ sessionToken: Config.redacted('SESSION_TOKEN').pipe(Config.option, Config.nested('HSX')),
6
+ controlPlaneUrl: Config.url('CONTROL_PLANE_URL').pipe(Config.withDefault(new URL(DEFAULT_MCP_CONTROL_PLANE_URL)), Config.nested('HSX')),
7
+ }).pipe(Config.map((config) => ({
8
+ allowedRoots: Option.isSome(config.allowedRoots)
9
+ ? splitAllowedRoots(config.allowedRoots.value)
10
+ : [],
11
+ ...(Option.isSome(config.sessionToken) ? { sessionToken: config.sessionToken.value } : {}),
12
+ controlPlaneUrl: config.controlPlaneUrl,
13
+ })));
14
+ function mcpConfigProvider(env = process.env) {
15
+ const values = new Map();
16
+ for (const [key, value] of Object.entries(env)) {
17
+ if (typeof value === 'string' && value.length > 0)
18
+ values.set(key, value);
19
+ }
20
+ return ConfigProvider.fromMap(values, { pathDelim: '_', seqDelim: ',' });
21
+ }
22
+ export function loadMcpConfig(env = process.env) {
23
+ return Effect.runSync(Effect.withConfigProvider(mcpConfigProvider(env))(mcpConfig));
24
+ }
25
+ function splitAllowedRoots(value) {
26
+ return value
27
+ .split(':')
28
+ .map((entry) => entry.trim())
29
+ .filter((entry) => entry.length > 0);
30
+ }
31
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAShE,MAAM,6BAA6B,GAAG,sBAAsB,CAAC;AAE7D,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAC/C,MAAM,CAAC,MAAM,EACb,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EACpB,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CACrB;IACD,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACxF,eAAe,EAAE,MAAM,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,IAAI,CACnD,MAAM,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,6BAA6B,CAAC,CAAC,EAC1D,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CACrB;CACF,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC;QAC9C,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC;QAC9C,CAAC,CAAC,EAAE;IACN,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1F,eAAe,EAAE,MAAM,CAAC,eAAe;CACxC,CAAC,CAAC,CACJ,CAAC;AAEF,SAAS,iBAAiB,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC7D,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,cAAc,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;AAC3E,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAyB,OAAO,CAAC,GAAG;IAChE,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;AACtF,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAa;IACtC,OAAO,KAAK;SACT,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;SAC5B,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACzC,CAAC"}
@@ -0,0 +1,45 @@
1
+ import type { McpConfig } from './config.js';
2
+ export declare const MCP_VERSION = "0.2.3";
3
+ export declare const MCP_PROTOCOL_VERSION = "2024-11-05";
4
+ export interface JsonRpcRequest {
5
+ readonly jsonrpc?: '2.0';
6
+ readonly id?: string | number | null;
7
+ readonly method?: string;
8
+ readonly params?: unknown;
9
+ }
10
+ export interface JsonRpcSuccess {
11
+ readonly jsonrpc: '2.0';
12
+ readonly id: string | number | null;
13
+ readonly result: unknown;
14
+ }
15
+ export interface JsonRpcFailure {
16
+ readonly jsonrpc: '2.0';
17
+ readonly id: string | number | null;
18
+ readonly error: {
19
+ readonly code: number;
20
+ readonly message: string;
21
+ };
22
+ }
23
+ export type JsonRpcResponse = JsonRpcSuccess | JsonRpcFailure;
24
+ export interface McpRequestContext {
25
+ readonly cwd: string;
26
+ readonly config?: McpConfig;
27
+ }
28
+ export interface McpTool {
29
+ readonly name: string;
30
+ readonly description: string;
31
+ readonly inputSchema: {
32
+ readonly type: 'object';
33
+ readonly properties: Record<string, unknown>;
34
+ };
35
+ }
36
+ export interface McpToolResult {
37
+ readonly content: readonly {
38
+ readonly type: 'text';
39
+ readonly text: string;
40
+ }[];
41
+ }
42
+ export declare function listMcpTools(): readonly McpTool[];
43
+ export declare function handleMcpRequest(request: JsonRpcRequest, context: McpRequestContext): Promise<JsonRpcResponse | undefined>;
44
+ export declare function callMcpTool(name: string, args: Record<string, unknown>, context: McpRequestContext): Promise<McpToolResult>;
45
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG7C,eAAO,MAAM,WAAW,UAAU,CAAC;AACnC,eAAO,MAAM,oBAAoB,eAAe,CAAC;AAEjD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC;IACzB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE;QACd,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH;AAED,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG,cAAc,CAAC;AAE9D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;CAC7B;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE;QACpB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;QACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAC9C,CAAC;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,SAAS;QACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;KACvB,EAAE,CAAC;CACL;AAwHD,wBAAgB,YAAY,IAAI,SAAS,OAAO,EAAE,CAEjD;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAsBtC;AAED,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,aAAa,CAAC,CA+NxB"}
package/dist/index.js ADDED
@@ -0,0 +1,474 @@
1
+ import { isAbsolute, relative, resolve, sep } from 'node:path';
2
+ import { validateProject } from '@hs-x/validator';
3
+ import { Redacted } from 'effect';
4
+ import { loadMcpConfig } from './config.js';
5
+ export const MCP_VERSION = '0.2.3';
6
+ export const MCP_PROTOCOL_VERSION = '2024-11-05';
7
+ const rootArgSchema = {
8
+ type: 'string',
9
+ description: 'Project root. Defaults to the MCP server working directory.',
10
+ };
11
+ const tools = [
12
+ {
13
+ name: 'hsx.status',
14
+ description: 'Return local HS-X project status using the same validation substrate as the CLI.',
15
+ inputSchema: {
16
+ type: 'object',
17
+ properties: {
18
+ root: rootArgSchema,
19
+ },
20
+ },
21
+ },
22
+ {
23
+ name: 'hsx.check',
24
+ description: 'Run hs-x check for a local project and return structured diagnostics.',
25
+ inputSchema: {
26
+ type: 'object',
27
+ properties: {
28
+ root: rootArgSchema,
29
+ },
30
+ },
31
+ },
32
+ {
33
+ name: 'hsx.dev.capabilities',
34
+ description: 'List the workers and capabilities (tools, triggers, card backends, syncs) declared by a local HS-X project — the targets hsx.dev.invoke accepts.',
35
+ inputSchema: {
36
+ type: 'object',
37
+ properties: {
38
+ root: rootArgSchema,
39
+ },
40
+ },
41
+ },
42
+ {
43
+ name: 'hsx.dev.invoke',
44
+ description: 'Invoke one capability of a local HS-X project through the PRODUCTION runtime router (payload validation, context, handler, result envelope — exactly what a deployed Worker runs). Fixture defaults fill the dispatch payload; pass input/enrolledObject/install to override. Works on freshly-migrated apps.',
45
+ inputSchema: {
46
+ type: 'object',
47
+ properties: {
48
+ root: rootArgSchema,
49
+ capabilityId: { type: 'string', description: 'Capability id (see hsx.dev.capabilities).' },
50
+ input: { type: 'object', description: 'Handler input (default: {}).' },
51
+ enrolledObject: {
52
+ type: 'object',
53
+ description: 'Enrolled object {id, objectType, properties} (default: fixture).',
54
+ },
55
+ install: { type: 'object', description: 'Install identity (default: local fixture).' },
56
+ },
57
+ },
58
+ },
59
+ {
60
+ name: 'hsx.dev.invoke_last',
61
+ description: 'Replay the last recorded invocation for a local HS-X project (.hs-x/last-invocation.json) — the failure-replay loop.',
62
+ inputSchema: {
63
+ type: 'object',
64
+ properties: {
65
+ root: rootArgSchema,
66
+ },
67
+ },
68
+ },
69
+ {
70
+ name: 'hsx.dev.session.start',
71
+ description: 'Start a dev server for a local HS-X project (background process; logs to .hs-x/dev-server.log). Returns the URL once /_hsx/health responds. One session per project.',
72
+ inputSchema: {
73
+ type: 'object',
74
+ properties: {
75
+ root: rootArgSchema,
76
+ port: { type: 'number', description: 'Port (default 8787).' },
77
+ },
78
+ },
79
+ },
80
+ {
81
+ name: 'hsx.dev.session.status',
82
+ description: 'Health + identity of the project dev session started via hsx.dev.session.start.',
83
+ inputSchema: { type: 'object', properties: { root: rootArgSchema } },
84
+ },
85
+ {
86
+ name: 'hsx.dev.session.stop',
87
+ description: 'Stop the project dev session (SIGTERM to the recorded pid).',
88
+ inputSchema: { type: 'object', properties: { root: rootArgSchema } },
89
+ },
90
+ {
91
+ name: 'hsx.dev.logs',
92
+ description: 'Tail the dev session log (.hs-x/dev-server.log) — request lines + handler logs.',
93
+ inputSchema: {
94
+ type: 'object',
95
+ properties: {
96
+ root: rootArgSchema,
97
+ lines: { type: 'number', description: 'Trailing lines (default 50).' },
98
+ },
99
+ },
100
+ },
101
+ {
102
+ name: 'hsx.secrets.hubspot_oauth.set',
103
+ description: 'Store a HubSpot app OAuth client secret for one HS-X account/project/environment/app.',
104
+ inputSchema: {
105
+ type: 'object',
106
+ properties: {
107
+ accountId: { type: 'string' },
108
+ projectId: { type: 'string' },
109
+ hubSpotAppId: { type: 'number' },
110
+ clientId: { type: 'string' },
111
+ clientSecret: { type: 'string' },
112
+ environment: { type: 'string', enum: ['dev', 'staging', 'production'] },
113
+ controlPlaneUrl: { type: 'string' },
114
+ },
115
+ },
116
+ },
117
+ ];
118
+ export function listMcpTools() {
119
+ return tools;
120
+ }
121
+ export async function handleMcpRequest(request, context) {
122
+ try {
123
+ const result = await dispatchMcpRequest(request, context);
124
+ if (request.id === undefined) {
125
+ return undefined;
126
+ }
127
+ return { jsonrpc: '2.0', id: request.id ?? null, result };
128
+ }
129
+ catch (error) {
130
+ if (request.id === undefined) {
131
+ return undefined;
132
+ }
133
+ return {
134
+ jsonrpc: '2.0',
135
+ id: request.id ?? null,
136
+ error: {
137
+ code: -32000,
138
+ message: error instanceof Error ? error.message : String(error),
139
+ },
140
+ };
141
+ }
142
+ }
143
+ export async function callMcpTool(name, args, context) {
144
+ const root = projectRoot(args, context);
145
+ if (name === 'hsx.status') {
146
+ const validation = await validateProject({ root });
147
+ const diagnosticsBySeverity = { error: 0, warning: 0 };
148
+ for (const diagnostic of validation.diagnostics) {
149
+ diagnosticsBySeverity[diagnostic.severity] += 1;
150
+ }
151
+ return content({
152
+ ok: validation.ok,
153
+ command: 'status',
154
+ root,
155
+ filesChecked: validation.filesChecked,
156
+ diagnosticsBySeverity,
157
+ });
158
+ }
159
+ if (name === 'hsx.check') {
160
+ return content({
161
+ command: 'check',
162
+ ...(await validateProject({ root })),
163
+ });
164
+ }
165
+ if (name === 'hsx.dev.capabilities') {
166
+ const { loadProjectWorkers, DevInvokeError } = await import('@hs-x/cli/dev/invoke');
167
+ try {
168
+ const workers = await loadProjectWorkers(root);
169
+ return content({
170
+ ok: true,
171
+ command: 'dev capabilities',
172
+ root,
173
+ workers: workers.map((worker) => ({
174
+ name: worker.name,
175
+ capabilities: worker.capabilities,
176
+ })),
177
+ });
178
+ }
179
+ catch (error) {
180
+ if (error instanceof DevInvokeError) {
181
+ throw new Error(`${error.message}${error.hint ? ` ${error.hint}` : ''}`);
182
+ }
183
+ throw error;
184
+ }
185
+ }
186
+ if (name === 'hsx.dev.invoke' || name === 'hsx.dev.invoke_last') {
187
+ const { invokeCapabilityLocally, loadLastInvocation, DevInvokeError } = await import('@hs-x/cli/dev/invoke');
188
+ let capabilityId;
189
+ let payloadOverrides = {};
190
+ if (name === 'hsx.dev.invoke_last') {
191
+ const recorded = await loadLastInvocation(root);
192
+ if (!recorded) {
193
+ throw new Error('No recorded invocation to replay. Call hsx.dev.invoke once first.');
194
+ }
195
+ capabilityId = recorded.capabilityId;
196
+ payloadOverrides = recorded.payload;
197
+ }
198
+ else {
199
+ capabilityId = requiredString(args, 'capabilityId');
200
+ payloadOverrides = {
201
+ ...(args.input !== undefined ? { input: args.input } : {}),
202
+ ...(args.enrolledObject !== undefined ? { enrolledObject: args.enrolledObject } : {}),
203
+ ...(args.install !== undefined ? { install: args.install } : {}),
204
+ };
205
+ }
206
+ try {
207
+ const outcome = await invokeCapabilityLocally({
208
+ root,
209
+ capabilityId,
210
+ ...(payloadOverrides.input !== undefined ? { input: payloadOverrides.input } : {}),
211
+ ...(payloadOverrides.enrolledObject !== undefined
212
+ ? { enrolledObject: payloadOverrides.enrolledObject }
213
+ : {}),
214
+ ...(payloadOverrides.install !== undefined ? { install: payloadOverrides.install } : {}),
215
+ });
216
+ return content({
217
+ ok: outcome.status >= 200 && outcome.status < 300,
218
+ command: 'dev invoke',
219
+ capabilityId,
220
+ worker: outcome.workerName,
221
+ kind: outcome.capabilityKind,
222
+ status: outcome.status,
223
+ response: outcome.body ?? null,
224
+ });
225
+ }
226
+ catch (error) {
227
+ if (error instanceof DevInvokeError) {
228
+ throw new Error(`${error.message}${error.hint ? ` ${error.hint}` : ''}`);
229
+ }
230
+ throw error;
231
+ }
232
+ }
233
+ if (name === 'hsx.dev.session.start') {
234
+ const port = typeof args.port === 'number' ? args.port : 8787;
235
+ const existing = await readDevSession(root);
236
+ if (existing && (await devSessionHealthy(existing.port))) {
237
+ return content({ ok: true, command: 'dev session start', alreadyRunning: true, ...existing });
238
+ }
239
+ const { spawn } = await import('node:child_process');
240
+ const { mkdir } = await import('node:fs/promises');
241
+ const { createWriteStream } = await import('node:fs');
242
+ const { join } = await import('node:path');
243
+ await mkdir(join(root, '.hs-x'), { recursive: true });
244
+ const logPath = join(root, '.hs-x', 'dev-server.log');
245
+ const log = createWriteStream(logPath, { flags: 'a' });
246
+ // HSX_MCP_DEV_BINARY lets tests point at the repo CLI; default = installed hs-x.
247
+ const binary = process.env.HSX_MCP_DEV_BINARY ?? 'hs-x';
248
+ const [command, ...prefixArgs] = binary.split(' ');
249
+ const child = spawn(command, [...prefixArgs, 'dev', '--cwd', root, '--port', String(port)], { detached: true, stdio: ['ignore', 'pipe', 'pipe'] });
250
+ child.stdout?.pipe(log);
251
+ child.stderr?.pipe(log);
252
+ child.unref();
253
+ const session = { pid: child.pid ?? 0, port, url: `http://127.0.0.1:${port}`, logPath };
254
+ await writeDevSession(root, session);
255
+ for (let attempt = 0; attempt < 40; attempt += 1) {
256
+ if (await devSessionHealthy(port)) {
257
+ return content({ ok: true, command: 'dev session start', ...session });
258
+ }
259
+ await new Promise((resolve) => setTimeout(resolve, 250));
260
+ }
261
+ throw new Error(`Dev server did not become healthy on port ${port} within 10s — read the log via hsx.dev.logs.`);
262
+ }
263
+ if (name === 'hsx.dev.session.status') {
264
+ const session = await readDevSession(root);
265
+ if (!session)
266
+ return content({ ok: false, command: 'dev session status', running: false });
267
+ const healthy = await devSessionHealthy(session.port);
268
+ return content({ ok: healthy, command: 'dev session status', running: healthy, ...session });
269
+ }
270
+ if (name === 'hsx.dev.session.stop') {
271
+ const session = await readDevSession(root);
272
+ if (!session)
273
+ return content({ ok: true, command: 'dev session stop', running: false });
274
+ try {
275
+ process.kill(session.pid, 'SIGTERM');
276
+ }
277
+ catch {
278
+ // already gone
279
+ }
280
+ const { rm } = await import('node:fs/promises');
281
+ const { join } = await import('node:path');
282
+ await rm(join(root, '.hs-x', 'dev-session.json'), { force: true });
283
+ return content({ ok: true, command: 'dev session stop', stopped: session.pid });
284
+ }
285
+ if (name === 'hsx.dev.logs') {
286
+ const lines = typeof args.lines === 'number' ? args.lines : 50;
287
+ const { readFile } = await import('node:fs/promises');
288
+ const { join } = await import('node:path');
289
+ const session = await readDevSession(root);
290
+ const logPath = session?.logPath ?? join(root, '.hs-x', 'dev-server.log');
291
+ const raw = await readFile(logPath, 'utf8').catch(() => '');
292
+ const tail = raw.split('\n').filter(Boolean).slice(-lines);
293
+ return content({ ok: true, command: 'dev logs', logPath, lines: tail });
294
+ }
295
+ if (name === 'hsx.secrets.hubspot_oauth.set') {
296
+ const sessionToken = readSessionToken(context);
297
+ if (!sessionToken) {
298
+ throw new Error('hsx.secrets.hubspot_oauth.set requires a bearer session. ' +
299
+ 'Set HSX_SESSION_TOKEN in the MCP server environment (obtain one via `hs-x login`).');
300
+ }
301
+ const accountId = requiredString(args, 'accountId');
302
+ const projectId = requiredString(args, 'projectId');
303
+ const hubSpotAppId = requiredNumber(args, 'hubSpotAppId');
304
+ const clientId = requiredString(args, 'clientId');
305
+ const clientSecret = requiredString(args, 'clientSecret');
306
+ const environment = optionalString(args, 'environment') ?? 'production';
307
+ const config = resolveMcpConfig(context);
308
+ const controlPlaneUrl = optionalString(args, 'controlPlaneUrl') ?? config.controlPlaneUrl.toString();
309
+ const response = await fetch(new URL(`/v1/accounts/${encodeURIComponent(accountId)}/projects/${encodeURIComponent(projectId)}/hubspot-apps/${encodeURIComponent(String(hubSpotAppId))}/oauth-secret`, controlPlaneUrl), {
310
+ method: 'PUT',
311
+ headers: {
312
+ 'content-type': 'application/json',
313
+ authorization: `Bearer ${sessionToken}`,
314
+ },
315
+ body: JSON.stringify({ clientId, clientSecret, environment }),
316
+ });
317
+ const body = await response.json().catch(() => undefined);
318
+ if (!response.ok) {
319
+ throw new Error(isRecord(body) && typeof body.message === 'string'
320
+ ? body.message
321
+ : `Control plane returned ${response.status}`);
322
+ }
323
+ // Whitelist non-sensitive response fields. Never echo client secret material
324
+ // (or any other token-shaped value) back through the MCP transport.
325
+ const safeData = isRecord(body)
326
+ ? {
327
+ accountId: typeof body.accountId === 'string' ? body.accountId : undefined,
328
+ projectId: typeof body.projectId === 'string' ? body.projectId : undefined,
329
+ hubSpotAppId: typeof body.hubSpotAppId === 'number' ? body.hubSpotAppId : undefined,
330
+ environment: typeof body.environment === 'string' ? body.environment : undefined,
331
+ secretSet: typeof body.secretSet === 'boolean' ? body.secretSet : true,
332
+ updatedAt: typeof body.updatedAt === 'string' ? body.updatedAt : undefined,
333
+ }
334
+ : { secretSet: true };
335
+ return content({ command: name, ok: true, data: safeData });
336
+ }
337
+ throw new Error(`Unknown MCP tool: ${name}`);
338
+ }
339
+ async function dispatchMcpRequest(request, context) {
340
+ if (request.method === 'initialize') {
341
+ return {
342
+ protocolVersion: MCP_PROTOCOL_VERSION,
343
+ serverInfo: { name: '@hs-x/mcp', version: MCP_VERSION },
344
+ capabilities: { tools: {} },
345
+ };
346
+ }
347
+ if (request.method === 'tools/list') {
348
+ return { tools: listMcpTools() };
349
+ }
350
+ if (request.method === 'tools/call') {
351
+ const params = parseToolCallParams(request.params);
352
+ return callMcpTool(params.name, params.arguments, context);
353
+ }
354
+ throw new Error(`Unsupported MCP method: ${request.method ?? '(missing)'}`);
355
+ }
356
+ function parseToolCallParams(params) {
357
+ if (!isRecord(params) || typeof params.name !== 'string') {
358
+ throw new Error('tools/call requires params.name');
359
+ }
360
+ if (params.arguments !== undefined && !isRecord(params.arguments)) {
361
+ throw new Error('tools/call params.arguments must be an object when provided');
362
+ }
363
+ return {
364
+ name: params.name,
365
+ arguments: params.arguments ?? {},
366
+ };
367
+ }
368
+ function projectRoot(args, context) {
369
+ if (args.root !== undefined && typeof args.root !== 'string') {
370
+ throw new Error('root must be a string when provided');
371
+ }
372
+ const rootArg = args.root ?? '.';
373
+ const allowedRoots = buildAllowedRoots(context);
374
+ const resolved = resolve(context.cwd, rootArg);
375
+ for (const allowed of allowedRoots) {
376
+ if (isWithin(resolved, allowed)) {
377
+ return resolved;
378
+ }
379
+ }
380
+ throw new Error('root must resolve within the MCP working directory or an HSX_MCP_ALLOWED_ROOTS entry');
381
+ }
382
+ function buildAllowedRoots(context) {
383
+ const config = resolveMcpConfig(context);
384
+ const roots = new Set();
385
+ roots.add(resolve(context.cwd));
386
+ for (const entry of config.allowedRoots) {
387
+ if (isAbsolute(entry)) {
388
+ roots.add(resolve(entry));
389
+ }
390
+ }
391
+ return Array.from(roots);
392
+ }
393
+ function isWithin(candidate, parent) {
394
+ if (candidate === parent)
395
+ return true;
396
+ const rel = relative(parent, candidate);
397
+ if (rel.length === 0)
398
+ return true;
399
+ if (rel.startsWith('..') || isAbsolute(rel))
400
+ return false;
401
+ // Defence in depth: ensure no segment escape on platforms where relative()
402
+ // might produce surprises.
403
+ return !rel.split(sep).some((segment) => segment === '..');
404
+ }
405
+ function readSessionToken(_context) {
406
+ // The stdio MCP server runs in the developer's shell. Bearer sessions are
407
+ // not yet carried per-call by the JSON-RPC layer, so for now we accept a
408
+ // process-scoped token populated by the MCP host launcher (e.g. exported
409
+ // by `hs-x login`). This matches the bearer pattern used by the CLI.
410
+ const token = resolveMcpConfig(_context).sessionToken;
411
+ return token ? Redacted.value(token) : undefined;
412
+ }
413
+ function resolveMcpConfig(context) {
414
+ return context.config ?? loadMcpConfig();
415
+ }
416
+ function requiredString(args, key) {
417
+ const value = args[key];
418
+ if (typeof value !== 'string' || value.length === 0) {
419
+ throw new Error(`${key} must be a non-empty string`);
420
+ }
421
+ return value;
422
+ }
423
+ function optionalString(args, key) {
424
+ const value = args[key];
425
+ if (value === undefined)
426
+ return undefined;
427
+ if (typeof value !== 'string' || value.length === 0) {
428
+ throw new Error(`${key} must be a non-empty string when provided`);
429
+ }
430
+ return value;
431
+ }
432
+ function requiredNumber(args, key) {
433
+ const value = args[key];
434
+ if (typeof value !== 'number' || !Number.isFinite(value)) {
435
+ throw new Error(`${key} must be a number`);
436
+ }
437
+ return value;
438
+ }
439
+ function content(value) {
440
+ return {
441
+ content: [{ type: 'text', text: JSON.stringify(value, null, 2) }],
442
+ };
443
+ }
444
+ function isRecord(value) {
445
+ return typeof value === 'object' && value !== null;
446
+ }
447
+ async function readDevSession(root) {
448
+ try {
449
+ const { readFile } = await import('node:fs/promises');
450
+ const { join } = await import('node:path');
451
+ const parsed = JSON.parse(await readFile(join(root, '.hs-x', 'dev-session.json'), 'utf8'));
452
+ return typeof parsed.pid === 'number' && typeof parsed.port === 'number' ? parsed : undefined;
453
+ }
454
+ catch {
455
+ return undefined;
456
+ }
457
+ }
458
+ async function writeDevSession(root, session) {
459
+ const { writeFile } = await import('node:fs/promises');
460
+ const { join } = await import('node:path');
461
+ await writeFile(join(root, '.hs-x', 'dev-session.json'), `${JSON.stringify(session, null, 2)}\n`);
462
+ }
463
+ async function devSessionHealthy(port) {
464
+ try {
465
+ const response = await fetch(`http://127.0.0.1:${port}/_hsx/health`, {
466
+ signal: AbortSignal.timeout(1500),
467
+ });
468
+ return response.ok;
469
+ }
470
+ catch {
471
+ return false;
472
+ }
473
+ }
474
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=stdio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":""}
package/dist/stdio.js ADDED
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env node
2
+ import process from 'node:process';
3
+ import { makeHsxNodeTracer } from '@hs-x/types/tracing';
4
+ import { Effect } from 'effect';
5
+ import { handleMcpRequest } from './index.js';
6
+ import { loadMcpConfig } from './config.js';
7
+ let buffer = '';
8
+ process.stdin.setEncoding('utf8');
9
+ const config = loadMcpConfig();
10
+ const tracer = createMcpTracer();
11
+ for await (const chunk of process.stdin) {
12
+ buffer += chunk;
13
+ const lines = buffer.split('\n');
14
+ buffer = lines.pop() ?? '';
15
+ for (const line of lines) {
16
+ if (line.trim().length === 0) {
17
+ continue;
18
+ }
19
+ const request = JSON.parse(line);
20
+ const response = await runMcpRequest(request);
21
+ if (response) {
22
+ process.stdout.write(`${JSON.stringify(response)}\n`);
23
+ }
24
+ }
25
+ }
26
+ if (tracer) {
27
+ await tracer.forceFlush().finally(() => tracer.shutdown());
28
+ }
29
+ async function runMcpRequest(request) {
30
+ if (!tracer) {
31
+ return handleMcpRequest(request, { cwd: process.cwd(), config });
32
+ }
33
+ const program = Effect.promise(() => handleMcpRequest(request, { cwd: process.cwd(), config })).pipe(Effect.withSpan('mcp.request', {
34
+ attributes: {
35
+ 'rpc.system': 'jsonrpc',
36
+ 'rpc.method': request.method ?? '(missing)',
37
+ 'service.name': '@hs-x/mcp',
38
+ },
39
+ }), Effect.provide(tracer.layer));
40
+ try {
41
+ return await Effect.runPromise(program);
42
+ }
43
+ finally {
44
+ await tracer.forceFlush();
45
+ }
46
+ }
47
+ function createMcpTracer() {
48
+ const options = mcpTracingOptions();
49
+ return options ? makeHsxNodeTracer(options) : undefined;
50
+ }
51
+ function mcpTracingOptions() {
52
+ const headers = process.env.OTEL_EXPORTER_OTLP_HEADERS ??
53
+ (process.env.HONEYCOMB_API_KEY
54
+ ? `x-honeycomb-team=${process.env.HONEYCOMB_API_KEY}`
55
+ : undefined);
56
+ if (!headers && !process.env.OTEL_EXPORTER_OTLP_ENDPOINT) {
57
+ return undefined;
58
+ }
59
+ return {
60
+ serviceName: 'hsx-mcp',
61
+ ...(process.env.HSX_MCP_VERSION ? { serviceVersion: process.env.HSX_MCP_VERSION } : {}),
62
+ ...(process.env.OTEL_DEPLOYMENT_ENVIRONMENT
63
+ ? { deploymentEnvironment: process.env.OTEL_DEPLOYMENT_ENVIRONMENT }
64
+ : {}),
65
+ ...(process.env.OTEL_EXPORTER_OTLP_ENDPOINT
66
+ ? { endpoint: process.env.OTEL_EXPORTER_OTLP_ENDPOINT }
67
+ : {}),
68
+ ...(headers ? { headers } : {}),
69
+ };
70
+ }
71
+ //# sourceMappingURL=stdio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdio.js","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@hs-x/mcp",
3
+ "version": "0.2.3",
4
+ "description": "HS-X public MCP server for developer-side coding agents.",
5
+ "type": "module",
6
+ "bin": {
7
+ "hs-x-mcp": "./dist/stdio.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "default": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "README.md",
20
+ "CONTEXT.md"
21
+ ],
22
+ "scripts": {
23
+ "build": "tsc -b",
24
+ "clean": "tsc -b --clean"
25
+ },
26
+ "dependencies": {
27
+ "@hs-x/types": "0.2.3",
28
+ "@hs-x/validator": "0.2.3",
29
+ "effect": "^3.10.19",
30
+ "@hs-x/cli": "0.2.3"
31
+ },
32
+ "devDependencies": {
33
+ "@hs-x/fixtures": "0.1.0",
34
+ "@types/node": "^25.8.0"
35
+ },
36
+ "publishConfig": {
37
+ "access": "public"
38
+ },
39
+ "license": "Apache-2.0"
40
+ }