@elsium-ai/mcp 0.7.0 → 0.9.0

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/README.md CHANGED
@@ -186,6 +186,8 @@ interface MCPServerConfig {
186
186
  name: string
187
187
  version?: string
188
188
  tools: Tool[]
189
+ resources?: MCPResourceHandler[]
190
+ prompts?: MCPPromptHandler[]
189
191
  }
190
192
  ```
191
193
 
@@ -194,6 +196,8 @@ interface MCPServerConfig {
194
196
  | `name` | `string` | yes | -- | Server name reported in the `initialize` handshake |
195
197
  | `version` | `string` | no | `'0.1.0'` | Server version reported in the `initialize` handshake |
196
198
  | `tools` | `Tool[]` | yes | -- | Array of ElsiumAI `Tool` objects to expose over MCP |
199
+ | `resources` | `MCPResourceHandler[]` | no | `[]` | Resource handlers to expose over MCP |
200
+ | `prompts` | `MCPPromptHandler[]` | no | `[]` | Prompt handlers to expose over MCP |
197
201
 
198
202
  ### `MCPServer`
199
203
 
@@ -210,7 +214,7 @@ interface MCPServer {
210
214
  | Member | Description |
211
215
  | ------ | ----------- |
212
216
  | `running` | Read-only boolean indicating whether the server is currently listening for requests |
213
- | `start()` | Begin listening on `stdin` for incoming JSON-RPC messages. Handles `initialize`, `notifications/initialized`, `tools/list`, and `tools/call` |
217
+ | `start()` | Begin listening on `stdin` for incoming JSON-RPC messages. Handles `initialize`, `notifications/initialized`, `tools/list`, `tools/call`, `resources/list`, `resources/read`, `prompts/list`, and `prompts/get` |
214
218
  | `stop()` | Stop the server by setting the running flag to false |
215
219
 
216
220
  ### `createMCPServer(config)`
@@ -250,8 +254,155 @@ const server = createMCPServer({
250
254
  })
251
255
 
252
256
  await server.start()
253
- // The server is now listening on stdin/stdout.
254
- // MCP clients (e.g. Claude Desktop) can connect to it via stdio transport.
257
+ ```
258
+
259
+ **Example -- server with resources and prompts**
260
+
261
+ ```typescript
262
+ import { createMCPServer } from '@elsium-ai/mcp'
263
+ import { createTool } from '@elsium-ai/tools'
264
+ import { z } from 'zod'
265
+
266
+ const greet = createTool({
267
+ name: 'greet',
268
+ description: 'Return a greeting for the given name',
269
+ input: z.object({ name: z.string() }),
270
+ execute: async ({ input }) => `Hello, ${input.name}!`,
271
+ })
272
+
273
+ const server = createMCPServer({
274
+ name: 'my-server',
275
+ version: '1.0.0',
276
+ tools: [greet],
277
+ resources: [
278
+ {
279
+ uri: 'config://app',
280
+ name: 'App Configuration',
281
+ description: 'Current application configuration',
282
+ mimeType: 'application/json',
283
+ read: async () => JSON.stringify({ env: 'production', version: '1.0.0' }),
284
+ },
285
+ ],
286
+ prompts: [
287
+ {
288
+ name: 'summarize',
289
+ description: 'Summarize the given text',
290
+ arguments: [
291
+ { name: 'text', description: 'Text to summarize', required: true },
292
+ { name: 'style', description: 'Summary style (brief or detailed)', required: false },
293
+ ],
294
+ get: async (args) => ({
295
+ messages: [
296
+ {
297
+ role: 'user',
298
+ content: `Summarize the following text in a ${args?.style ?? 'brief'} style:\n\n${args?.text}`,
299
+ },
300
+ ],
301
+ }),
302
+ },
303
+ ],
304
+ })
305
+
306
+ await server.start()
307
+ ```
308
+
309
+ ---
310
+
311
+ ## Resources
312
+
313
+ ### `MCPResourceHandler`
314
+
315
+ Defines a resource that the MCP server can expose. Resources provide read-only data to clients (configuration, files, database records, etc.).
316
+
317
+ ```typescript
318
+ interface MCPResourceHandler {
319
+ uri: string
320
+ name: string
321
+ description?: string
322
+ mimeType?: string
323
+ read(): Promise<string>
324
+ }
325
+ ```
326
+
327
+ | Property | Type | Required | Description |
328
+ | -------- | ---- | -------- | ----------- |
329
+ | `uri` | `string` | yes | Unique URI identifying the resource (e.g. `'config://app'`, `'file:///data.json'`) |
330
+ | `name` | `string` | yes | Human-readable name for the resource |
331
+ | `description` | `string` | no | Description of what the resource provides |
332
+ | `mimeType` | `string` | no | MIME type of the returned content |
333
+ | `read` | `() => Promise<string>` | yes | Async function that returns the resource content as a string |
334
+
335
+ ---
336
+
337
+ ## Prompts
338
+
339
+ ### `MCPPromptHandler`
340
+
341
+ Defines a prompt template that the MCP server can expose. Prompts allow clients to request pre-built message sequences with optional arguments.
342
+
343
+ ```typescript
344
+ interface MCPPromptHandler {
345
+ name: string
346
+ description?: string
347
+ arguments?: MCPPromptArgument[]
348
+ get(args?: Record<string, string>): Promise<{ messages: Array<{ role: string; content: string }> }>
349
+ }
350
+
351
+ interface MCPPromptArgument {
352
+ name: string
353
+ description?: string
354
+ required?: boolean
355
+ }
356
+ ```
357
+
358
+ | Property | Type | Required | Description |
359
+ | -------- | ---- | -------- | ----------- |
360
+ | `name` | `string` | yes | Unique name for the prompt |
361
+ | `description` | `string` | no | Description of what the prompt does |
362
+ | `arguments` | `MCPPromptArgument[]` | no | Arguments the prompt accepts |
363
+ | `get` | `(args?) => Promise<{ messages }>` | yes | Async function that returns the prompt's message sequence |
364
+
365
+ ---
366
+
367
+ ## Client Resource and Prompt Methods
368
+
369
+ The `MCPClient` also supports listing and reading resources and prompts from a connected server:
370
+
371
+ ```typescript
372
+ interface MCPClient {
373
+ listResources(): Promise<MCPResourceInfo[]>
374
+ readResource(uri: string): Promise<string>
375
+ listPrompts(): Promise<MCPPromptInfo[]>
376
+ getPrompt(name: string, args?: Record<string, string>): Promise<{ messages: Array<{ role: string; content: string }> }>
377
+ }
378
+ ```
379
+
380
+ | Method | Description |
381
+ | ------ | ----------- |
382
+ | `listResources()` | List all resources exposed by the connected MCP server |
383
+ | `readResource(uri)` | Read the content of a specific resource by URI |
384
+ | `listPrompts()` | List all prompts exposed by the connected MCP server |
385
+ | `getPrompt(name, args?)` | Get a prompt's message sequence, optionally passing arguments |
386
+
387
+ ```typescript
388
+ import { createMCPClient } from '@elsium-ai/mcp'
389
+
390
+ const client = createMCPClient({
391
+ name: 'my-client',
392
+ transport: 'stdio',
393
+ command: 'node',
394
+ args: ['./my-mcp-server.js'],
395
+ })
396
+
397
+ await client.connect()
398
+
399
+ const resources = await client.listResources()
400
+ const config = await client.readResource('config://app')
401
+
402
+ const prompts = await client.listPrompts()
403
+ const prompt = await client.getPrompt('summarize', { text: 'Long article...', style: 'brief' })
404
+
405
+ await client.disconnect()
255
406
  ```
