Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Turn a Pipelex MTHDS bundle into an API request against any bundle-shaped pipelex-api route — push it as a ready-to-run query into the live "Pipelex FastAPI" Postman collection, emit a curl command, execute it directly, or just preview the body. Covers the whole bundle surface: run (/v1/execute, /v1/start), dry-run validate (/v1/validate — no inference, no cost), crate resolution (/v1/resolve), and typed codegen (/v1/codegen — ts-zod, python-pydantic, python-structures). Use this whenever the us
SkillScore82/100
Test results 82
3/3 safety checks passed
18%82%of test cases passed +64 pts
Passed 18 of 22 test cases with the skill, and 4 of 22 without it.
14 fixed4 passed either way4 still failing0 broke
One test taskFrom which directory in the Pipelex repository should `make bundle-run` or script invocations be executed?
Adds every file the skill has, pinned so you can update it. No account needed.
pip install "decimalai>=0.15"
decimalai skills add pipelex-postman-bundle
claude --plugin-dir "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.agents"The same install from Python, for a notebook or a setup script.
pip install "decimalai>=0.15"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("pipelex-postman-bundle")
if result.exit_code:
raise SystemExit(result.problems)
print("Added. Start Claude Code with the command below.")claude --plugin-dir "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.agents"Type these in a Claude Code session. No account or API key. It writes the skill and any files it bundles, and asks first when its safety rating isn't Passed.
/plugin marketplace add decimal-labs/decimalai-claude-plugins
/plugin install decimalai@decimalai/decimalai:install pipelex-postman-bundleThe plugin needs python3 and curl on your machine.
No Python or account. Claude Code picks it up in its next session.
curl -fsSL --create-dirs -o .claude/skills/pipelex-postman-bundle/SKILL.md https://app.decimal.ai/s/pipelex-postman-bundle/SKILL.md.claude/skills/pipelex-postman-bundle/SKILL.mdThis gets SKILL.md only. The skill's 1 other file is not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[claude-agent-sdk]"
decimalai skills add pipelex-postman-bundleimport asyncio
from claude_agent_sdk import ClaudeAgentOptions
from decimalai.claude_agent_sdk import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
async def main():
question = "Hello!"
async with support.run(question) as run: # one user message, one run
async for message in run.query(options=ClaudeAgentOptions(max_turns=6)):
print(message)
# In a notebook or async code: await main()
asyncio.run(main())Prefer its own loader? ClaudeAgentOptions(plugins=[skills_plugin()], skills="all") reads the same folder. Use one or the other: a skill delivered both ways reaches the prompt twice.
The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[claude-agent-sdk]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("pipelex-postman-bundle")
if result.exit_code:
raise SystemExit(result.problems)
import asyncio
from claude_agent_sdk import ClaudeAgentOptions
from decimalai.claude_agent_sdk import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
async def main():
question = "Hello!"
async with support.run(question) as run: # one user message, one run
async for message in run.query(options=ClaudeAgentOptions(max_turns=6)):
print(message)
# In a notebook or async code: await main()
asyncio.run(main())Prefer its own loader? ClaudeAgentOptions(plugins=[skills_plugin()], skills="all") reads the same folder. Use one or the other: a skill delivered both ways reaches the prompt twice.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/pipelex-postman-bundle/SKILL.mdimport asyncio
from pathlib import Path
from claude_agent_sdk import ClaudeAgentOptions, query
skill = Path(".agents/skills/pipelex-postman-bundle/SKILL.md").read_text()
options = ClaudeAgentOptions(system_prompt=f"You are a helpful agent.\n\n{skill}", max_turns=6)
async def main():
async for message in query(prompt="Hello!", options=options):
print(message)
# In a notebook or async code: await main()
asyncio.run(main())This gets SKILL.md only. The skill's 1 other file is not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai-agents]"
decimalai skills add pipelex-postman-bundlefrom agents import Agent, Runner
from decimalai.openai_agents import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = Agent(
name=support.name,
instructions=support.instructions, # your prompt, then the skill list
tools=[*support.tools], # your tools, then load_skill
)
# In a notebook or async code: result = await Runner.run(agent, "Hello!")
result = Runner.run_sync(agent, "Hello!")Using SandboxAgent? capabilities=[Shell(), decimalai.openai_agents.sandbox_skills()] points its own loader at the same folder.
The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai-agents]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("pipelex-postman-bundle")
if result.exit_code:
raise SystemExit(result.problems)
from agents import Agent, Runner
from decimalai.openai_agents import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = Agent(
name=support.name,
instructions=support.instructions, # your prompt, then the skill list
tools=[*support.tools], # your tools, then load_skill
)
# In a notebook or async code: result = await Runner.run(agent, "Hello!")
result = Runner.run_sync(agent, "Hello!")Using SandboxAgent? capabilities=[Shell(), decimalai.openai_agents.sandbox_skills()] points its own loader at the same folder.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/pipelex-postman-bundle/SKILL.mdfrom pathlib import Path
from agents import Agent, Runner
skill = Path(".agents/skills/pipelex-postman-bundle/SKILL.md").read_text()
agent = Agent(name="support", instructions=f"You are a helpful agent.\n\n{skill}")
# In a notebook or async code: result = await Runner.run(agent, "Hello!")
result = Runner.run_sync(agent, "Hello!")This gets SKILL.md only. The skill's 1 other file is not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai]"
decimalai skills add pipelex-postman-bundleimport json
from openai import OpenAI
from decimalai.openai import agent_config
client = OpenAI()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
def lookup_order(order_id: str) -> str:
return f"Order {order_id} shipped yesterday."
# Your tools, as Chat Completions takes them, and what answers each.
TOOLS = [{"type": "function", "function": {
"name": "lookup_order",
"description": "Look up the status of an order.",
"parameters": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]},
}}]
FUNCTIONS = {"lookup_order": lookup_order}
question = "Where is order A1001?"
with support.run(question) as run: # one user message, one run
# run.system is your prompt, then the skill list.
messages = [{"role": "system", "content": run.system}, run.message]
while True:
reply = client.chat.completions.create(
model="gpt-5.4-mini",
messages=messages,
tools=[*TOOLS, *run.tools], # your tools, then load_skill
).choices[0].message
messages.append(reply)
if not reply.tool_calls:
break
for call in reply.tool_calls:
# load_skill is answered by the run; your own tools by FUNCTIONS.
function = FUNCTIONS.get(call.function.name)
messages.append(run.tool_result(call) or {
"role": "tool", "tool_call_id": call.id,
"content": function(**json.loads(call.function.arguments)) if function
else f"There is no tool named {call.function.name!r}.",
})
print(reply.content)
# The Responses API takes run.response_tools instead of run.tools.The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("pipelex-postman-bundle")
if result.exit_code:
raise SystemExit(result.problems)
import json
from openai import OpenAI
from decimalai.openai import agent_config
client = OpenAI()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
def lookup_order(order_id: str) -> str:
return f"Order {order_id} shipped yesterday."
# Your tools, as Chat Completions takes them, and what answers each.
TOOLS = [{"type": "function", "function": {
"name": "lookup_order",
"description": "Look up the status of an order.",
"parameters": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]},
}}]
FUNCTIONS = {"lookup_order": lookup_order}
question = "Where is order A1001?"
with support.run(question) as run: # one user message, one run
# run.system is your prompt, then the skill list.
messages = [{"role": "system", "content": run.system}, run.message]
while True:
reply = client.chat.completions.create(
model="gpt-5.4-mini",
messages=messages,
tools=[*TOOLS, *run.tools], # your tools, then load_skill
).choices[0].message
messages.append(reply)
if not reply.tool_calls:
break
for call in reply.tool_calls:
# load_skill is answered by the run; your own tools by FUNCTIONS.
function = FUNCTIONS.get(call.function.name)
messages.append(run.tool_result(call) or {
"role": "tool", "tool_call_id": call.id,
"content": function(**json.loads(call.function.arguments)) if function
else f"There is no tool named {call.function.name!r}.",
})
print(reply.content)
# The Responses API takes run.response_tools instead of run.tools.No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/pipelex-postman-bundle/SKILL.mdfrom pathlib import Path
from openai import OpenAI
client = OpenAI()
skill = Path(".agents/skills/pipelex-postman-bundle/SKILL.md").read_text()
reply = client.chat.completions.create(
model="gpt-5.4-mini",
messages=[
{"role": "system", "content": f"You are a helpful agent.\n\n{skill}"},
{"role": "user", "content": "Hello!"},
],
).choices[0].messageThis gets SKILL.md only. The skill's 1 other file is not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[anthropic]"
decimalai skills add pipelex-postman-bundleimport anthropic
from decimalai.anthropic import agent_config
client = anthropic.Anthropic()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
question = "Hello!"
with support.run(question) as run: # one user message, one run
answer = client.beta.messages.tool_runner(
model="claude-haiku-5-5",
max_tokens=4096,
system=run.system, # your prompt, then the skill list
tools=[*run.tools], # your tools, then load_skill
messages=[{"role": "user", "content": question}],
).until_done()The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[anthropic]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("pipelex-postman-bundle")
if result.exit_code:
raise SystemExit(result.problems)
import anthropic
from decimalai.anthropic import agent_config
client = anthropic.Anthropic()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
question = "Hello!"
with support.run(question) as run: # one user message, one run
answer = client.beta.messages.tool_runner(
model="claude-haiku-5-5",
max_tokens=4096,
system=run.system, # your prompt, then the skill list
tools=[*run.tools], # your tools, then load_skill
messages=[{"role": "user", "content": question}],
).until_done()No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/pipelex-postman-bundle/SKILL.mdfrom pathlib import Path
import anthropic
client = anthropic.Anthropic()
skill = Path(".agents/skills/pipelex-postman-bundle/SKILL.md").read_text()
reply = client.messages.create(
model="claude-haiku-5-5",
max_tokens=4096,
system=f"You are a helpful agent.\n\n{skill}",
messages=[{"role": "user", "content": "Hello!"}],
)This gets SKILL.md only. The skill's 1 other file is not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[google-genai]"
decimalai skills add pipelex-postman-bundlefrom google import genai
from google.genai import types
from decimalai.google_genai import agent_config
client = genai.Client()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
def lookup_order(order_id: str) -> str:
return f"Order {order_id} shipped yesterday."
# Your functions, as declarations for the model, and what answers each.
TOOLS = [{"function_declarations": [{
"name": "lookup_order",
"description": "Look up the status of an order.",
"parameters_json_schema": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]},
}]}]
FUNCTIONS = {"lookup_order": lookup_order}
question = "Where is order A1001?"
with support.run(question) as run: # one user message, one run
config = types.GenerateContentConfig(
system_instruction=run.system, # your prompt, then the skill list
tools=[*TOOLS, *run.tool_params], # your functions, then load_skill
)
contents = [{"role": "user", "parts": [{"text": run.message}]}]
while True:
response = client.models.generate_content(
model="gemini-3.5-flash", contents=contents, config=config,
)
if not response.function_calls:
break
contents.append(response.candidates[0].content)
parts = []
for call in response.function_calls:
# load_skill is answered by the run; your own functions by FUNCTIONS.
# A loop of your own rather than automatic function calling, which
# raises KeyError when the model asks for a function you did not pass.
function = FUNCTIONS.get(call.name)
parts.append(run.tool_result(call) or {"function_response": {
"name": call.name, "id": call.id,
"response": {"result": function(**(call.args or {})) if function
else f"There is no function named {call.name!r}."},
}})
contents.append({"role": "user", "parts": parts})
print(response.text)The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[google-genai]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("pipelex-postman-bundle")
if result.exit_code:
raise SystemExit(result.problems)
from google import genai
from google.genai import types
from decimalai.google_genai import agent_config
client = genai.Client()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
def lookup_order(order_id: str) -> str:
return f"Order {order_id} shipped yesterday."
# Your functions, as declarations for the model, and what answers each.
TOOLS = [{"function_declarations": [{
"name": "lookup_order",
"description": "Look up the status of an order.",
"parameters_json_schema": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]},
}]}]
FUNCTIONS = {"lookup_order": lookup_order}
question = "Where is order A1001?"
with support.run(question) as run: # one user message, one run
config = types.GenerateContentConfig(
system_instruction=run.system, # your prompt, then the skill list
tools=[*TOOLS, *run.tool_params], # your functions, then load_skill
)
contents = [{"role": "user", "parts": [{"text": run.message}]}]
while True:
response = client.models.generate_content(
model="gemini-3.5-flash", contents=contents, config=config,
)
if not response.function_calls:
break
contents.append(response.candidates[0].content)
parts = []
for call in response.function_calls:
# load_skill is answered by the run; your own functions by FUNCTIONS.
# A loop of your own rather than automatic function calling, which
# raises KeyError when the model asks for a function you did not pass.
function = FUNCTIONS.get(call.name)
parts.append(run.tool_result(call) or {"function_response": {
"name": call.name, "id": call.id,
"response": {"result": function(**(call.args or {})) if function
else f"There is no function named {call.name!r}."},
}})
contents.append({"role": "user", "parts": parts})
print(response.text)No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/pipelex-postman-bundle/SKILL.mdfrom pathlib import Path
from google import genai
from google.genai import types
client = genai.Client()
skill = Path(".agents/skills/pipelex-postman-bundle/SKILL.md").read_text()
response = client.models.generate_content(
model="gemini-3.5-flash",
contents="Hello!",
config=types.GenerateContentConfig(system_instruction=f"You are a helpful agent.\n\n{skill}"),
)This gets SKILL.md only. The skill's 1 other file is not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[langchain]" langchain-openai
decimalai skills add pipelex-postman-bundlefrom langchain.agents import create_agent
from decimalai.langchain import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = create_agent(
"openai:gpt-5.4-mini",
tools=[], # your tools; the middleware adds load_skill
middleware=[support.middleware], # your prompt, the skill list and load_skill
)
result = agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[langchain]" langchain-openaifrom decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("pipelex-postman-bundle")
if result.exit_code:
raise SystemExit(result.problems)
from langchain.agents import create_agent
from decimalai.langchain import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = create_agent(
"openai:gpt-5.4-mini",
tools=[], # your tools; the middleware adds load_skill
middleware=[support.middleware], # your prompt, the skill list and load_skill
)
result = agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/pipelex-postman-bundle/SKILL.mdfrom pathlib import Path
from langchain.agents import create_agent
skill = Path(".agents/skills/pipelex-postman-bundle/SKILL.md").read_text()
agent = create_agent("openai:gpt-5.4-mini", tools=[], system_prompt=f"You are a helpful agent.\n\n{skill}")
result = agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})This gets SKILL.md only. The skill's 1 other file is not included.
CrewAI's own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" "crewai>=1.15.27"
decimalai skills add pipelex-postman-bundleimport decimalai.crewai
from crewai import Agent, Crew, Task
agent = Agent(
role="Support", goal="Help the customer", backstory="A support agent.",
llm=llm, # your own CrewAI LLM
skills=decimalai.crewai.skills(), # the installed folder
tools=decimalai.crewai.skill_tools(), # reads a skill's files, runs its scripts
)
task = Task(description="Hello!", expected_output="an answer", agent=agent)
Crew(agents=[agent], tasks=[task]).kickoff()The same install from Python, for a notebook or a setup script. CrewAI's own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" "crewai>=1.15.27"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("pipelex-postman-bundle")
if result.exit_code:
raise SystemExit(result.problems)
import decimalai.crewai
from crewai import Agent, Crew, Task
agent = Agent(
role="Support", goal="Help the customer", backstory="A support agent.",
llm=llm, # your own CrewAI LLM
skills=decimalai.crewai.skills(), # the installed folder
tools=decimalai.crewai.skill_tools(), # reads a skill's files, runs its scripts
)
task = Task(description="Hello!", expected_output="an answer", agent=agent)
Crew(agents=[agent], tasks=[task]).kickoff()No DecimalAI package. CrewAI's own loader reads the folder, and nothing pins or updates it.
.agents/skills/pipelex-postman-bundle/SKILL.mdfrom pathlib import Path
from crewai import Agent, Crew, Task
agent = Agent(
role="Support", goal="Help the customer", backstory="A support agent.",
llm=llm, # your own CrewAI LLM
skills=[Path(".agents/skills")],
)
task = Task(description="Hello!", expected_output="an answer", agent=agent)
Crew(agents=[agent], tasks=[task]).kickoff()This gets SKILL.md only. The skill's 1 other file is not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[adk]"
decimalai skills add pipelex-postman-bundlefrom decimalai.adk import DecimalAIPlugin, agent_config
from google.adk.agents import LlmAgent
from google.adk.apps import App
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = LlmAgent(
name="support", # ADK needs a Python identifier
model="gemini-3.5-flash",
instruction=support.instruction, # your prompt, then the skill list
tools=[*support.tools], # your tools, then load_skill
)
# DecimalAIPlugin makes each invocation of runners built from this App one trace.
app = App(name="support", root_agent=agent, plugins=[DecimalAIPlugin()])Prefer ADK's own loader? SkillToolset(skills=decimalai.adk.skills(), ...) reads the same folder. Use one or the other: a skill delivered both ways reaches the prompt twice.
The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[adk]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("pipelex-postman-bundle")
if result.exit_code:
raise SystemExit(result.problems)
from decimalai.adk import DecimalAIPlugin, agent_config
from google.adk.agents import LlmAgent
from google.adk.apps import App
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = LlmAgent(
name="support", # ADK needs a Python identifier
model="gemini-3.5-flash",
instruction=support.instruction, # your prompt, then the skill list
tools=[*support.tools], # your tools, then load_skill
)
# DecimalAIPlugin makes each invocation of runners built from this App one trace.
app = App(name="support", root_agent=agent, plugins=[DecimalAIPlugin()])Prefer ADK's own loader? SkillToolset(skills=decimalai.adk.skills(), ...) reads the same folder. Use one or the other: a skill delivered both ways reaches the prompt twice.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/pipelex-postman-bundle/SKILL.mdfrom pathlib import Path
from google.adk.agents import LlmAgent
skill = Path(".agents/skills/pipelex-postman-bundle/SKILL.md").read_text()
agent = LlmAgent(
name="support",
model="gemini-3.5-flash",
instruction=lambda context: f"You are a helpful agent.\n\n{skill}",
)This gets SKILL.md only. The skill's 1 other file is not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[pydantic-ai]"
decimalai skills add pipelex-postman-bundlefrom pydantic_ai import Agent
from decimalai.pydantic_ai import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = Agent(
"openai:gpt-4o-mini",
name=support.name,
tools=[], # your tools; the capability adds load_skill
capabilities=[support], # your prompt, the skill list and load_skill
)
# In a notebook or async code: result = await agent.run("Hello!")
result = agent.run_sync("Hello!")On the Pydantic AI harness, decimalai.pydantic_ai_harness.skills(project) uses its own loader instead.
The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[pydantic-ai]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("pipelex-postman-bundle")
if result.exit_code:
raise SystemExit(result.problems)
from pydantic_ai import Agent
from decimalai.pydantic_ai import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = Agent(
"openai:gpt-4o-mini",
name=support.name,
tools=[], # your tools; the capability adds load_skill
capabilities=[support], # your prompt, the skill list and load_skill
)
# In a notebook or async code: result = await agent.run("Hello!")
result = agent.run_sync("Hello!")On the Pydantic AI harness, decimalai.pydantic_ai_harness.skills(project) uses its own loader instead.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/pipelex-postman-bundle/SKILL.mdfrom pathlib import Path
from pydantic_ai import Agent
skill = Path(".agents/skills/pipelex-postman-bundle/SKILL.md").read_text()
agent = Agent("openai:gpt-4o-mini", instructions=f"You are a helpful agent.\n\n{skill}")
# In a notebook or async code: result = await agent.run("Hello!")
result = agent.run_sync("Hello!")This gets SKILL.md only. The skill's 1 other file is not included.
Deep Agents' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" deepagents
decimalai skills add pipelex-postman-bundleimport decimalai.deepagents
from deepagents import create_deep_agent
agent = create_deep_agent(model=model, **decimalai.deepagents.skills())
agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})The default backend reads files but has no shell. To run a skill's scripts, pass skills(backend=LocalShellBackend(...)).
The same install from Python, for a notebook or a setup script. Deep Agents' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" deepagentsfrom decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("pipelex-postman-bundle")
if result.exit_code:
raise SystemExit(result.problems)
import decimalai.deepagents
from deepagents import create_deep_agent
agent = create_deep_agent(model=model, **decimalai.deepagents.skills())
agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})The default backend reads files but has no shell. To run a skill's scripts, pass skills(backend=LocalShellBackend(...)).
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/pipelex-postman-bundle/SKILL.mdfrom pathlib import Path
from deepagents import create_deep_agent
skill = Path(".agents/skills/pipelex-postman-bundle/SKILL.md").read_text()
agent = create_deep_agent(model=model, system_prompt=f"You are a helpful agent.\n\n{skill}")
agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})This gets SKILL.md only. The skill's 1 other file is not included.
Its own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" agent-framework
decimalai skills add pipelex-postman-bundleimport asyncio
from agent_framework import Agent
from decimalai.agent_framework import skills
agent = Agent(client=client, instructions="You are a helpful agent.", context_providers=[skills()])
asyncio.run(agent.run("Hello!"))It caches skills by default, so restart the process after decimalai skills update.
The same install from Python, for a notebook or a setup script. Its own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" agent-frameworkfrom decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("pipelex-postman-bundle")
if result.exit_code:
raise SystemExit(result.problems)
import asyncio
from agent_framework import Agent
from decimalai.agent_framework import skills
agent = Agent(client=client, instructions="You are a helpful agent.", context_providers=[skills()])
asyncio.run(agent.run("Hello!"))It caches skills by default, so restart the process after decimalai skills update.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/pipelex-postman-bundle/SKILL.mdimport asyncio
from pathlib import Path
from agent_framework import Agent
skill = Path(".agents/skills/pipelex-postman-bundle/SKILL.md").read_text()
agent = Agent(client=client, instructions=f"You are a helpful agent.\n\n{skill}")
asyncio.run(agent.run("Hello!"))This gets SKILL.md only. The skill's 1 other file is not included.
Strands' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" strands-agents
decimalai skills add pipelex-postman-bundlefrom decimalai.strands import skills
from strands import Agent
from strands.vended_tools import file_editor, shell
agent = Agent(
model=model, # always pass one: the default is Amazon Bedrock
system_prompt="You are a helpful agent.",
tools=[file_editor, shell],
plugins=[skills()],
)
agent("Hello!")Strands loads an agent's skills once, so build the agent again after decimalai skills update.
The same install from Python, for a notebook or a setup script. Strands' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" strands-agentsfrom decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("pipelex-postman-bundle")
if result.exit_code:
raise SystemExit(result.problems)
from decimalai.strands import skills
from strands import Agent
from strands.vended_tools import file_editor, shell
agent = Agent(
model=model, # always pass one: the default is Amazon Bedrock
system_prompt="You are a helpful agent.",
tools=[file_editor, shell],
plugins=[skills()],
)
agent("Hello!")Strands loads an agent's skills once, so build the agent again after decimalai skills update.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/pipelex-postman-bundle/SKILL.mdfrom pathlib import Path
from strands import Agent
skill = Path(".agents/skills/pipelex-postman-bundle/SKILL.md").read_text()
agent = Agent(model=model, system_prompt=f"You are a helpful agent.\n\n{skill}")
agent("Hello!")This gets SKILL.md only. The skill's 1 other file is not included.
Adds every file the skill has, pinned so you can update it. Cursor, Copilot, Cline and Warp read this folder by themselves.
pip install "decimalai>=0.15"
decimalai skills add pipelex-postman-bundleNo Python or account. Cursor, Copilot, Cline and Warp read this folder by themselves.
curl -fsSL --create-dirs -o .agents/skills/pipelex-postman-bundle/SKILL.md https://app.decimal.ai/s/pipelex-postman-bundle/SKILL.md.agents/skills/pipelex-postman-bundle/SKILL.mdThis gets SKILL.md only. The skill's 1 other file is not included.
Give its text to your model as instructions. No account or package needed.
This gets SKILL.md only. The skill's 1 other file is not included.
Raw files: /s/pipelex-postman-bundle/SKILL.md · /s/pipelex-postman-bundle.json
Fetch the file and give its text to your model as instructions. No account or package needed.
curl -fsSL https://app.decimal.ai/s/pipelex-postman-bundle/SKILL.mdcurl -fsSL https://app.decimal.ai/s/pipelex-postman-bundle.jsonThis gets SKILL.md only. The skill's 1 other file is not included.
You don't need a DecimalAI account.
Saved prompts and skills, pinned versions, and traces of this skill in your runs. DecimalAI does not run your agent.
Claude Code reads files from your project, so DecimalAI config does not apply there.
On Claude Agent SDK: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On OpenAI Agents: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On OpenAI SDK: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Anthropic: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Gemini API: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On LangChain: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On CrewAI: set DECIMAL_API_KEY and add decimalai.init(crewai=True) to record runs and skill use. The skill version stays in your repo.
On Google ADK: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Pydantic AI: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Deep Agents: set DECIMAL_API_KEY and add decimalai.init(langchain=True) to record runs and skill use. The skill version stays in your repo.
On Microsoft Agent Framework: set DECIMAL_API_KEY and add decimalai.init(otel=True, agent_name="support") to record runs and skill use. The skill version stays in your repo.
On Strands: set DECIMAL_API_KEY and add decimalai.init(otel=True, agent_name="support") to record runs and skill use. The skill version stays in your repo.
Editors read files from your project, so DecimalAI config does not apply there.
Anywhere else: record a use with decimalai.log_skill_activation() inside a trace.
Create runnable API requests for one Pipelex MTHDS bundle and push them into the live Pipelex FastAPI collection (or emit curl, or run them directly), so the user can exercise any bundle-shaped endpoint against a Pipelex API server. The query resolves the bundle the same way the CLI's pipelex run bundle <path> does.
This is a focused, one-bundle-at-a-time tool. It is not the full collection sync — for diffing the whole API surface against the code, that's the separate /update-postman command.
--endpoint | Route | Body beside files | Needs a pipe? | Needs inputs? | Inference? |
|---|---|---|---|---|---|
execute | POST /v1/execute | pipe_code, inputs | yes | yes | YES — costs money |
start | POST /v1/start | pipe_code, inputs, callback_urls | yes | yes | YES — costs money |
validate | POST /v1/validate | allow_signatures, optional render | no | no | no (free dry-run) |
resolve | POST /v1/resolve | nothing | no | no | no (free) |
codegen | POST /v1/codegen | kind, target | no | no | no (free) |
Every non-run endpoint answers with the /validate verdict discipline: a produced verdict is always a 200 discriminated on is_valid — the artifact on the valid arm, structured errors[] problem items on the invalid arm. Non-2xx is reserved for no-verdict conditions (request-shape 422, auth 401, server 5xx), rendered as RFC 9457 problem+json with a registry code.
For the bundle the user names, it upserts requests into the collection under:
Bundles/
<bundle>/ (named by the bundle's `domain`, or the filename)
Execute (sync) Start (async) Validate (dry-run)
Resolve (crate) Codegen (types → <target>)
Which requests appear depends on --endpoint: the default both is execute + start; every other endpoint is pushed alone. Pushes merge by request name — pushing --endpoint codegen doesn't wipe an Execute/Start pair pushed earlier, and two codegen targets (distinct names) coexist. Requests use the collection variable {{base_url}} and inherit the collection's {{auth_token}} bearer auth (and the Start request's callback_urls is the {{callback_url}} variable), so the same query works against a local or hosted server by switching the Postman environment.
(The top folder used to be Run Bundle/ — if a stale folder by that name lingers in the collection, it can be deleted.)
filesEvery route carries the method the same way: files, the MTHDS standard's map of file entries. Each key is a file's tree path, its path from the method tree's root, and each value is the file's UTF-8 text, or {"base64": "..."} for a file whose bytes are not UTF-8, such as an image or an office template:
{
"pipe_code": "greeting.greet",
"inputs": { "...": "inputs.json copied verbatim" },
"files": {
"bundle.mthds": "domain = \"greeting\"\nmain_pipe = \"greet\"\n...",
"templates/card.html": "<p>Hello, {{ text }}</p>\n",
"assets/logo.png": { "base64": "iVBORw0KGgo..." }
}
}
pipe_code and inputs ride execute/start only, allow_signatures and the optional render ride validate, and kind/target ride codegen; resolve sends files alone. The start body additionally carries callback_urls (see Callback URLs). files comes last in every body, so the fields you edit in Postman stay on top.
What travels is every file of the method's tree, listed by the mthds package's own lister, so it is judged by the same membership rule the runner and every MTHDS client apply (the standard's method-tree.md):
METHODS.toml, else the directory you point at. A .mthds file named alone with no METHODS.toml above it travels as the one-file tree of that file, nothing beside it..git/, .venv/, .env, .mthds/), __pycache__ and node_modules, virtual environments, nested repositories and nested packages, the tree's own .gitignored files and the manifest's [package] exclude patterns.inputs.json or inputs.toml, at any depth, out of every tree, and a runner applying that rule refuses such a key. The mthds lister pinned here still lists it, so the script drops it from files itself: the sibling inputs.json travels as inputs on execute/start and nowhere else.{"sha256", "size"}, names bytes the runner already holds in its blob store, which only an upload (POST /v1/blobs/missing, then PUT /v1/blobs/{sha256}) puts there. A Postman query or a curl command never uploads, so every file travels inline.mthds_contents, mthds_sources, bundle_b64 or resources.The listing stops at the runner's own limits on a tree a request sends (the MAX_METHOD_TREE_* limits of pipelex_api.limits), so pointing the skill at a large directory by mistake fails in moments. The script also refuses a main bundle the membership rule keeps out of the tree, such as a .gitignored one, since the pipe_code read from it would name a pipe the runner never receives.
The pipe_code the script infers is the main bundle's main_pipe qualified by that bundle's domain (greeting.greet, not greet): the whole tree travels, so a sibling bundle declaring a pipe of the same code would make a bare code ambiguous, which the runner refuses. An explicit --pipe is sent exactly as given.
POST /v1/validate is the API's dry-run: it parses, loads, and dry-runs every pipe with mock inputs and zero inference (no LLM calls, no cost), then returns the validated bundle blueprint, a graph_spec, and per-pipe input/output JSON-Schema pipe_io_contracts. It confirms the whole pipeline wires up without ever running it — the safe, free counterpart to execute/start. Reach for it to "just check" or "dry-run" a bundle.
main_pipe is optional for /validate. A bundle with no main_pipe still validates (200, is_valid: true) — you just get graph_spec: null. --pipe is ignored.allow_signatures (--allow-signatures) tolerates unimplemented pipe signatures instead of rejecting the bundle (each dry-runs trivially by minting a mock). Useful for in-progress bundles. It parameterizes the dry-run sweep, so it rides validate only — the crate routes run no sweep and do not accept it. Default strict.render (--render markdown) opts into a server-rendered Markdown view of the verdict, riding the 200 on both arms as rendered_markdown. This is what a skill-driven validate sends; a hook omits it and reads the structured is_valid. The structured fields stay the contract; the Markdown is the view.POST /v1/resolve resolves the library closure into its normalized crate — fully qualified refs, flattened refinement, materialized natives, fingerprint set. It runs no dry-run sweep (runnability is /validate's vocabulary). The valid arm carries the canonical JSON crate — the same bytes pipelex resolve --format json prints, so a fingerprint computed from either surface agrees.
POST /v1/codegen resolves the closure the same way, then projects the crate through two explicit axes: kind (only types is served — an inputs template is projected client-side from the input form POST /v1/pipe-io serves) × target:
ts-zod — zod schemas + inferred TypeScript typespython-pydantic — self-contained pydantic BaseModelspython-structures — Pipelex runtime StructuredContent classes (a Pipelex extension)The valid arm carries the stamped artifact set plus its codegen.lock: a client that writes them verbatim reproduces a local pipelex codegen types run byte-for-byte and passes the offline pipelex codegen check. There is deliberately no server-side check route (the drift check is offline by design). An unknown kind/target, or a pipe_ref on the concept-set-wide types, is a request-shape 422.
--target is required for codegen — there is no default; ask the user which consumer they're generating for if unclear. The request also accepts a method_ref instead of files (an address-form reference is fetched and resolved; the registry form is a 422 request.unsupported) — this skill always sends files.
start endpoint)/v1/start is fire-and-forget: it returns a run_id immediately and POSTs the finished result to a webhook later, so a start request must carry callback_urls.
Postman push (default mode) always uses the {{callback_url}} collection variable — never a baked-in URL. The pushed body is "callback_urls": ["{{callback_url}}"], so the callback is switchable in the Postman environment right alongside base_url and auth_token (local vs hosted). Nothing to resolve — just tell the user to set callback_url in their Postman environment (a https://webhook.site/... endpoint is the easy way to watch the result land).
--run / --curl (a real HTTP call, or a preview of one) need a concrete URL. Resolution order there:
--callback-url <url> (repeatable — the field is a JSON list; a single URL is the common case).CALLBACK_URL in the environment or the repo .env. make exports .env; the script also reads .env directly when invoked outside make.--callback-url.This only affects start — no other endpoint takes callback_urls. The API's SSRF guard rejects loopback/private/metadata hosts, so a localhost callback won't validate — use a public https:// URL.
Every command on this page runs from api/, the server's directory in the pipelex repository: cd api first, or prefix the make targets with -C api from the repository root (make -C api bundle-run …), and give BUNDLE and the script's paths relative to api/. The script lists the method's tree with the mthds package and reads the runner's limits from pipelex_api, so it runs with the server's own environment, api/.venv, never a bare python3. The make targets are the convenient wrapper: they install that environment, then run the script with it.
make bundle-run BUNDLE=<dir|.mthds> # POST to a running API, print the response
make bundle-validate BUNDLE=<dir|.mthds> # dry-run validate via /v1/validate (free)
make bundle-resolve BUNDLE=<dir|.mthds> # resolve to the normalized crate (free)
make bundle-codegen BUNDLE=<dir|.mthds> TARGET=ts-zod # project typed artifacts + lock (free)
make bundle-curl BUNDLE=<dir|.mthds> # emit a ready-to-run curl
make bundle-postman BUNDLE=<dir|.mthds> # push request(s) into the Postman collection
make bundle-dry BUNDLE=<dir|.mthds> # print the request body only
# optional: ENDPOINT=execute|start|validate|resolve|codegen|both
# PIPE=<code> INPUTS=<path> NAME=<folder> ALLOW_SIGNATURES=1 TARGET=<codegen target>
# CALLBACK_URL=<url> BASE_URL=<url> TOKEN=<bearer> ARGS=<extra>
bundle-validate / bundle-resolve / bundle-codegen hardcode --run with their endpoint (they're free and safe to run live).
Under the hood it's one script that resolves the bundle once and sends the request to one of four sinks. <bundle-path> is a bundle directory (preferred) or a single .mthds file. Call the script directly for a path outside the repo or finer control, with the server's environment (make install creates it when it is missing):
Push into the Postman collection (default). Source the env first so the Postman key is present (it lives in ~/.zshenv):
source ~/.zshenv 2>/dev/null
.venv/bin/python .claude/skills/postman-bundle/scripts/build_postman_query.py <bundle-path> [--endpoint <ep>] [--target <t>]
After a successful push, tell the user it's in Postman (it auto-syncs), and that they should set base_url and auth_token in their Postman environment, then Send.
Run it yourself from Claude Code — POSTs the exact same body to a running API and prints the response:
.venv/bin/python .claude/skills/postman-bundle/scripts/build_postman_query.py <bundle-path> --run --endpoint <ep>
# defaults to http://127.0.0.1:8081 and no auth (AUTH_MODE=none). Override:
# --base-url https://api.pipelex.com --token <bearer>
The API must be up — start it locally with make run first. Heads-up: only execute/start trigger real inference (cost + latency) — confirm the user wants a live run for those. Every other endpoint is free and safe to fire without confirmation:
.venv/bin/python .claude/skills/postman-bundle/scripts/build_postman_query.py <bundle-path> --run --endpoint validate
.venv/bin/python .claude/skills/postman-bundle/scripts/build_postman_query.py <bundle-path> --run --endpoint resolve
.venv/bin/python .claude/skills/postman-bundle/scripts/build_postman_query.py <bundle-path> --run --endpoint codegen --target python-pydantic
Emit a curl command (--curl) — writes the body to a temp file and prints a curl --data @file, so the files' contents never need shell escaping. Preview only (--dry-run) — print the request body, touch nothing. Every mode prints the tree's root and the files it sends first, marking those that travel in Base64.
Useful options (apply across modes):
| Option | When to use |
|---|---|
--endpoint <ep> | Pick the endpoint (see cheat sheet). Default both (= execute + start) for Postman/curl; --run both runs execute. |
--target <t> | (codegen only, required) ts-zod, python-pydantic, or python-structures. |
--allow-signatures | (validate only) Tolerate unimplemented pipe signatures. Default strict. |
--render <fmt> | (validate only) Opt-in server-side view, e.g. --render markdown → response carries rendered_markdown (what a skill-driven validate sends). Omit for the lean structured body a hook reads. Repeatable. |
--inputs <path> | Inputs JSON lives elsewhere, or you point at a .mthds file directly (file mode does not auto-detect inputs). execute/start only. |
--pipe <pipe_code> | The bundle has no main_pipe, or you want a different pipe. Used by execute/start (as pipe_code, exactly as given, so write domain.pipe_code when another bundle of the tree declares the same code); ignored by validate/resolve/codegen. |
--callback-url <url> | (start only) Webhook the async result is POSTed to. Repeatable. Falls back to CALLBACK_URL in env/.env. |
--base-url / --token | Target server + bearer for --run/--curl. |
--name <folder> | Override the per-bundle Postman subfolder name. |
--run (execute; confirm first — real inference).--run --endpoint validate (or make bundle-validate).--run --endpoint resolve.--run --endpoint codegen --target <t> — ask which target if the user didn't say.--endpoint.--curl. Just checking resolution → --dry-run.pipelex run bundle)bundle.mthds if present, else the single *.mthds in the dir. Multiple .mthds and no bundle.mthds is ambiguous → ask the user to pass the file directly. The sibling inputs.json is auto-detected. The directory's whole method tree is sent as files, its bundles in subdirectories included, so multi-file methods resolve..mthds file → the main bundle is that file, and the tree it belongs to is sent: the package's tree when a METHODS.toml sits at or above its directory, else that one file. Inputs only come from --inputs.pipe_code (run routes) is the main bundle's main_pipe, qualified by its domain (override with --pipe, sent as given).inputs is the inputs.json content copied verbatim — exactly what the API receives, same as the CLI. The file itself is never one of the files.We are not doing uploads. If inputs.json references a local file (e.g. "url": "inputs/cv.pdf"), the script copies it verbatim and prints a warning listing those URLs. Pass that warning on to the user: those entries must be replaced with real https:// URLs before the request will run. Prefer demoing on a self-contained, text-input bundle.
The method's own files are a different matter: a template, an image or a module the steps read travels in files with the bundles. Python is the one limit: a tree holding a .py file runs only on a sandbox-hosted runner (any other answers a 501), and a Python structure class is refused on every runner, so a method whose concepts rely on a structures/ folder of Python classes, rather than inline [concept.X.structure] blocks, will not run over the API — flag that if you see a structures/ dir doing real work.
POSTMAN_API_KEY → the script exits asking you to source ~/.zshenv. Do that and retry. If still unset, the user needs to add it (Postman → Settings → API keys → Generate).main_pipe and no --pipe (execute/start) → the script exits; ask the user which pipe and pass --pipe.codegen without --target → the script exits listing the three targets; ask the user which consumer they're generating for.start selected via --run/--curl and no callback URL → the script exits. Resolve from --callback-url, CALLBACK_URL in .env, or ask the user (e.g. a https://webhook.site/... endpoint). (The Postman push never hits this — it uses the {{callback_url}} variable and needs no resolution.)main_pipe, validating/resolving → fine, not an error: those endpoints need no pipe; validate just returns graph_spec: null.METHODS.toml, a tree past the runner's limits) or the main bundle is outside its own tree (.gitignored, say) → the script exits naming the cause; fix the method's directory, or point at the method's own folder rather than a directory above it.ModuleNotFoundError: mthds or pipelex_api → the script ran with the wrong interpreter: use .venv/bin/python from api/ (make install creates it) or a make bundle-* target.35082494-559c5753-885c-409a-af63-7647fe28d301 (Pipelex FastAPI). Override with --collection-uid.https://api.getpostman.com (the script handles GET + PUT).Skills that do similar work, with their headline benchmark lift.
From the same source and nearby in the catalogue.