kojee-mcp 0.1.2 → 0.2.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
@@ -6,7 +6,7 @@ kojee-mcp is a local MCP proxy that lets any MCP-capable agent use Kojee-managed
6
6
 
7
7
  1. **Get a gateway token** from the [Kojee dashboard](https://kojee.ai).
8
8
  2. **Add to your MCP config** (see examples below).
9
- 3. **Tools appear automatically** -- the proxy discovers and exposes all tools your token has access to.
9
+ 3. **Tools appear automatically** -- all Kojee tools your token has access to are exposed directly (e.g. `gmail_send_email`, `github_list_repos`, `calendar_create_event`). Agents call them like any native MCP tool — no discovery step, no wrapper, no indirection.
10
10
 
11
11
  ## MCP Config Examples
12
12
 
@@ -517,106 +517,51 @@ function sleep(ms) {
517
517
  }
518
518
 
519
519
  // src/tool-registry.ts
520
- var BUILTIN_TOOL_NAMES = /* @__PURE__ */ new Set([
521
- "kojee_check_approval",
522
- "kojee_revoke_request",
523
- "kojee_send_feedback"
524
- ]);
525
- function extractConnector(toolName) {
526
- if (BUILTIN_TOOL_NAMES.has(toolName)) return null;
527
- const idx = toolName.indexOf("_");
528
- if (idx === -1) return null;
529
- return toolName.substring(0, idx);
530
- }
531
520
  var ToolRegistry = class {
532
521
  constructor(gateway) {
533
522
  this.gateway = gateway;
534
523
  }
535
524
  gateway;
536
- /** Connector ID connector info with tool list */
537
- connectors = /* @__PURE__ */ new Map();
538
- /** All tool names (flat) for validation */
539
- allToolNames = /* @__PURE__ */ new Set();
525
+ /** Flat map: tool name full tool definition */
526
+ tools = /* @__PURE__ */ new Map();
540
527
  /**
541
- * Fetch the lean tool list from the gateway and group by connector.
528
+ * Fetch all tools with full schemas from the gateway in a single RPC call.
542
529
  */
543
530
  async discoverTools() {
544
- console.error("[tools] Fetching lean tool list from gateway...");
545
- const listResult = await this.gateway.sendRpc("tools/list", {});
546
- const toolList = listResult?.tools;
531
+ console.error("[tools] Fetching tools with full schemas from gateway...");
532
+ const result = await this.gateway.sendRpc("tools/list", {
533
+ include_schema: true
534
+ });
535
+ const toolList = result?.tools;
547
536
  if (!toolList || !Array.isArray(toolList)) {
548
537
  console.error("[tools] No tools returned from gateway");
549
538
  return;
550
539
  }
551
540
  for (const tool of toolList) {
552
- this.allToolNames.add(tool.name);
553
- const connector = extractConnector(tool.name);
554
- if (!connector) continue;
555
- let info = this.connectors.get(connector);
556
- if (!info) {
557
- info = { id: connector, tools: [] };
558
- this.connectors.set(connector, info);
541
+ if (this.tools.has(tool.name)) {
542
+ console.error(`[tools] Warning: duplicate tool name "${tool.name}" \u2014 overwriting`);
559
543
  }
560
- info.tools.push({ name: tool.name, description: tool.description });
561
- }
562
- console.error(
563
- `[tools] Discovered ${this.allToolNames.size} tools across ${this.connectors.size} connectors`
564
- );
565
- }
566
- /**
567
- * Get the list of connector meta-tools to register with the MCP server.
568
- * Each connector becomes a tool like "kojee_gmail" whose description
569
- * lists its available tools.
570
- */
571
- getConnectorTools() {
572
- const tools = [];
573
- for (const [connectorId, info] of this.connectors) {
574
- const toolNames = info.tools.map((t) => t.name).join(", ");
575
- tools.push({
576
- name: connectorId,
577
- description: `${connectorId} tools available via Kojee (${info.tools.length} tools: ${toolNames}). Call this tool to see descriptions and details for each.`,
578
- inputSchema: { type: "object", properties: {} }
579
- });
580
- }
581
- return tools;
582
- }
583
- /**
584
- * Get the detailed tool list for a specific connector.
585
- */
586
- getConnectorToolList(connectorId) {
587
- const info = this.connectors.get(connectorId);
588
- if (!info) {
589
- return `No connector '${connectorId}' found. Available: ${Array.from(this.connectors.keys()).join(", ")}`;
544
+ this.tools.set(tool.name, tool);
590
545
  }
591
- const lines = info.tools.map((t) => `- **${t.name}**: ${t.description}`);
592
- return `## ${connectorId} tools
593
-
594
- ${lines.join("\n")}
595
-
596
- Use kojee_get_tool_schema to get the full input schema, then kojee_call_tool to execute.`;
546
+ console.error(`[tools] Registered ${this.tools.size} tools from gateway`);
597
547
  }
598
548
  /**
599
- * Get full schemas for specific tools via tools/get_schema.
549
+ * Return all registered tools for the MCP ListTools response.
600
550
  */
601
- async getToolSchemas(names) {
602
- const result = await this.gateway.sendRpc("tools/get_schema", { names });
603
- const response = result;
604
- if (response.not_found && response.not_found.length > 0) {
605
- console.error(`[tools] Schemas not found for: ${response.not_found.join(", ")}`);
606
- }
607
- return response.tools ?? [];
551
+ getAllTools() {
552
+ return Array.from(this.tools.values());
608
553
  }
609
554
  /**
610
555
  * Call a tool through the gateway.
611
556
  */
612
557
  async callTool(name, args) {
613
- if (!this.allToolNames.has(name)) {
614
- const available = Array.from(this.connectors.keys()).map((c) => `kojee_${c}`).join(", ");
558
+ if (!this.tools.has(name)) {
559
+ const available = Array.from(this.tools.keys()).slice(0, 10).join(", ");
615
560
  return {
616
561
  content: [
617
562
  {
618
563
  type: "text",
619
- text: `Tool '${name}' not found. Use one of the connector tools (${available}) to discover available tools.`
564
+ text: `Tool '${name}' not found. Some available tools: ${available}${this.tools.size > 10 ? ", ..." : ""}`
620
565
  }
621
566
  ],
622
567
  isError: true
@@ -627,13 +572,9 @@ Use kojee_get_tool_schema to get the full input schema, then kojee_call_tool to
627
572
  arguments: args
628
573
  });
629
574
  }
630
- /** List of connector IDs. */
631
- get connectorIds() {
632
- return Array.from(this.connectors.keys());
633
- }
634
- /** Total number of discovered tools. */
575
+ /** Total number of registered tools. */
635
576
  get toolCount() {
636
- return this.allToolNames.size;
577
+ return this.tools.size;
637
578
  }
638
579
  };
639
580
 
@@ -644,85 +585,11 @@ import {
644
585
  ListToolsRequestSchema,
645
586
  CallToolRequestSchema
646
587
  } from "@modelcontextprotocol/sdk/types.js";
647
- var UTILITY_TOOL_NAMES = /* @__PURE__ */ new Set([
648
- "get_tool_schema",
649
- "call_tool",
650
- "check_approval",
651
- "revoke_request"
652
- ]);
653
- var UTILITY_TOOLS = [
654
- {
655
- name: "get_tool_schema",
656
- description: "Get the full input schema for one or more Kojee tools. Call this before call_tool to know the exact parameters required.",
657
- inputSchema: {
658
- type: "object",
659
- properties: {
660
- names: {
661
- type: "array",
662
- items: { type: "string" },
663
- description: 'Tool names to get schemas for (e.g. ["gmail_send_email", "github_list_repos"])'
664
- }
665
- },
666
- required: ["names"]
667
- }
668
- },
669
- {
670
- name: "call_tool",
671
- description: "Call a Kojee tool by name with the specified arguments. Use the connector tools (e.g. kojee_gmail) to discover tools, then get_tool_schema to get parameters, then this to execute.",
672
- inputSchema: {
673
- type: "object",
674
- properties: {
675
- name: {
676
- type: "string",
677
- description: 'The tool name (e.g. "gmail_send_email")'
678
- },
679
- arguments: {
680
- type: "object",
681
- description: "The tool arguments matching the tool's input schema",
682
- additionalProperties: true
683
- }
684
- },
685
- required: ["name"]
686
- }
687
- },
688
- {
689
- name: "check_approval",
690
- description: "Check the status of a pending approval request. Use this after a tool call returns 'require_approval' to poll whether the user has approved or denied.",
691
- inputSchema: {
692
- type: "object",
693
- properties: {
694
- approval_id: {
695
- type: "string",
696
- description: "The approval ID returned when a tool call requires approval"
697
- }
698
- },
699
- required: ["approval_id"]
700
- }
701
- },
702
- {
703
- name: "revoke_request",
704
- description: "Revoke/cancel a pending approval request you no longer need.",
705
- inputSchema: {
706
- type: "object",
707
- properties: {
708
- approval_id: {
709
- type: "string",
710
- description: "The approval ID to revoke"
711
- },
712
- reason: {
713
- type: "string",
714
- description: "Optional reason for revoking"
715
- }
716
- },
717
- required: ["approval_id"]
718
- }
719
- }
720
- ];
721
588
  function createMcpServer(registry) {
722
589
  const server = new Server(
723
590
  {
724
591
  name: "kojee-mcp",
725
- version: "0.1.1"
592
+ version: "0.2.0"
726
593
  },
727
594
  {
728
595
  capabilities: {
@@ -731,69 +598,21 @@ function createMcpServer(registry) {
731
598
  }
732
599
  );
733
600
  server.setRequestHandler(ListToolsRequestSchema, async () => {
734
- const connectorTools = registry.getConnectorTools();
735
- return { tools: [...connectorTools, ...UTILITY_TOOLS] };
601
+ const tools = registry.getAllTools().map((t) => ({
602
+ name: t.name,
603
+ description: t.description,
604
+ inputSchema: t.inputSchema
605
+ }));
606
+ return { tools };
736
607
  });
737
608
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
738
609
  const { name, arguments: args } = request.params;
739
- if (!UTILITY_TOOL_NAMES.has(name)) {
740
- const toolList = registry.getConnectorToolList(name);
741
- return {
742
- content: [{ type: "text", text: toolList }],
743
- isError: false
744
- };
745
- }
746
- switch (name) {
747
- case "get_tool_schema": {
748
- const names = args?.names ?? [];
749
- if (names.length === 0) {
750
- return {
751
- content: [{ type: "text", text: "Provide tool names in the 'names' array." }],
752
- isError: true
753
- };
754
- }
755
- const schemas = await registry.getToolSchemas(names);
756
- return {
757
- content: [{ type: "text", text: JSON.stringify(schemas, null, 2) }],
758
- isError: false
759
- };
760
- }
761
- case "call_tool": {
762
- const toolName = args?.name;
763
- if (!toolName) {
764
- return {
765
- content: [{ type: "text", text: "Provide the tool name in the 'name' field." }],
766
- isError: true
767
- };
768
- }
769
- const toolArgs = args?.arguments ?? {};
770
- const rawResult = await registry.callTool(toolName, toolArgs);
771
- const result = translateToolCallResult(rawResult);
772
- return {
773
- content: result.content,
774
- isError: result.isError
775
- };
776
- }
777
- case "check_approval":
778
- case "revoke_request": {
779
- const rawResult = await registry.callTool(name, args ?? {});
780
- const result = translateToolCallResult(rawResult);
781
- return {
782
- content: result.content,
783
- isError: result.isError
784
- };
785
- }
786
- default:
787
- return {
788
- content: [
789
- {
790
- type: "text",
791
- text: `Unknown tool '${name}'. Use one of the connector tools or utility tools.`
792
- }
793
- ],
794
- isError: true
795
- };
796
- }
610
+ const rawResult = await registry.callTool(name, args ?? {});
611
+ const result = translateToolCallResult(rawResult);
612
+ return {
613
+ content: result.content,
614
+ isError: result.isError
615
+ };
797
616
  });
798
617
  return server;
799
618
  }
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  startProxy
4
- } from "./chunk-WIXI3EVR.js";
4
+ } from "./chunk-O5UYOIQX.js";
5
5
 
6
6
  // src/cli.ts
7
7
  import { Command } from "commander";
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  startProxy
3
- } from "./chunk-WIXI3EVR.js";
3
+ } from "./chunk-O5UYOIQX.js";
4
4
  export {
5
5
  startProxy
6
6
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kojee-mcp",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "Local MCP proxy for Kojee — handles DPoP auth, tool discovery, and governance transparently",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",