Skip to content

Commit fd7c555

Browse files
committed
fix(ci): checkout submodules and format serve.ts
- Add submodules: true to CI checkout step - Fix shellHook to check for package.json instead of directory - Format tests/mocks/serve.ts with oxfmt
1 parent a4367cf commit fd7c555

File tree

3 files changed

+99
-100
lines changed

3 files changed

+99
-100
lines changed

.github/workflows/ci.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ jobs:
4646
steps:
4747
- name: Checkout repository
4848
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
49+
with:
50+
submodules: true
4951

5052
- name: Setup Nix
5153
uses: ./.github/actions/setup-nix

flake.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@
115115
fi
116116
117117
# Install Node.js dependencies for MCP mock server (used in tests)
118-
if [ -d vendor/stackone-ai-node ]; then
118+
if [ -f vendor/stackone-ai-node/package.json ]; then
119119
if [ ! -f vendor/stackone-ai-node/node_modules/.pnpm/lock.yaml ] || \
120120
[ vendor/stackone-ai-node/pnpm-lock.yaml -nt vendor/stackone-ai-node/node_modules/.pnpm/lock.yaml ]; then
121121
echo "📦 Installing MCP mock server dependencies..."

tests/mocks/serve.ts

Lines changed: 96 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -5,130 +5,127 @@
55
* Usage:
66
* bun run tests/mocks/serve.ts [port]
77
*/
8-
import { Hono } from 'hono';
9-
import { cors } from 'hono/cors';
8+
import { Hono } from "hono";
9+
import { cors } from "hono/cors";
1010
import {
11-
accountMcpTools,
12-
createMcpApp,
13-
defaultMcpTools,
14-
exampleBamboohrTools,
15-
mixedProviderTools,
16-
} from '../../vendor/stackone-ai-node/mocks/mcp-server';
11+
accountMcpTools,
12+
createMcpApp,
13+
defaultMcpTools,
14+
exampleBamboohrTools,
15+
mixedProviderTools,
16+
} from "../../vendor/stackone-ai-node/mocks/mcp-server";
1717

18-
const port = parseInt(process.env.PORT || Bun.argv[2] || '8787', 10);
18+
const port = parseInt(process.env.PORT || Bun.argv[2] || "8787", 10);
1919

2020
// Create the MCP app with all test tool configurations
2121
const mcpApp = createMcpApp({
22-
accountTools: {
23-
default: defaultMcpTools,
24-
acc1: accountMcpTools.acc1,
25-
acc2: accountMcpTools.acc2,
26-
acc3: accountMcpTools.acc3,
27-
'test-account': accountMcpTools['test-account'],
28-
mixed: mixedProviderTools,
29-
'your-bamboohr-account-id': exampleBamboohrTools,
30-
'your-stackone-account-id': exampleBamboohrTools,
31-
},
22+
accountTools: {
23+
default: defaultMcpTools,
24+
acc1: accountMcpTools.acc1,
25+
acc2: accountMcpTools.acc2,
26+
acc3: accountMcpTools.acc3,
27+
"test-account": accountMcpTools["test-account"],
28+
mixed: mixedProviderTools,
29+
"your-bamboohr-account-id": exampleBamboohrTools,
30+
"your-stackone-account-id": exampleBamboohrTools,
31+
},
3232
});
3333

3434
// Create the main app with CORS and mount the MCP app
3535
const app = new Hono();
3636

3737
// Add CORS for cross-origin requests
38-
app.use('/*', cors());
38+
app.use("/*", cors());
3939

4040
// Health check endpoint
41-
app.get('/health', (c) => c.json({ status: 'ok' }));
41+
app.get("/health", (c) => c.json({ status: "ok" }));
4242

4343
// Mount the MCP app (handles /mcp endpoint)
44-
app.route('/', mcpApp);
44+
app.route("/", mcpApp);
4545

