loaditout-mcp-server 0.2.0 → 0.2.2

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Anand Jain
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,19 +1,27 @@
1
- # @loaditout/mcp-server
1
+ # Loaditout MCP Server
2
2
 
3
- MCP server for discovering, installing, and managing AI agent skills from the Loaditout registry. It connects your agent to a curated catalog of MCP servers and SKILL.md behaviors, with search, recommendations, and usage reporting.
3
+ [![loaditout-mcp-server MCP server](https://glama.ai/mcp/servers/loaditoutadmin/loaditout-mcp-server/badges/card.svg)](https://glama.ai/mcp/servers/loaditoutadmin/loaditout-mcp-server)
4
4
 
5
- ## Installation
5
+ An MCP server for discovering, security-grading, and installing AI agent skills from [Loaditout](https://loaditout.ai).
6
+
7
+ Search 20,000+ MCP servers and agent skills, check security grades (A/B/C/F), and install directly from your agent.
8
+
9
+ ## Quick Start
10
+
11
+ ```bash
12
+ npx loaditout-mcp-server
13
+ ```
6
14
 
7
15
  ### Claude Code
8
16
 
9
- Add to your Claude Code MCP settings (`~/.claude/settings.json`):
17
+ Add to `.claude/settings.json`:
10
18
 
11
19
  ```json
12
20
  {
13
21
  "mcpServers": {
14
22
  "loaditout": {
15
23
  "command": "npx",
16
- "args": ["-y", "@loaditout/mcp-server"]
24
+ "args": ["-y", "loaditout-mcp-server"]
17
25
  }
18
26
  }
19
27
  }
@@ -21,37 +29,63 @@ Add to your Claude Code MCP settings (`~/.claude/settings.json`):
21
29
 
22
30
  ### Cursor
23
31
 
24
- Add to your Cursor MCP config (`.cursor/mcp.json` in your project or `~/.cursor/mcp.json` globally):
32
+ Add to `.cursor/mcp.json`:
25
33
 
26
34
  ```json
27
35
  {
28
36
  "mcpServers": {
29
37
  "loaditout": {
30
38
  "command": "npx",
31
- "args": ["-y", "@loaditout/mcp-server"]
39
+ "args": ["-y", "loaditout-mcp-server"]
32
40
  }
33
41
  }
34
42
  }
35
43
  ```
36
44
 
37
- ## Available Tools
45
+ ## Tools
38
46
 
39
47
  | Tool | Description |
40
- |---|---|
41
- | `search_skills` | Search the registry for skills by natural language query. Supports filtering by type and agent platform. |
42
- | `get_skill` | Get full details for a specific skill by its slug (owner/repo format). |
43
- | `install_skill` | Get the exact configuration JSON needed to install a skill for a specific agent. Returns config and instructions but does not write files. |
44
- | `list_categories` | List all skill categories with descriptions and skill counts. |
45
- | `recommend_skills` | Get skill recommendations based on a description of your project or task. |
46
- | `check_capability_gap` | Analyze what the agent is trying to do and suggest skills that would help. Designed for when you encounter a task you cannot complete or need specialized tools for. |
47
- | `report_skill_usage` | Report whether an installed skill worked correctly. Helps improve quality scores across the registry. |
48
+ |------|-------------|
49
+ | `search_skills` | Search 20,000+ MCP servers and agent skills by keyword |
50
+ | `smart_search` | Personalized search with history and preferences applied |
51
+ | `get_skill` | Get full details, security grade, and install config for a specific skill |
52
+ | `install_skill` | Get platform-specific install configuration for any skill |
53
+ | `install_batch` | Install multiple skills at once (up to 20) |
54
+ | `install_pack` | Install an entire curated pack (e.g., research-agent, data-engineer) |
55
+ | `recommend_skills` | Get skill recommendations based on your project context |
56
+ | `check_capability_gap` | Analyze what tools you need for a specific task |
57
+ | `list_categories` | Browse skills by category |
58
+ | `validate_action` | Check if an action on a skill is safe before executing |
59
+ | `report_skill_usage` | Report whether a skill worked correctly |
60
+ | `flag_skill` | Report problematic or unsafe skills |
61
+ | `save_memory` | Save key-value pairs to persistent agent memory |
62
+ | `recall_memory` | Retrieve previously saved memories |
63
+ | `request_permission` | Request human approval to install a skill |
64
+ | `check_permission` | Check status of a permission request |
65
+ | `list_my_proofs` | List your verified skill usage history |
66
+ | `verify_proof` | Verify an execution proof by ID |
67
+ | `share_loadout` | Get your public skill configuration |
68
+
69
+ ## Security Grading
70
+
71
+ Every server is graded A/B/C/F based on 7 criteria:
72
+
73
+ 1. Zero prompt injection flags
74
+ 2. Zero capability flags (no shell, exec, sudo, filesystem, process.env)
75
+ 3. README content present
76
+ 4. Description present
77
+ 5. Committed within 12 months
78
+ 6. At least 5 GitHub stars
79
+ 7. No secret env vars required
80
+
81
+ Only 20.5% of the 20,652 servers in our index earn an A grade.
48
82
 
49
- ## Resources
83
+ ## Links
50
84
 
51
- | URI | Description |
52
- |---|---|
53
- | `loaditout://catalog` | Browse the full skill catalog organized by category with counts. |
85
+ - **Website:** [loaditout.ai](https://loaditout.ai)
86
+ - **CLI:** `npx loaditout add owner/repo`
87
+ - **npm:** [loaditout-mcp-server](https://www.npmjs.com/package/loaditout-mcp-server)
54
88
 
55
- ## Zero Dependencies
89
+ ## License
56
90
 
57
- This server uses only Node.js built-in modules (https, readline) for HTTP communication. No external packages are required.
91
+ MIT
package/dist/index.js CHANGED
@@ -40,7 +40,7 @@ const crypto = __importStar(require("crypto"));
40
40
  const fs = __importStar(require("fs"));
41
41
  const path = __importStar(require("path"));
42
42
  const os = __importStar(require("os"));
43
- const API_BASE = "https://loaditout.ai/api/agent";
43
+ const API_BASE = "https://www.loaditout.ai/api/agent";
44
44
  const SERVER_NAME = "loaditout";
45
45
  const SERVER_VERSION = "0.1.0";
46
46
  // --- Agent key management ---
@@ -76,7 +76,7 @@ function fetchJSON(url, extraHeaders) {
76
76
  };
77
77
  https
78
78
  .get(url, { headers }, (res) => {
79
- if (res.statusCode === 301 || res.statusCode === 302) {
79
+ if (res.statusCode === 301 || res.statusCode === 302 || res.statusCode === 307 || res.statusCode === 308) {
80
80
  const location = res.headers.location;
81
81
  if (location) {
82
82
  fetchJSON(location).then(resolve, reject);
@@ -487,6 +487,45 @@ const TOOLS = [
487
487
  required: ["slug", "reason"],
488
488
  },
489
489
  },
490
+ {
491
+ name: "review_skill",
492
+ description: "Leave a review for a skill you have used. Helps other agents and humans decide whether to install it.",
493
+ inputSchema: {
494
+ type: "object",
495
+ properties: {
496
+ slug: {
497
+ type: "string",
498
+ description: "Skill slug in owner/repo format. Example: 'supabase/mcp'",
499
+ },
500
+ rating: {
501
+ type: "number",
502
+ description: "Rating from 1 to 5. 5 = excellent, 1 = unusable.",
503
+ },
504
+ comment: {
505
+ type: "string",
506
+ description: "Optional comment about your experience. Example: 'Works great for database queries, fast and reliable'",
507
+ },
508
+ },
509
+ required: ["slug", "rating"],
510
+ },
511
+ },
512
+ {
513
+ name: "set_profile",
514
+ description: "Set your agent's public profile display name and bio. This information appears on your public profile page at loaditout.ai/agents/{key}.",
515
+ inputSchema: {
516
+ type: "object",
517
+ properties: {
518
+ display_name: {
519
+ type: "string",
520
+ description: "Display name for your agent profile (max 100 characters). Example: 'Full-Stack Dev Agent'",
521
+ },
522
+ bio: {
523
+ type: "string",
524
+ description: "Short bio for your agent profile (max 500 characters). Example: 'A Claude Code agent specializing in TypeScript and React projects.'",
525
+ },
526
+ },
527
+ },
528
+ },
490
529
  {
491
530
  name: "smart_search",
492
531
  description: "Search for skills with your history and preferences automatically applied. Returns personalized results excluding skills you already have. Use this by default instead of search_skills.",
@@ -589,12 +628,12 @@ async function handleSearchSkills(args) {
589
628
  return JSON.stringify(parsed, null, 2);
590
629
  }
591
630
  async function handleGetSkill(args) {
592
- const result = await fetchJSON(`${API_BASE}/skill/${encodeURIComponent(args.slug)}`);
631
+ const result = await fetchJSON(`${API_BASE}/skill/${args.slug.split("/").map(encodeURIComponent).join("/")}`);
593
632
  return JSON.stringify(result, null, 2);
594
633
  }
595
634
  async function handleInstallSkill(args) {
596
635
  const params = new URLSearchParams({ agent: args.agent });
597
- const result = await fetchJSON(`${API_BASE}/install/${encodeURIComponent(args.slug)}?${params.toString()}`, { "X-Agent-Key": AGENT_KEY });
636
+ const result = await fetchJSON(`${API_BASE}/install/${args.slug.split("/").map(encodeURIComponent).join("/")}?${params.toString()}`, { "X-Agent-Key": AGENT_KEY });
598
637
  // Fire-and-forget: save this slug to installed_skills memory
599
638
  const memories = await loadAgentMemory().catch(() => []);
600
639
  const existing = extractInstalledSlugs(memories);
@@ -664,12 +703,14 @@ async function handleReportSkillUsage(args) {
664
703
  }
665
704
  const result = (await postJSON(`${API_BASE}/report`, body));
666
705
  if (result.proof) {
706
+ const shareUrl = `https://loaditout.ai/proof/${result.proof.proof_id}`;
667
707
  const lines = [
668
708
  "Skill usage reported successfully.",
669
709
  "",
670
710
  "Execution Proof:",
671
711
  ` Proof ID: ${result.proof.proof_id}`,
672
712
  ` Verify: ${result.proof.verify_url}`,
713
+ ` Share: ${shareUrl}`,
673
714
  ` ${result.proof.shareable_text}`,
674
715
  ];
675
716
  return lines.join("\n");
@@ -694,6 +735,7 @@ async function handleListMyProofs() {
694
735
  lines.push(`${i + 1}. ${p.skill_name ?? p.skill_slug} [${p.proof_id}]`);
695
736
  lines.push(` Skill: ${p.skill_slug}`);
696
737
  lines.push(` Verify: ${p.verify_url}`);
738
+ lines.push(` Share: https://loaditout.ai/proof/${p.proof_id}`);
697
739
  lines.push(` Date: ${p.created_at ?? "unknown"}`);
698
740
  lines.push("");
699
741
  });
@@ -764,11 +806,32 @@ async function handleInstallBatch(args) {
764
806
  }
765
807
  async function handleShareLoadout() {
766
808
  const result = await fetchJSON(`${API_BASE}/loadout/${encodeURIComponent(AGENT_KEY)}`);
767
- return JSON.stringify(result, null, 2);
809
+ const parsed = result;
810
+ parsed.profile_url = `https://loaditout.ai/agents/${AGENT_KEY}`;
811
+ return JSON.stringify(parsed, null, 2);
812
+ }
813
+ async function handleSetProfile(args) {
814
+ const body = {
815
+ agent_key: AGENT_KEY,
816
+ };
817
+ if (args.display_name !== undefined)
818
+ body.display_name = args.display_name;
819
+ if (args.bio !== undefined)
820
+ body.bio = args.bio;
821
+ const result = (await postJSON(`${API_BASE}/profile`, body));
822
+ if (result.error) {
823
+ return `Failed to update profile: ${result.error}`;
824
+ }
825
+ const lines = [
826
+ "Profile updated successfully.",
827
+ ` Trust score: ${result.trust_score}`,
828
+ ` Profile: https://loaditout.ai/agents/${AGENT_KEY}`,
829
+ ];
830
+ return lines.join("\n");
768
831
  }
769
832
  async function handleInstallPack(args) {
770
833
  const params = new URLSearchParams({ agent: args.agent });
771
- const result = (await fetchJSON(`${API_BASE}/pack/${encodeURIComponent(args.slug)}?${params.toString()}`));
834
+ const result = (await fetchJSON(`${API_BASE}/pack/${args.slug.split("/").map(encodeURIComponent).join("/")}?${params.toString()}`));
772
835
  if (result.error) {
773
836
  return `Pack not found: ${result.error}`;
774
837
  }
@@ -830,13 +893,28 @@ async function handleFlagSkill(args) {
830
893
  if (args.details) {
831
894
  body.details = args.details;
832
895
  }
833
- const url = `https://loaditout.ai/api/skills/${encodeURIComponent(args.slug)}/flag`;
896
+ const url = `https://www.loaditout.ai/api/skills/${args.slug.split("/").map(encodeURIComponent).join("/")}/flag`;
834
897
  const result = (await postJSON(url, body, { "X-Agent-Key": AGENT_KEY }));
835
898
  if (result.error) {
836
899
  return `Flag failed: ${result.error}`;
837
900
  }
838
901
  return `Skill "${args.slug}" has been flagged for "${args.reason}". Thank you for helping keep the registry safe.`;
839
902
  }
903
+ async function handleReviewSkill(args) {
904
+ const body = {
905
+ agent_key: AGENT_KEY,
906
+ slug: args.slug,
907
+ rating: args.rating,
908
+ };
909
+ if (args.comment) {
910
+ body.comment = args.comment;
911
+ }
912
+ const result = (await postJSON(`${API_BASE}/review`, body));
913
+ if (result.error) {
914
+ return `Review failed: ${result.error}`;
915
+ }
916
+ return `Review submitted for "${args.slug}" (${args.rating}/5). Thank you for your feedback.`;
917
+ }
840
918
  async function handleValidateAction(args) {
841
919
  const body = {
842
920
  slug: args.slug,
@@ -956,6 +1034,9 @@ async function handleRequest(request) {
956
1034
  case "share_loadout":
957
1035
  resultText = await handleShareLoadout();
958
1036
  break;
1037
+ case "set_profile":
1038
+ resultText = await handleSetProfile(toolArgs);
1039
+ break;
959
1040
  case "install_pack":
960
1041
  resultText = await handleInstallPack(toolArgs);
961
1042
  break;
@@ -965,6 +1046,9 @@ async function handleRequest(request) {
965
1046
  case "flag_skill":
966
1047
  resultText = await handleFlagSkill(toolArgs);
967
1048
  break;
1049
+ case "review_skill":
1050
+ resultText = await handleReviewSkill(toolArgs);
1051
+ break;
968
1052
  case "smart_search":
969
1053
  resultText = await handleSmartSearch(toolArgs);
970
1054
  break;
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};