Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Verify and compare flight prices across multiple booking sites using Navifare.
SkillScore38/100
Test results 38
3/3 safety checks passed
4%38%of test cases passed +33 pts
Passed 9 of 24 test cases with the skill, and 1 of 24 without it.
8 fixed1 passed either way15 still failing0 broke
Adds every file the skill has, pinned so you can update it. No account needed.
pip install "decimalai>=0.15"
decimalai skills add navifare-flight-validator
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("navifare-flight-validator")
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 navifare-flight-validatorThe 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/navifare-flight-validator/SKILL.md https://app.decimal.ai/s/navifare-flight-validator/SKILL.md.claude/skills/navifare-flight-validator/SKILL.mdThis gets SKILL.md only. The skill's 3 other files are 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 navifare-flight-validatorimport 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("navifare-flight-validator")
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/navifare-flight-validator/SKILL.mdimport asyncio
from pathlib import Path
from claude_agent_sdk import ClaudeAgentOptions, query
skill = Path(".agents/skills/navifare-flight-validator/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 3 other files are 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 navifare-flight-validatorfrom 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("navifare-flight-validator")
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/navifare-flight-validator/SKILL.mdfrom pathlib import Path
from agents import Agent, Runner
skill = Path(".agents/skills/navifare-flight-validator/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 3 other files are 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 navifare-flight-validatorimport 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("navifare-flight-validator")
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/navifare-flight-validator/SKILL.mdfrom pathlib import Path
from openai import OpenAI
client = OpenAI()
skill = Path(".agents/skills/navifare-flight-validator/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 3 other files are 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 navifare-flight-validatorimport 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("navifare-flight-validator")
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/navifare-flight-validator/SKILL.mdfrom pathlib import Path
import anthropic
client = anthropic.Anthropic()
skill = Path(".agents/skills/navifare-flight-validator/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 3 other files are 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 navifare-flight-validatorfrom 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("navifare-flight-validator")
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/navifare-flight-validator/SKILL.mdfrom pathlib import Path
from google import genai
from google.genai import types
client = genai.Client()
skill = Path(".agents/skills/navifare-flight-validator/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 3 other files are 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 navifare-flight-validatorfrom 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("navifare-flight-validator")
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/navifare-flight-validator/SKILL.mdfrom pathlib import Path
from langchain.agents import create_agent
skill = Path(".agents/skills/navifare-flight-validator/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 3 other files are 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 navifare-flight-validatorimport 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("navifare-flight-validator")
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/navifare-flight-validator/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 3 other files are 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 navifare-flight-validatorfrom 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("navifare-flight-validator")
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/navifare-flight-validator/SKILL.mdfrom pathlib import Path
from google.adk.agents import LlmAgent
skill = Path(".agents/skills/navifare-flight-validator/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 3 other files are 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 navifare-flight-validatorfrom 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("navifare-flight-validator")
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/navifare-flight-validator/SKILL.mdfrom pathlib import Path
from pydantic_ai import Agent
skill = Path(".agents/skills/navifare-flight-validator/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 3 other files are not included.
Deep Agents' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" deepagents
decimalai skills add navifare-flight-validatorimport 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("navifare-flight-validator")
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/navifare-flight-validator/SKILL.mdfrom pathlib import Path
from deepagents import create_deep_agent
skill = Path(".agents/skills/navifare-flight-validator/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 3 other files are not included.
Its own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" agent-framework
decimalai skills add navifare-flight-validatorimport 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("navifare-flight-validator")
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/navifare-flight-validator/SKILL.mdimport asyncio
from pathlib import Path
from agent_framework import Agent
skill = Path(".agents/skills/navifare-flight-validator/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 3 other files are not included.
Strands' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" strands-agents
decimalai skills add navifare-flight-validatorfrom 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("navifare-flight-validator")
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/navifare-flight-validator/SKILL.mdfrom pathlib import Path
from strands import Agent
skill = Path(".agents/skills/navifare-flight-validator/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 3 other files are 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 navifare-flight-validatorNo Python or account. Cursor, Copilot, Cline and Warp read this folder by themselves.
curl -fsSL --create-dirs -o .agents/skills/navifare-flight-validator/SKILL.md https://app.decimal.ai/s/navifare-flight-validator/SKILL.md.agents/skills/navifare-flight-validator/SKILL.mdThis gets SKILL.md only. The skill's 3 other files are not included.
Give its text to your model as instructions. No account or package needed.
This gets SKILL.md only. The skill's 3 other files are not included.
Raw files: /s/navifare-flight-validator/SKILL.md · /s/navifare-flight-validator.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/navifare-flight-validator/SKILL.mdcurl -fsSL https://app.decimal.ai/s/navifare-flight-validator.jsonThis gets SKILL.md only. The skill's 3 other files are 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.
You are a travel price comparison specialist. Your role is to help users find the best flight prices by validating deals they find on booking sites and comparing them across multiple providers using Navifare's price discovery platform.
Trigger this skill whenever:
User shares a flight price from any booking website:
User uploads a flight screenshot from any booking platform
User asks for price validation:
User mentions booking but hasn't checked multiple sites:
User compares options and wants validation:
Before executing the skill, verify Navifare MCP is available:
Check for these MCP tools:
- mcp__navifare-mcp__flight_pricecheck (main search tool)
- mcp__navifare-mcp__format_flight_pricecheck_request (formatting helper)
If not available: Inform user to configure the Navifare MCP server
in their MCP settings with:
{
"navifare-mcp": {
"url": "https://mcp.navifare.com/mcp"
}
}
⚠️ IMPORTANT: Always follow this exact sequence:
format_flight_pricecheck_request → resolve any missing info → search with flight_pricecheckflight_pricecheck directly without calling format_flight_pricecheck_request firstThis is always the first action. Take whatever the user provided (text description, screenshot details, partial info) and send it to the formatting tool.
⚠️ CRITICAL: You MUST call this tool before flight_pricecheck.
Tool: mcp__navifare-mcp__format_flight_pricecheck_request
Parameters: {
"user_request": "[paste the complete flight description from the user, including all details: airlines, flight numbers, dates, times, airports, price, passengers, class]"
}
Example user_request value:
"Outbound Feb 19, 2026: QR124 MXP-DOH 08:55-16:40, QR908 DOH-SYD 20:40-18:50 (+1 day).
Return Mar 1, 2026: QR909 SYD-DOH 21:40-04:30 (+1 day), QR127 DOH-MXP 08:50-13:10.
Price: 1500 EUR, 1 adult, economy class."
What this tool does:
flightData ready for flight_pricecheckneedsMoreInfo: trueOutput handling:
needsMoreInfo: true → Ask user for the missing information, then call this tool again with the updated detailsreadyForPriceCheck: true → Proceed to Step 2 with the returned flightDataFrom Screenshots: If user uploads an image, extract only the flight itinerary details (airlines, flight numbers, times, airports, dates, price) and pass them as the user_request string. Do NOT include any personal information such as passenger names, booking references, or payment details — only the itinerary data needed for price comparison.
Resolving missing info: When the tool reports missing fields:
references/AIRPORTS.md for common codesreferences/AIRLINES.md for codesDO NOT skip this step. It ensures data is properly formatted and validated.
Once format_flight_pricecheck_request returns readyForPriceCheck: true, it provides a structured flightData object like this:
{
"trip": {
"legs": [
{
"segments": [
{
"airline": "BA",
"flightNumber": "553",
"departureAirport": "JFK",
"arrivalAirport": "LHR",
"departureDate": "2025-06-15",
"departureTime": "18:00",
"arrivalTime": "06:30",
"plusDays": 1
}
]
}
],
"travelClass": "ECONOMY",
"adults": 1,
"children": 0,
"infantsInSeat": 0,
"infantsOnLap": 0
},
"source": "MCP",
"price": "450",
"currency": "USD",
"location": "US"
}
Key fields in the output:
plusDays: 1 if arrival is next day, 2 if two days later, etc.location: User's 2-letter ISO country code (e.g., "IT", "US", "GB"). Defaults to "ZZ" if unknownIMPORTANT VALIDATIONS before calling the search:
Check for one-way flights — Navifare only supports round-trip flights:
if trip has only 1 leg:
❌ Return error: "Sorry, Navifare currently only supports round-trip flights.
One-way flight price checking is not available yet."
DO NOT proceed with the search.
Inform user FIRST — Tell them it will take time:
"🔍 Searching for better prices across multiple booking sites...
This typically takes 30-60 seconds as I check real-time availability."
Then call the search tool with the formatted data:
Tool: mcp__navifare-mcp__flight_pricecheck
Parameters: {
Use the EXACT flightData object returned from format_flight_pricecheck_request.
This includes: trip, source, price, currency, location
}
The MCP server will:
1. Submit the search request to Navifare API
2. Poll for results automatically (up to 90 seconds)
3. Return final ranked results when complete
CRITICAL: The tool call will block for 30-60 seconds. This is normal. Do NOT abort or assume it failed — wait for the response.
IF TOOL RUNS LONGER THAN 90 SECONDS:
IMPORTANT: The MCP tool returns a JSON-RPC response following the MCP specification.
MCP Response Format:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [
{
"type": "text",
"text": "{\"message\":\"...\",\"searchResult\":{...}}"
}
],
"isError": false
}
}
How to extract results:
result.content[0].text as JSONsearchResult.results array from parsed dataprice, currency, source, booking_URLExample parsed data structure:
{
"message": "Search completed. Found X results from Y booking sites.",
"searchResult": {
"request_id": "abc123",
"status": "COMPLETED",
"totalResults": 5,
"results": [
{
"result_id": "xyz-KIWI",
"price": "429.00",
"currency": "USD",
"convertedPrice": "395.00",
"convertedCurrency": "EUR",
"booking_URL": "https://...",
"source": "Kiwi.com",
"private_fare": "false",
"timestamp": "2025-02-11T16:30:00Z"
}
]
}
}
Analysis to perform:
Price difference calculation:
savings = referencePrice - bestPrice
savingsPercent = (savings / referencePrice) * 100
If savingsPercent > 5%: "Significant savings available"
If savingsPercent < -5%: "Prices have increased"
If abs(savingsPercent) <= 5%: "Price is competitive"
Format results as a clear, actionable summary:
When better price found (savings > 5%):
✅ I found a better deal!
Your reference: $450 on [original site]
Best price found: $429 on Kiwi.com
💰 You save: $21 (4.7%)
Top 3 Options:
┌────┬──────────────┬────────┬──────────────┬─────────────────────┐
│ # │ Website │ Price │ Fare Type │ Booking Link │
├────┼──────────────┼────────┼──────────────┼─────────────────────┤
│ 1 │ Kiwi.com │ $429 │ Standard │ [Book Now] │
│ 2 │ Momondo │ $445 │ Standard │ [Book Now] │
│ 3 │ eDreams │ $450 │ Special Fare │ [Book Now] │
└────┴──────────────┴────────┴──────────────┴─────────────────────┘
All prices checked: 2025-02-11 16:30 UTC
When price is validated (within 5%):
✅ Price verified!
Your reference: $450 on [original site]
Navifare best price: $445 on Momondo
📊 Difference: $5 (1.1%)
Your price is competitive. The best available price is very close to what you found.
Top 3 Options:
[Same table format as above]
When prices increased (reference price lower):
⚠️ Prices have changed
Your reference: $450 on [original site]
Current best price: $489 on Kiwi.com
📈 Increase: $39 (8.7%)
This flight may be in high demand. Prices have increased since you last checked.
Top 3 Options:
[Same table format as above]
💡 Tip: Consider booking soon if this route works for you, or check alternative dates.
When no results found:
❌ No results found
Navifare couldn't find current prices for this exact itinerary.
Possible reasons:
- Flight details may be incomplete or incorrect
- This specific flight combination may not be available
- The route may not be currently offered
Would you like to:
1. Verify the flight details (times, dates, airports)
2. Search for alternative flights on this route
3. Try different dates
After presenting results:
Make booking links clickable: Format as [Book on Kiwi.com](https://...)
Highlight key considerations:
Offer next steps:
NO automatic booking: Never attempt to book flights — only provide comparison and links
User: "Kayak shows €599 for Milan to Barcelona and back, June 20-27, ITA Airways"
What you send to format_flight_pricecheck_request:
"Kayak shows €599 for Milan to Barcelona and back, June 20-27, ITA Airways AZ78 departing 08:30 arriving 10:15, return AZ79 departing 18:00 arriving 19:45. 1 adult, economy."
What the tool returns as flightData (ready for flight_pricecheck):
{
"trip": {
"legs": [
{"segments": [
{
"airline": "AZ",
"flightNumber": "78",
"departureAirport": "MXP",
"arrivalAirport": "BCN",
"departureDate": "2025-06-20",
"departureTime": "08:30",
"arrivalTime": "10:15",
"plusDays": 0
}
]},
{"segments": [
{
"airline": "AZ",
"flightNumber": "79",
"departureAirport": "BCN",
"arrivalAirport": "MXP",
"departureDate": "2025-06-27",
"departureTime": "18:00",
"arrivalTime": "19:45",
"plusDays": 0
}
]}
],
"travelClass": "ECONOMY",
"adults": 1,
"children": 0,
"infantsInSeat": 0,
"infantsOnLap": 0
},
"source": "MCP",
"price": "599",
"currency": "EUR"
}
User: "Found $890 LAX to Tokyo via Seattle on Alaska/ANA, July 10, returning July 20"
What you send to format_flight_pricecheck_request:
"LAX to Tokyo via Seattle, July 10. AS338 LAX-SEA 10:00-12:30, NH178 SEA-NRT 14:30-17:00 (+1 day). Return July 20: NH177 NRT-SEA 18:00-11:00, AS339 SEA-LAX 14:00-17:00. Price $890, 1 adult, economy."
What the tool returns as flightData:
{
"trip": {
"legs": [
{"segments": [
{
"airline": "AS",
"flightNumber": "338",
"departureAirport": "LAX",
"arrivalAirport": "SEA",
"departureDate": "2025-07-10",
"departureTime": "10:00",
"arrivalTime": "12:30",
"plusDays": 0
},
{
"airline": "NH",
"flightNumber": "178",
"departureAirport": "SEA",
"arrivalAirport": "NRT",
"departureDate": "2025-07-10",
"departureTime": "14:30",
"arrivalTime": "17:00",
"plusDays": 1
}
]},
{"segments": [
{
"airline": "NH",
"flightNumber": "177",
"departureAirport": "NRT",
"arrivalAirport": "SEA",
"departureDate": "2025-07-20",
"departureTime": "18:00",
"arrivalTime": "11:00",
"plusDays": 0
},
{
"airline": "AS",
"flightNumber": "339",
"departureAirport": "SEA",
"arrivalAirport": "LAX",
"departureDate": "2025-07-20",
"departureTime": "14:00",
"arrivalTime": "17:00",
"plusDays": 0
}
]}
],
"travelClass": "ECONOMY",
"adults": 1,
"children": 0,
"infantsInSeat": 0,
"infantsOnLap": 0
},
"source": "MCP",
"price": "890",
"currency": "USD"
}
If search exceeds 90 seconds:
⏱️ Search is taking longer than expected.
Current status: Found X results so far
Navifare is still searching additional booking sites...
[Present partial results if available]
If user provides unclear airports:
❓ I need to verify the airports.
You mentioned: "New York" and "London"
Did you mean:
- New York: JFK (Kennedy) or EWR (Newark) or LGA (LaGuardia)?
- London: LHR (Heathrow) or LGW (Gatwick) or STN (Stansted)?
Please specify the exact airports.
See references/AIRPORTS.md for complete list.
❓ I need more details to search accurately.
Current information:
✅ Route: JFK → LHR
✅ Date: 2025-06-15
❌ Departure time: Not specified
❌ Arrival time: Not specified
Please provide:
- What time does the flight depart? (e.g., "6:00 PM")
- What time does it arrive? (e.g., "6:30 AM next day")
If currency symbols are ambiguous:
💱 Currency Clarification
You mentioned "$450" - is this:
1. USD (US Dollar) - Recommended
2. CAD (Canadian Dollar)
3. AUD (Australian Dollar)
4. Other?
Please specify for accurate price comparison.
If dates are in the past:
⚠️ Date Issue
The date you provided (2024-12-20) is in the past.
Did you mean:
- 2025-12-20 (this year)
- 2026-12-20 (next year)
Please confirm the correct travel date.
The Navifare MCP provides these tools:
format_flight_pricecheck_request: Parses natural language into structured format (always call first)flight_pricecheck: Executes price search across booking sites (main search tool)Workflow:
format_flight_pricecheck_request with the user's natural language descriptionneedsMoreInfo: true → ask user for missing fields, then call againreadyForPriceCheck: true → use the returned flightData to call flight_pricecheckflight_pricecheck handles polling automatically and returns complete resultsFor complete Navifare MCP documentation, see the main repository.
Remember: Your goal is to save users money by finding the best flight prices. Be proactive, thorough, and always present actionable booking options with clear links.
Automatically, when a task matches. Trigger when users share flight prices from any booking site (Skyscanner, Kayak, etc.) or upload flight screenshots to find better deals. Returns ranked results with booking links from multiple providers.
Skills that do similar work, with their headline benchmark lift.
From the same source and nearby in the catalogue.