256
407
 
257
408
  ---
package/dist/client.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { Tool } from '@elsium-ai/tools';
2
+ import type { MCPPrompt, MCPPromptMessage, MCPResource, MCPResourceContent } from './types';
2
3
  export interface MCPClientStdioConfig {
3
4
  name: string;
4
5
  transport: 'stdio';
@@ -26,6 +27,10 @@ export interface MCPClient {
26
27
  listTools(): Promise<MCPToolInfo[]>;
27
28
  callTool(name: string, args: Record<string, unknown>): Promise<unknown>;
28
29
  toElsiumTools(): Promise<Tool[]>;
30
+ listResources(): Promise<MCPResource[]>;
31
+ readResource(uri: string): Promise<MCPResourceContent[]>;
32
+ listPrompts(): Promise<MCPPrompt[]>;
33
+ getPrompt(name: string, args?: Record<string, string>): Promise<MCPPromptMessage[]>;
29
34
  readonly connected: boolean;
30
35
  }
31
36
  export declare function createMCPClient(config: MCPClientConfig): MCPClient;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAoC,MAAM,kBAAkB,CAAA;AAE9E,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,SAAS,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,MAAM,eAAe,GAAG,oBAAoB,GAAG,mBAAmB,CAAA;AAExE,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACpC;AAgBD,MAAM,WAAW,SAAS;IACzB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3B,SAAS,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAAA;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACvE,aAAa,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;IAChC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;CAC3B;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,CAKlE"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAoC,MAAM,kBAAkB,CAAA;AAC9E,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAE3F,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,SAAS,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,MAAM,eAAe,GAAG,oBAAoB,GAAG,mBAAmB,CAAA;AAExE,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACpC;AAgBD,MAAM,WAAW,SAAS;IACzB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3B,SAAS,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAAA;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACvE,aAAa,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;IAChC,aAAa,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAAA;IACvC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAA;IACxD,WAAW,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAAA;IACnC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAA;IACnF,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;CAC3B;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,CAKlE"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { createMCPClient } from './client';
2
2
  export type { MCPClient, MCPClientConfig, MCPClientStdioConfig, MCPClientHttpConfig, MCPToolInfo, } from './client';
3
3
  export { createMCPServer, createMCPHttpHandler } from './server';
4
- export type { MCPServer, MCPServerConfig, MCPHttpHandlerConfig, MCPHttpHandler } from './server';
5
- export type { JsonRpcRequest, JsonRpcResponse, MCPTransport } from './types';
4
+ export type { MCPServer, MCPServerConfig, MCPHttpHandlerConfig, MCPHttpHandler, MCPResourceHandler, MCPPromptHandler, } from './server';
5
+ export type { JsonRpcRequest, JsonRpcResponse, MCPTransport, MCPResource, MCPResourceContent, MCPPrompt, MCPPromptArgument, MCPPromptMessage, } from './types';
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC1C,YAAY,EACX,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,mBAAmB,EACnB,WAAW,GACX,MAAM,UAAU,CAAA;AAGjB,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAChE,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAGhG,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC1C,YAAY,EACX,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,mBAAmB,EACnB,WAAW,GACX,MAAM,UAAU,CAAA;AAGjB,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAChE,YAAY,EACX,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,GAChB,MAAM,UAAU,CAAA;AAGjB,YAAY,EACX,cAAc,EACd,eAAe,EACf,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,SAAS,EACT,iBAAiB,EACjB,gBAAgB,GAChB,MAAM,SAAS,CAAA"}
package/dist/index.js CHANGED
@@ -259,6 +259,25 @@ function createHttpMCPClient(config) {
259
259
  `);
260
260
  return textContent ?? result;
261
261
  },
262
+ async listResources() {
263
+ const result = await sendRequest("resources/list");
264
+ return result.resources ?? [];
265
+ },
266
+ async readResource(uri) {
267
+ const result = await sendRequest("resources/read", { uri });
268
+ return result.contents ?? [];
269
+ },
270
+ async listPrompts() {
271
+ const result = await sendRequest("prompts/list");
272
+ return result.prompts ?? [];
273
+ },
274
+ async getPrompt(name, args) {
275
+ const params = { name };
276
+ if (args)
277
+ params.arguments = args;
278
+ const result = await sendRequest("prompts/get", params);
279
+ return result.messages ?? [];
280
+ },
262
281
  async toElsiumTools() {
263
282
  const mcpTools = await this.listTools();
264
283
  const client = this;
@@ -467,6 +486,25 @@ function createStdioMCPClient(config) {
467
486
  `);
468
487
  return textContent ?? result;
469
488
  },
