Analyze project from URL/path and auto-detect build system to create Nix package
Analyze a project from a URL or local directory and create a Nix package with auto-detected build system.
If parameters are missing from $ARGUMENTS, use mcp_question to gather them:
mcp_question({
questions: [
{
question: "What is the source location? (GitHub URL, git URL, or local path)",
header: "Source",
options: [
{ label: "Enter URL or path...", description: "e.g., https://github.com/user/repo or ~/Projects/myapp" }
]
},
{
question: "What should the package be named? (leave blank to auto-detect)",
header: "Name",
options: [
{ label: "Auto-detect (Recommended)", description: "Derive from repository/directory name" },
{ label: "Enter name...", description: "Custom package name (lowercase, hyphens OK)" }
]
}
]
})
Expected $ARGUMENTS format: <source_url_or_path> [package_name]
https://github.com/user/myapp~/Projects/myapp my-custom-namehttps://forge.meskill.farm/iamruinous/projectFor URLs:
mcp_github_get_file_contents to read project filesfetchurlFor Local Paths:
mcp_read and mcp_glob to analyze the directoryCheck for these files in priority order:
| File | Type | Build System |
|---|---|---|
go.mod |
Go | buildGoModule |
Cargo.toml |
Rust | rustPlatform.buildRustPackage |
pyproject.toml |
Python | python3Packages.buildPythonPackage |
setup.py |
Python (legacy) | python3Packages.buildPythonPackage |
package.json |
Node.js | buildNpmPackage or shell wrapper |
CMakeLists.txt |
C/C++ | stdenv.mkDerivation with cmake |
Makefile |
C/C++ | stdenv.mkDerivation |
mkdocs.yml |
Docs (MkDocs) | stdenv.mkDerivation with mkdocs |
*.sh only |
Shell script | stdenv.mkDerivation wrapper |
*.deb |
Binary | stdenv.mkDerivation extract |
From detected project files, extract:
go.mod, Cargo.toml, pyproject.toml, package.json, or directory name0.1.0 as default{pkgs, ...}:
pkgs.buildGoModule rec {
pname = "<package-name>";
version = "<version>";
src = pkgs.fetchFromGitHub {
owner = "<owner>";
repo = "<repo>";
rev = "v${version}";
hash = "sha256-AAAA...";
};
vendorHash = "sha256-BBBB...";
meta = with pkgs.lib; {
description = "<description>";
homepage = "<url>";
license = licenses.<license>;
mainProgram = "<binary-name>";
platforms = platforms.unix;
};
}
For Forgejo/Gitea sources, use fetchgit:
src = pkgs.fetchgit {
url = "<git-url>";
rev = "v${version}";
hash = "sha256-AAAA...";
};
{pkgs, ...}:
pkgs.rustPlatform.buildRustPackage rec {
pname = "<package-name>";
version = "<version>";
src = pkgs.fetchFromGitHub {
owner = "<owner>";
repo = "<repo>";
rev = "v${version}";
hash = "sha256-AAAA...";
};
cargoHash = "sha256-BBBB...";
meta = with pkgs.lib; {
description = "<description>";
homepage = "<url>";
license = licenses.<license>;
mainProgram = "<binary-name>";
};
}
{pkgs, ...}:
pkgs.python3Packages.buildPythonApplication rec {
pname = "<package-name>";
version = "<version>";
format = "pyproject";
src = pkgs.fetchFromGitHub {
owner = "<owner>";
repo = "<repo>";
rev = "v${version}";
hash = "sha256-AAAA...";
};
nativeBuildInputs = with pkgs.python3Packages; [
setuptools
setuptools-scm
wheel
];
propagatedBuildInputs = with pkgs.python3Packages; [
# Add dependencies from pyproject.toml
];
pythonImportsCheck = ["<module_name>"];
meta = with pkgs.lib; {
description = "<description>";
homepage = "<url>";
license = licenses.<license>;
mainProgram = "<binary-name>";
};
}
For CLI tools, prefer shell wrapper with bundled JS:
{pkgs, ...}:
pkgs.stdenv.mkDerivation {
pname = "<package-name>";
version = "<version>";
dontUnpack = true;
propagatedBuildInputs = with pkgs; [
nodejs
];
buildPhase = ''
mkdir -p $out/bin
mkdir -p $out/share/<package-name>
# Copy source files
cp -r ${./src}/* $out/share/<package-name>/
# Create wrapper script
cat > $out/bin/<package-name> << 'EOF'
#!/usr/bin/env bash
exec ${pkgs.nodejs}/bin/node $out/share/<package-name>/index.js "$@"
EOF
chmod +x $out/bin/<package-name>
'';
installPhase = "true";
meta = with pkgs.lib; {
description = "<description>";
homepage = "<url>";
license = licenses.<license>;
mainProgram = "<package-name>";
platforms = platforms.unix;
};
}
{pkgs, ...}:
pkgs.stdenv.mkDerivation rec {
pname = "<package-name>";
version = "<version>";
src = pkgs.fetchzip {
url = "<release-url>";
sha256 = "sha256-AAAA...";
};
# Or for pre-built docs:
dontBuild = true;
installPhase = ''
runHook preInstall
mkdir -p $out
cp -r * $out/
runHook postInstall
'';
meta = with pkgs.lib; {
description = "<description>";
homepage = "<url>";
license = licenses.<license>;
platforms = platforms.linux;
};
}
{pkgs, ...}:
pkgs.stdenv.mkDerivation {
pname = "<package-name>";
version = "<version>";
dontUnpack = true;
propagatedBuildInputs = with pkgs; [
bash
coreutils
# Add detected dependencies
];
passthru.shellPath = "/bin/<package-name>";
outputs = ["out"];
buildPhase = ''
mkdir -p $out/bin
substitute ${./<script>.sh} $out/bin/<package-name> \
--replace '@bash@' '${pkgs.bash}/bin/bash' \
--replace '@coreutils@' '${pkgs.coreutils}'
chmod +x $out/bin/<package-name>
'';
installPhase = "true";
meta = with pkgs.lib; {
description = "<description>";
homepage = "<url>";
license = licenses.<license>;
mainProgram = "<package-name>";
platforms = platforms.unix;
};
}
# For GitHub URL
Parse owner/repo from URL
Use mcp_github_get_file_contents to check for:
- go.mod, Cargo.toml, pyproject.toml, package.json, mkdocs.yml
# For Forgejo/Gitea URL
Use mcp_webfetch or clone to analyze
# For local path
Use mcp_glob to find project files
Use mcp_read to analyze content
mkdir -p packages/<package-name>
Use the appropriate template based on detected type.
# <package-name>
<description>
## Overview
<brief explanation of purpose>
## Features
- Feature 1
- Feature 2
## Usage
```nix
environment.systemPackages = with pkgs; [
<package-name>
];
# First build (will fail with correct hash)
nix build .#<package-name>
# Copy hash from error output
# Update default.nix with correct hash
# Build again
nix build .#<package-name>
# Test
./result/bin/<package-name> --help
Add entry to the packages README following the existing format.
For the first build, use placeholder hashes:
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
vendorHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
cargoHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
Then extract correct hashes from build errors:
nix build .#<package-name> 2>&1 | grep "got:" | awk '{print $2}'
Or use prefetch tools:
# For GitHub
nix-prefetch-github <owner> <repo> --rev v<version>
# For URLs
nix-prefetch-url --unpack <url>
# For git repos
nix-prefetch-git <git-url> --rev v<version>
# User provides GitHub URL
/add-package https://github.com/docker/mcp-gateway
# Agent analyzes:
# - Detects go.mod -> Go project
# - Extracts name: mcp-gateway
# - Finds version from releases: 0.28.0
# - Reads description from README
# - Identifies Apache 2.0 license
# Creates packages/docker-mcp-gateway/default.nix
# Creates packages/docker-mcp-gateway/README.md
# Runs nix build, extracts hashes
# Updates packages/README.md
nix build .#<package-name> succeeds