Skip to content

Commit fed691d

Browse files
khaoss85claude
andcommitted
feat: add Smithery compatibility
- Add createServer() function for programmatic server creation - Add createSandboxServer() for Smithery capability scanning - Export new functions from index.ts - Add .smithery/ to gitignore Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 6d389fc commit fed691d

3 files changed

Lines changed: 61 additions & 1 deletion

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,4 @@ coverage/
2929
# Cache
3030
.npm
3131
.eslintcache
32+
.smithery/

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@
2323
* @see https://github.com/arvo-health/arvo-mcp
2424
*/
2525

26-
export { runServer } from './server.js'
26+
export { runServer, createServer, createSandboxServer } from './server.js'
2727
export { TOOLS, getToolByName, isReadOnlyTool } from './tools/index.js'
2828
export { ArvoApiClient, createClient } from './api/client.js'

src/server.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,72 @@ const SERVER_VERSION = '1.0.0'
2424

2525
let apiClient: ArvoApiClient | null = null
2626

27+
function getClientWithKey(apiKey?: string): ArvoApiClient {
28+
return createClient(apiKey)
29+
}
30+
2731
function getClient(): ArvoApiClient {
2832
if (!apiClient) {
2933
apiClient = createClient()
3034
}
3135
return apiClient
3236
}
3337

38+
/**
39+
* Create an Arvo MCP server instance (for Smithery and programmatic use)
40+
*/
41+
export function createServer(config?: { apiKey?: string }) {
42+
const client = config?.apiKey ? getClientWithKey(config.apiKey) : getClient()
43+
44+
const server = new Server(
45+
{
46+
name: SERVER_NAME,
47+
version: SERVER_VERSION,
48+
},
49+
{
50+
capabilities: {
51+
tools: {},
52+
},
53+
}
54+
)
55+
56+
// Handle list_tools request
57+
server.setRequestHandler(ListToolsRequestSchema, async () => {
58+
return { tools: TOOLS }
59+
})
60+
61+
// Handle call_tool request
62+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
63+
const { name, arguments: args } = request.params
64+
65+
const tool = getToolByName(name)
66+
if (!tool) {
67+
return {
68+
content: [{ type: 'text', text: JSON.stringify({ error: `Unknown tool: ${name}` }) }],
69+
isError: true,
70+
}
71+
}
72+
73+
try {
74+
const result = await client.executeTool(name, (args as Record<string, unknown>) || {})
75+
const resultText = typeof result === 'string' ? result : JSON.stringify(result, null, 2)
76+
return { content: [{ type: 'text', text: resultText }] }
77+
} catch (error) {
78+
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'
79+
return { content: [{ type: 'text', text: JSON.stringify({ error: errorMessage }) }], isError: true }
80+
}
81+
})
82+
83+
return server
84+
}
85+
86+
/**
87+
* Create a sandbox server for Smithery scanning (with mock config)
88+
*/
89+
export function createSandboxServer() {
90+
return createServer({ apiKey: 'sandbox-test-key' })
91+
}
92+
3493
export async function runServer() {
3594
// Validate API key on startup
3695
const client = getClient()

0 commit comments

Comments
 (0)