489
+ async listResources() {
490
+ const result = await sendRequest("resources/list");
491
+ return result.resources ?? [];
492
+ },
493
+ async readResource(uri) {
494
+ const result = await sendRequest("resources/read", { uri });
495
+ return result.contents ?? [];
496
+ },
497
+ async listPrompts() {
498
+ const result = await sendRequest("prompts/list");
499
+ return result.prompts ?? [];
500
+ },
501
+ async getPrompt(name, args) {
502
+ const params = { name };
503
+ if (args)
504
+ params.arguments = args;
505
+ const result = await sendRequest("prompts/get", params);
506
+ return result.messages ?? [];
507
+ },
470
508
  async toElsiumTools() {
471
509
  const mcpTools = await this.listTools();
472
510
  const client = this;
@@ -515,6 +553,18 @@ var log3 = createLogger();
515
553
  function createMCPServer(config) {
516
554
  let running = false;
517
555
  const toolMap = new Map(config.tools.map((t) => [t.name, t]));
556
+ const resourceMap = new Map((config.resources ?? []).map((r) => [r.uri, r]));
557
+ const promptMap = new Map((config.prompts ?? []).map((p) => [p.name, p]));
558
+ function buildCapabilities() {
559
+ const capabilities = {};
560
+ if (config.tools.length > 0)
561
+ capabilities.tools = {};
562
+ if (config.resources?.length)
563
+ capabilities.resources = {};
564
+ if (config.prompts?.length)
565
+ capabilities.prompts = {};
566
+ return capabilities;
567
+ }
518
568
  function handleRequest(request) {
519
569
  const id = request.id ?? 0;
520
570
  switch (request.method) {
@@ -524,7 +574,7 @@ function createMCPServer(config) {
524
574
  id,
525
575
  result: {
526
576
  protocolVersion: "2024-11-05",
527
- capabilities: { tools: {} },
577
+ capabilities: buildCapabilities(),
528
578
  serverInfo: {
529
579
  name: config.name,
530
580
  version: config.version ?? "0.1.0"
@@ -553,6 +603,37 @@ function createMCPServer(config) {
553
603
  case "tools/call": {
554
604
  return null;
555
605
  }
606
+ case "resources/list": {
607
+ const resources = (config.resources ?? []).map((r) => ({
608
+ uri: r.uri,
609
+ name: r.name,
610
+ description: r.description,
611
+ mimeType: r.mimeType
612
+ }));
613
+ return {
614
+ jsonrpc: "2.0",
615
+ id,
616
+ result: { resources }
617
+ };
618
+ }
619
+ case "resources/read": {
620
+ return null;
621
+ }
622
+ case "prompts/list": {
623
+ const prompts = (config.prompts ?? []).map((p) => ({
624
+ name: p.name,
625
+ description: p.description,
626
+ arguments: p.arguments
627
+ }));
628
+ return {
629
+ jsonrpc: "2.0",
630
+ id,
631
+ result: { prompts }
632
+ };
633
+ }
634
+ case "prompts/get": {
635
+ return null;
636
+ }
556
637
  default: {
557
638
  return {
558
639
  jsonrpc: "2.0",
@@ -604,10 +685,60 @@ function createMCPServer(config) {
604
685
  }
605
686
  };
606
687
  }
688
+ async function handleResourceRead(request) {
689
+ const id = request.id ?? 0;
690
+ const uri = request.params?.uri;
691
+ const resource = resourceMap.get(uri);
692
+ if (!resource) {
693
+ return {
694
+ jsonrpc: "2.0",
695
+ id,
696
+ error: { code: -32602, message: `Unknown resource: ${uri}` }
697
+ };
698
+ }
699
+ const data = await resource.read();
700
+ const content = typeof data === "string" ? { uri, mimeType: resource.mimeType, text: data } : { uri, mimeType: resource.mimeType, ...data };
701
+ return {
702
+ jsonrpc: "2.0",
703
+ id,
704
+ result: { contents: [content] }
705
+ };
706
+ }
707
+ async function handlePromptGet(request) {
708
+ const id = request.id ?? 0;
709
+ const name = request.params?.name;
710
+ const args = request.params?.arguments;
711
+ const prompt = promptMap.get(name);
712
+ if (!prompt) {
713
+ return {
714
+ jsonrpc: "2.0",
715
+ id,
716
+ error: { code: -32602, message: `Unknown prompt: ${name}` }
717
+ };
718
+ }
719
+ const messages = await prompt.get(args);
720
+ return {
721
+ jsonrpc: "2.0",
722
+ id,
723
+ result: { messages }
724
+ };
725
+ }
607
726
  function writeLine(data) {
608
727
  process.stdout.write(`${JSON.stringify(data)}
609
728
  `);
610
729
  }
730
+ async function handleAsyncRequest(request) {
731
+ switch (request.method) {
732
+ case "tools/call":
733
+ return handleToolCall(request);
734
+ case "resources/read":
735
+ return handleResourceRead(request);
736
+ case "prompts/get":
737
+ return handlePromptGet(request);
738
+ default:
739
+ return null;
740
+ }
741
+ }
611
742
  async function processRequestLine(line) {
612
743
  if (!line.trim())
613
744
  return;
@@ -617,9 +748,9 @@ function createMCPServer(config) {
617
748
  } catch {
618
749
  return;
619
750
  }
620
- if (request.method === "tools/call") {
621
- const response2 = await handleToolCall(request);
622
- writeLine(response2);
751
+ const asyncResponse = await handleAsyncRequest(request);
752
+ if (asyncResponse) {
753
+ writeLine(asyncResponse);
623
754
  return;
624
755
  }
625
756
  const response = handleRequest(request);
@@ -683,6 +814,15 @@ function createMCPServer(config) {
683
814
  }
684
815
  function createMCPHttpHandler(config) {
685
816
  const toolMap = new Map(config.tools.map((t) => [t.name, t]));
817
+ const resourceMap = new Map((config.resources ?? []).map((r) => [r.uri, r]));
818
+ const promptMap = new Map((config.prompts ?? []).map((p) => [p.name, p]));
819
+ const httpCapabilities = {};
820
+ if (config.tools.length > 0)
821
+ httpCapabilities.tools = {};
822
+ if (config.resources?.length)
823
+ httpCapabilities.resources = {};
824
+ if (config.prompts?.length)
825
+ httpCapabilities.prompts = {};
686
826
  function handleSyncRequest(request) {
687
827
  const id = request.id ?? 0;
688
828
  switch (request.method) {
@@ -692,7 +832,7 @@ function createMCPHttpHandler(config) {
692
832
  id,
693
833
  result: {
694
834
  protocolVersion: "2024-11-05",
695
- capabilities: { tools: {} },
835
+ capabilities: httpCapabilities,
696
836
  serverInfo: {
697
837
  name: config.name,
698
838
  version: config.version ?? "0.1.0"
@@ -716,6 +856,31 @@ function createMCPHttpHandler(config) {
716
856
  })
717
857
  }
718
858
  };
859
+ case "resources/list":
860
+ return {
861
+ jsonrpc: "2.0",
862
+ id,
863
+ result: {
864
+ resources: (config.resources ?? []).map((r) => ({
865
+ uri: r.uri,
866
+ name: r.name,
867
+ description: r.description,
868
+ mimeType: r.mimeType
869
+ }))
870
+ }
871
+ };
872
+ case "prompts/list":
873
+ return {
874
+ jsonrpc: "2.0",
875
+ id,
876
+ result: {
877
+ prompts: (config.prompts ?? []).map((p) => ({
878
+ name: p.name,
879
+ description: p.description,
880
+ arguments: p.arguments
881
+ }))
882
+ }
883
+ };
719
884
  default:
720
885
  return {
721
886
  jsonrpc: "2.0",
@@ -763,6 +928,56 @@ function createMCPHttpHandler(config) {
763
928
  }
764
929
  };
765
930
  }
931
+ async function handleResourceRead(request) {
932
+ const id = request.id ?? 0;
933
+ const uri = request.params?.uri;
934
+ const resource = resourceMap.get(uri);
935
+ if (!resource) {
936
+ return {
937
+ jsonrpc: "2.0",
938
+ id,
939
+ error: { code: -32602, message: `Unknown resource: ${uri}` }
940
+ };
941
+ }
942
+ const data = await resource.read();
943
+ const content = typeof data === "string" ? { uri, mimeType: resource.mimeType, text: data } : { uri, mimeType: resource.mimeType, ...data };
944
+ return {
945
+ jsonrpc: "2.0",
946
+ id,
947
+ result: { contents: [content] }
948
+ };
949
+ }
950
+ async function handlePromptGet(request) {
951
+ const id = request.id ?? 0;
952
+ const name = request.params?.name;
953
+ const args = request.params?.arguments;
954
+ const prompt = promptMap.get(name);
955
+ if (!prompt) {
956
+ return {
957
+ jsonrpc: "2.0",
958
+ id,
959
+ error: { code: -32602, message: `Unknown prompt: ${name}` }
960
+ };
961
+ }
962
+ const messages = await prompt.get(args);
963
+ return {
964
+ jsonrpc: "2.0",
965
+ id,
966
+ result: { messages }
967
+ };
968
+ }
969
+ async function handleAsyncMethod(body) {
970
+ switch (body.method) {
971
+ case "tools/call":
972
+ return handleToolCall(body);
973
+ case "resources/read":
974
+ return handleResourceRead(body);
975
+ case "prompts/get":
976
+ return handlePromptGet(body);
977
+ default:
978
+ return null;
979
+ }
980
+ }
766
981
  return async (request) => {
767
982
  if (request.method !== "POST") {
768
983
  return new Response(JSON.stringify({ error: "Method not allowed" }), {
@@ -774,14 +989,20 @@ function createMCPHttpHandler(config) {
774
989
  try {
775
990
  body = await request.json();
776
991
  } catch {
777
- return new Response(JSON.stringify({ jsonrpc: "2.0", id: 0, error: { code: -32700, message: "Parse error" } }), { status: 400, headers: { "Content-Type": "application/json" } });
992
+ return new Response(JSON.stringify({
993
+ jsonrpc: "2.0",
994
+ id: 0,
995
+ error: { code: -32700, message: "Parse error" }
996
+ }), { status: 400, headers: { "Content-Type": "application/json" } });
778
997
  }
779
- let response;
780
- if (body.method === "tools/call") {
781
- response = await handleToolCall(body);
782
- } else {
783
- response = handleSyncRequest(body);
998
+ const asyncResponse = await handleAsyncMethod(body);
999
+ if (asyncResponse) {
1000
+ return new Response(JSON.stringify(asyncResponse), {
1001
+ status: 200,
1002
+ headers: { "Content-Type": "application/json" }
1003
+ });
784
1004
  }
1005
+ const response = handleSyncRequest(body);
785
1006
  if (!response) {
786
1007
  return new Response(null, { status: 204 });
787
1008
  }
package/dist/server.d.ts CHANGED
@@ -1,8 +1,27 @@
1
1
  import type { Tool } from '@elsium-ai/tools';
2
+ import type { MCPPromptArgument, MCPPromptMessage } from './types';
3
+ export interface MCPResourceHandler {
4
+ uri: string;
5
+ name: string;
6
+ description?: string;
7
+ mimeType?: string;
8
+ read: () => Promise<string | {
9
+ text?: string;
10
+ blob?: string;
11
+ }>;
12
+ }
13
+ export interface MCPPromptHandler {
14
+ name: string;
15
+ description?: string;
16
+ arguments?: MCPPromptArgument[];
17
+ get: (args?: Record<string, string>) => Promise<MCPPromptMessage[]>;
18
+ }
2
19
  export interface MCPServerConfig {
3
20
  name: string;
4
21
  version?: string;
5
22
  tools: Tool[];
23
+ resources?: MCPResourceHandler[];
24
+ prompts?: MCPPromptHandler[];
6
25
  }
7
26
  export interface MCPServer {
8
27
  start(): Promise<void>;
@@ -14,6 +33,8 @@ export interface MCPHttpHandlerConfig {
14
33
  name: string;
15
34
  version?: string;
16
35
  tools: Tool[];
36
+ resources?: MCPResourceHandler[];
37
+ prompts?: MCPPromptHandler[];
17
38
  }
18
39
  export type MCPHttpHandler = (request: Request) => Promise<Response>;
19
40
  export declare function createMCPHttpHandler(config: MCPHttpHandlerConfig): MCPHttpHandler;
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAK5C,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,IAAI,EAAE,CAAA;CACb;AAgBD,MAAM,WAAW,SAAS;IACzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,IAAI,IAAI,IAAI,CAAA;IACZ,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CACzB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,CAmMlE;AAID,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,IAAI,EAAE,CAAA;CACb;AAED,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAEpE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,oBAAoB,GAAG,cAAc,CAmIjF"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAC5C,OAAO,KAAK,EAAmC,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAInG,MAAM,WAAW,kBAAkB;IAClC,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC9D;AAED,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,iBAAiB,EAAE,CAAA;IAC/B,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAA;CACnE;AAED,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,IAAI,EAAE,CAAA;IACb,SAAS,CAAC,EAAE,kBAAkB,EAAE,CAAA;IAChC,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAA;CAC5B;AAgBD,MAAM,WAAW,SAAS;IACzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,IAAI,IAAI,IAAI,CAAA;IACZ,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CACzB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,CA4SlE;AAID,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,IAAI,EAAE,CAAA;IACb,SAAS,CAAC,EAAE,kBAAkB,EAAE,CAAA;IAChC,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAA;CAC5B;AAED,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAEpE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,oBAAoB,GAAG,cAAc,CAwOjF"}
package/dist/types.d.ts CHANGED
@@ -15,4 +15,33 @@ export interface JsonRpcResponse {
15
15
  };
16
16
  }
17
17
  export type MCPTransport = 'stdio' | 'http';
18
+ export interface MCPResource {
19
+ uri: string;
20
+ name: string;
21
+ description?: string;
22
+ mimeType?: string;
23
+ }
24
+ export interface MCPResourceContent {
25
+ uri: string;
26
+ mimeType?: string;
27
+ text?: string;
28
+ blob?: string;
29
+ }
30
+ export interface MCPPrompt {
31
+ name: string;
32
+ description?: string;
33
+ arguments?: MCPPromptArgument[];
34
+ }
35
+ export interface MCPPromptArgument {
36
+ name: string;
37
+ description?: string;
38
+ required?: boolean;
39
+ }
40
+ export interface MCPPromptMessage {
41
+ role: 'user' | 'assistant';
42
+ content: {
43
+ type: 'text';
44
+ text: string;
45
+ };
46
+ }
18
47
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,KAAK,CAAA;IACd,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,eAAe;IAC/B,OAAO,EAAE,KAAK,CAAA;IACd,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;CACzD;AAED,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,KAAK,CAAA;IACd,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,eAAe;IAC/B,OAAO,EAAE,KAAK,CAAA;IACd,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;CACzD;AAED,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,CAAA;AAE3C,MAAM,WAAW,WAAW;IAC3B,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,kBAAkB;IAClC,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,iBAAiB,EAAE,CAAA;CAC/B;AAED,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAA;IAC1B,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CACvC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elsium-ai/mcp",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "description": "Model Context Protocol (MCP) support for ElsiumAI — bidirectional bridge",
5
5
  "license": "MIT",
6
6
  "author": "Eric Utrera <ebutrera9103@gmail.com>",
@@ -26,8 +26,8 @@
26
26
  "dev": "bun --watch src/index.ts"
27
27
  },
28
28
  "dependencies": {
29
- "@elsium-ai/core": "^0.7.0",
30
- "@elsium-ai/tools": "^0.7.0"
29
+ "@elsium-ai/core": "^0.9.0",
30
+ "@elsium-ai/tools": "^0.9.0"
31
31
  },
32
32
  "devDependencies": {
33
33
  "typescript": "^5.7.0"