4646
// RPC endpoint for tool execution
47-
app.post('/actions/rpc', async (c) => {
48-
const authHeader = c.req.header('Authorization');
49-
const accountIdHeader = c.req.header('x-account-id');
50-
51-
// Check for authentication
52-
if (!authHeader || !authHeader.startsWith('Basic ')) {
53-
return c.json(
54-
{ error: 'Unauthorized', message: 'Missing or invalid authorization header' },
55-
401,
56-
);
57-
}
58-
59-
const body = (await c.req.json()) as {
60-
action?: string;
61-
body?: Record<string, unknown>;
62-
headers?: Record<string, string>;
63-
path?: Record<string, string>;
64-
query?: Record<string, string>;
65-
};
66-
67-
// Validate action is provided
68-
if (!body.action) {
69-
return c.json({ error: 'Bad Request', message: 'Action is required' }, 400);
70-
}
71-
72-
// Test action to verify x-account-id is sent as HTTP header
73-
if (body.action === 'test_account_id_header') {
74-
return c.json({
75-
data: {
76-
httpHeader: accountIdHeader,
77-
bodyHeader: body.headers?.['x-account-id'],
78-
},
79-
});
80-
}
81-
82-
// Return mock response based on action
83-
if (body.action === 'bamboohr_get_employee') {
84-
return c.json({
85-
data: {
86-
id: body.path?.id || 'test-id',
87-
name: 'Test Employee',
88-
...body.body,
89-
},
90-
});
91-
}
92-
93-
if (body.action === 'bamboohr_list_employees') {
94-
return c.json({
95-
data: [
96-
{ id: '1', name: 'Employee 1' },
97-
{ id: '2', name: 'Employee 2' },
98-
],
99-
});
100-
}
101-
102-
if (body.action === 'test_error_action') {
103-
return c.json(
104-
{ error: 'Internal Server Error', message: 'Test error response' },
105-
500,
106-
);
107-
}
108-
109-
// Default response for other actions
110-
return c.json({
111-
data: {
112-
action: body.action,
113-
received: {
114-
body: body.body,
115-
headers: body.headers,
116-
path: body.path,
117-
query: body.query,
118-
},
119-
},
120-
});
47+
app.post("/actions/rpc", async (c) => {
48+
const authHeader = c.req.header("Authorization");
49+
const accountIdHeader = c.req.header("x-account-id");
50+
51+
// Check for authentication
52+
if (!authHeader || !authHeader.startsWith("Basic ")) {
53+
return c.json(
54+
{ error: "Unauthorized", message: "Missing or invalid authorization header" },
55+
401,
56+
);
57+
}
58+
59+
const body = (await c.req.json()) as {
60+
action?: string;
61+
body?: Record<string, unknown>;
62+
headers?: Record<string, string>;
63+
path?: Record<string, string>;
64+
query?: Record<string, string>;
65+
};
66+
67+
// Validate action is provided
68+
if (!body.action) {
69+
return c.json({ error: "Bad Request", message: "Action is required" }, 400);
70+
}
71+
72+
// Test action to verify x-account-id is sent as HTTP header
73+
if (body.action === "test_account_id_header") {
74+
return c.json({
75+
data: {
76+
httpHeader: accountIdHeader,
77+
bodyHeader: body.headers?.["x-account-id"],
78+
},
79+
});
80+
}
81+
82+
// Return mock response based on action
83+
if (body.action === "bamboohr_get_employee") {
84+
return c.json({
85+
data: {
86+
id: body.path?.id || "test-id",
87+
name: "Test Employee",
88+
...body.body,
89+
},
90+
});
91+
}
92+
93+
if (body.action === "bamboohr_list_employees") {
94+
return c.json({
95+
data: [
96+
{ id: "1", name: "Employee 1" },
97+
{ id: "2", name: "Employee 2" },
98+
],
99+
});
100+
}
101+
102+
if (body.action === "test_error_action") {
103+
return c.json({ error: "Internal Server Error", message: "Test error response" }, 500);
104+
}
105+
106+
// Default response for other actions
107+
return c.json({
108+
data: {
109+
action: body.action,
110+
received: {
111+
body: body.body,
112+
headers: body.headers,
113+
path: body.path,
114+
query: body.query,
115+
},
116+
},
117+
});
121118
});
122119

123120
console.log(`MCP Mock Server starting on port ${port}...`);
124121

125122
export default {
126-
port,
127-
fetch: app.fetch,
123+
port,
124+
fetch: app.fetch,
128125
};
129126

130127
console.log(`MCP Mock Server running at http://localhost:${port}`);
131-
console.log('Endpoints:');
128+
console.log("Endpoints:");
132129
console.log(` - GET /health - Health check`);
133130
console.log(` - ALL /mcp - MCP protocol endpoint`);
134131
console.log(` - POST /actions/rpc - RPC execution endpoint`);

0 commit comments

Comments
 (0)