Compare commits

..

2 Commits

Author SHA1 Message Date
iris-clawd
75ef1ecf91 test: add test script for LinearTool 2026-04-20 15:08:13 -03:00
iris-clawd
7961678879 feat: add LinearTool for Linear project management API 2026-04-20 15:08:04 -03:00
5 changed files with 192 additions and 256 deletions

View File

@@ -83,7 +83,6 @@ intelligent automations.
## Table of contents
- [Build with AI](#build-with-ai)
- [Why CrewAI?](#why-crewai)
- [Getting Started](#getting-started)
- [Key Features](#key-features)
@@ -102,22 +101,6 @@ intelligent automations.
- [Telemetry](#telemetry)
- [License](#license)
## Build with AI
Using an AI coding agent? Teach it CrewAI best practices in one command:
**Claude Code:**
```shell
/plugin marketplace add crewAIInc/skills
```
**Cursor, Codex, Windsurf, and others ([skills.sh](https://skills.sh/crewaiinc/skills)):**
```shell
npx skills add crewaiinc/skills
```
This installs the official [CrewAI Skills](https://github.com/crewAIInc/skills) — structured instructions that teach coding agents how to scaffold Flows, configure Crews, design agents and tasks, and follow CrewAI patterns.
## Why CrewAI?
<div align="center" style="margin-bottom: 30px;">

124
crewai/tools/linear_tool.py Normal file
View File

@@ -0,0 +1,124 @@
import os
from enum import Enum
from typing import Any, Type
import httpx
from crewai.tools import BaseTool
from pydantic import BaseModel, Field
LINEAR_API_URL = "https://api.linear.app/graphql"
class LinearAction(str, Enum):
MY_ISSUES = "my_issues"
LIST_TEAMS = "list_teams"
LIST_PROJECTS = "list_projects"
class LinearToolInput(BaseModel):
action: LinearAction = Field(
description=(
"Action to perform: "
"'my_issues' — fetch issues assigned to the authenticated user; "
"'list_teams' — list all teams in the workspace; "
"'list_projects' — list all projects in the workspace."
)
)
first: int = Field(
default=25,
ge=1,
le=250,
description="Maximum number of records to return (1250).",
)
_QUERIES: dict[LinearAction, str] = {
LinearAction.MY_ISSUES: """
query MyIssues($first: Int!) {
viewer {
assignedIssues(first: $first, orderBy: updatedAt) {
nodes {
id
identifier
title
state { name }
priority
url
updatedAt
}
}
}
}
""",
LinearAction.LIST_TEAMS: """
query ListTeams($first: Int!) {
teams(first: $first) {
nodes {
id
name
key
description
}
}
}
""",
LinearAction.LIST_PROJECTS: """
query ListProjects($first: Int!) {
projects(first: $first, orderBy: updatedAt) {
nodes {
id
name
description
state
url
updatedAt
}
}
}
""",
}
def _extract(action: LinearAction, data: dict) -> list[dict]:
if action == LinearAction.MY_ISSUES:
return data["viewer"]["assignedIssues"]["nodes"]
if action == LinearAction.LIST_TEAMS:
return data["teams"]["nodes"]
if action == LinearAction.LIST_PROJECTS:
return data["projects"]["nodes"]
return []
class LinearTool(BaseTool):
name: str = "Linear API Tool"
description: str = (
"Interact with the Linear project management API. "
"Supports fetching your assigned issues, listing teams, and listing projects."
)
args_schema: Type[BaseModel] = LinearToolInput
def _run(self, action: LinearAction, first: int = 25) -> Any:
api_key = os.environ.get("LINEAR_API_KEY", "")
if not api_key:
raise EnvironmentError("LINEAR_API_KEY environment variable is not set.")
query = _QUERIES[action]
payload = {"query": query, "variables": {"first": first}}
headers = {
"Authorization": api_key,
"Content-Type": "application/json",
}
response = httpx.post(
LINEAR_API_URL,
json=payload,
headers=headers,
timeout=15,
)
response.raise_for_status()
body = response.json()
if "errors" in body:
raise RuntimeError(f"Linear API errors: {body['errors']}")
return _extract(action, body["data"])

View File

@@ -78,7 +78,6 @@
{
"group": "Get Started",
"pages": [
"en/guides/coding-tools/build-with-ai",
"en/introduction",
"en/skills",
"en/installation",
@@ -128,8 +127,7 @@
"group": "Coding Tools",
"icon": "terminal",
"pages": [
"en/guides/coding-tools/agents-md",
"en/guides/coding-tools/build-with-ai"
"en/guides/coding-tools/agents-md"
]
},
{
@@ -554,7 +552,6 @@
{
"group": "Get Started",
"pages": [
"en/guides/coding-tools/build-with-ai",
"en/introduction",
"en/skills",
"en/installation",
@@ -604,8 +601,7 @@
"group": "Coding Tools",
"icon": "terminal",
"pages": [
"en/guides/coding-tools/agents-md",
"en/guides/coding-tools/build-with-ai"
"en/guides/coding-tools/agents-md"
]
},
{
@@ -1030,7 +1026,6 @@
{
"group": "Get Started",
"pages": [
"en/guides/coding-tools/build-with-ai",
"en/introduction",
"en/skills",
"en/installation",
@@ -1080,8 +1075,7 @@
"group": "Coding Tools",
"icon": "terminal",
"pages": [
"en/guides/coding-tools/agents-md",
"en/guides/coding-tools/build-with-ai"
"en/guides/coding-tools/agents-md"
]
},
{
@@ -1506,7 +1500,6 @@
{
"group": "Get Started",
"pages": [
"en/guides/coding-tools/build-with-ai",
"en/introduction",
"en/skills",
"en/installation",
@@ -1556,8 +1549,7 @@
"group": "Coding Tools",
"icon": "terminal",
"pages": [
"en/guides/coding-tools/agents-md",
"en/guides/coding-tools/build-with-ai"
"en/guides/coding-tools/agents-md"
]
},
{
@@ -1982,7 +1974,6 @@
{
"group": "Get Started",
"pages": [
"en/guides/coding-tools/build-with-ai",
"en/introduction",
"en/skills",
"en/installation",
@@ -2032,8 +2023,7 @@
"group": "Coding Tools",
"icon": "terminal",
"pages": [
"en/guides/coding-tools/agents-md",
"en/guides/coding-tools/build-with-ai"
"en/guides/coding-tools/agents-md"
]
},
{
@@ -2458,7 +2448,6 @@
{
"group": "Get Started",
"pages": [
"en/guides/coding-tools/build-with-ai",
"en/introduction",
"en/skills",
"en/installation",
@@ -2508,8 +2497,7 @@
"group": "Coding Tools",
"icon": "terminal",
"pages": [
"en/guides/coding-tools/agents-md",
"en/guides/coding-tools/build-with-ai"
"en/guides/coding-tools/agents-md"
]
},
{
@@ -2932,7 +2920,6 @@
{
"group": "Get Started",
"pages": [
"en/guides/coding-tools/build-with-ai",
"en/introduction",
"en/skills",
"en/installation",
@@ -2982,8 +2969,7 @@
"group": "Coding Tools",
"icon": "terminal",
"pages": [
"en/guides/coding-tools/agents-md",
"en/guides/coding-tools/build-with-ai"
"en/guides/coding-tools/agents-md"
]
},
{
@@ -3406,7 +3392,6 @@
{
"group": "Get Started",
"pages": [
"en/guides/coding-tools/build-with-ai",
"en/introduction",
"en/skills",
"en/installation",
@@ -3456,8 +3441,7 @@
"group": "Coding Tools",
"icon": "terminal",
"pages": [
"en/guides/coding-tools/agents-md",
"en/guides/coding-tools/build-with-ai"
"en/guides/coding-tools/agents-md"
]
},
{
@@ -3881,7 +3865,6 @@
{
"group": "Get Started",
"pages": [
"en/guides/coding-tools/build-with-ai",
"en/introduction",
"en/skills",
"en/installation",
@@ -3931,8 +3914,7 @@
"group": "Coding Tools",
"icon": "terminal",
"pages": [
"en/guides/coding-tools/agents-md",
"en/guides/coding-tools/build-with-ai"
"en/guides/coding-tools/agents-md"
]
},
{
@@ -4357,7 +4339,6 @@
{
"group": "Get Started",
"pages": [
"en/guides/coding-tools/build-with-ai",
"en/introduction",
"en/skills",
"en/installation",
@@ -4407,8 +4388,7 @@
"group": "Coding Tools",
"icon": "terminal",
"pages": [
"en/guides/coding-tools/agents-md",
"en/guides/coding-tools/build-with-ai"
"en/guides/coding-tools/agents-md"
]
},
{
@@ -4831,7 +4811,6 @@
{
"group": "Get Started",
"pages": [
"en/guides/coding-tools/build-with-ai",
"en/introduction",
"en/skills",
"en/installation",
@@ -4881,8 +4860,7 @@
"group": "Coding Tools",
"icon": "terminal",
"pages": [
"en/guides/coding-tools/agents-md",
"en/guides/coding-tools/build-with-ai"
"en/guides/coding-tools/agents-md"
]
},
{

View File

@@ -1,206 +0,0 @@
---
title: "Build with AI"
description: "Everything AI coding agents need to build, deploy, and scale with CrewAI — skills, machine-readable docs, deployment, and enterprise features."
icon: robot
mode: "wide"
---
# Build with AI
CrewAI is AI-native. This page brings together everything an AI coding agent needs to build with CrewAI — whether you're Claude Code, Codex, Cursor, Gemini CLI, or any other assistant helping a developer ship crews and flows.
### Supported Coding Agents
<CardGroup cols={5}>
<Card title="Claude Code" icon="message-bot" color="#D97706" />
<Card title="Cursor" icon="arrow-pointer" color="#3B82F6" />
<Card title="Codex" icon="terminal" color="#10B981" />
<Card title="Windsurf" icon="wind" color="#06B6D4" />
<Card title="Gemini CLI" icon="sparkles" color="#8B5CF6" />
</CardGroup>
<Note>
This page is designed to be consumed by both humans and AI assistants. If you're a coding agent, start with **Skills** to get CrewAI context, then use **llms.txt** for full docs access.
</Note>
---
## 1. Skills — Teach Your Agent CrewAI
**Skills** are instruction packs that give coding agents deep CrewAI knowledge — how to scaffold Flows, configure Crews, use tools, and follow framework conventions.
<Tabs>
<Tab title="Claude Code (Plugin Marketplace)">
<img src="https://cdn.simpleicons.org/anthropic/D97706" alt="Anthropic" width="28" style={{display: "inline", verticalAlign: "middle", marginRight: "8px"}} />
CrewAI skills are available in the **Claude Code plugin marketplace** — the same distribution channel used by top AI-native companies:
```
/plugin marketplace add crewAIInc/skills
```
</Tab>
<Tab title="npx (Any Agent)">
Works with Claude Code, Codex, Cursor, Gemini CLI, or any coding agent:
```shell
npx skills add crewaiinc/skills
```
Pulls from the [skills.sh registry](https://skills.sh/crewaiinc/skills).
</Tab>
</Tabs>
<Steps>
<Step title="Install the official skill pack">
Use either method above — the Claude Code plugin marketplace or `npx skills add`. Both install the official [crewAIInc/skills](https://github.com/crewAIInc/skills) pack.
</Step>
<Step title="Your agent gets instant CrewAI expertise">
The skill pack teaches your agent:
- **Flows** — stateful apps, steps, and crew kickoffs
- **Crews & Agents** — YAML-first patterns, roles, tasks, delegation
- **Tools & Integrations** — search, APIs, MCP servers, and common CrewAI tools
- **Project layout** — CLI scaffolds and repo conventions
- **Up-to-date patterns** — tracks current CrewAI docs and best practices
</Step>
<Step title="Start building">
Your agent can now scaffold and build CrewAI projects without you re-explaining the framework each session.
</Step>
</Steps>
<CardGroup cols={2}>
<Card title="Skills concept" icon="bolt" href="/en/concepts/skills">
How skills work in CrewAI agents — injection, activation, and patterns.
</Card>
<Card title="Skills landing page" icon="wand-magic-sparkles" href="/en/skills">
Overview of the crewAIInc/skills pack and what it includes.
</Card>
<Card title="AGENTS.md & coding tools" icon="terminal" href="/en/guides/coding-tools/agents-md">
Set up AGENTS.md for Claude Code, Codex, Cursor, and Gemini CLI.
</Card>
<Card title="Skills registry (skills.sh)" icon="globe" href="https://skills.sh/crewaiinc/skills">
Official listing — skills, install stats, and audits.
</Card>
</CardGroup>
---
## 2. llms.txt — Machine-Readable Docs
CrewAI publishes an `llms.txt` file that gives AI assistants direct access to the full documentation in a machine-readable format.
```
https://docs.crewai.com/llms.txt
```
<Tabs>
<Tab title="What is llms.txt?">
[`llms.txt`](https://llmstxt.org/) is an emerging standard for making documentation consumable by large language models. Instead of scraping HTML, your agent can fetch a single structured text file with all the content it needs.
CrewAI's `llms.txt` is **already live** — your agent can use it right now.
</Tab>
<Tab title="How to use it">
Point your coding agent at the URL when it needs CrewAI reference docs:
```
Fetch https://docs.crewai.com/llms.txt for CrewAI documentation.
```
Many coding agents (Claude Code, Cursor, etc.) can fetch URLs directly. The file contains structured documentation covering all CrewAI concepts, APIs, and guides.
</Tab>
<Tab title="Why it matters">
- **No scraping required** — clean, structured content in one request
- **Always up-to-date** — served directly from docs.crewai.com
- **Optimized for LLMs** — formatted for context windows, not browsers
- **Complements skills** — skills teach patterns, llms.txt provides reference
</Tab>
</Tabs>
---
## 3. Deploy to Enterprise
Go from a local crew to production on **CrewAI AMP** (Agent Management Platform) in minutes.
<Steps>
<Step title="Build locally">
Scaffold and test your crew or flow:
```bash
crewai create crew my_crew
cd my_crew
crewai run
```
</Step>
<Step title="Prepare for deployment">
Ensure your project structure is ready:
```bash
crewai deploy --prepare
```
See the [preparation guide](/en/enterprise/guides/prepare-for-deployment) for details on project structure and requirements.
</Step>
<Step title="Deploy to AMP">
Push to the CrewAI AMP platform:
```bash
crewai deploy
```
You can also deploy via [GitHub integration](/en/enterprise/guides/deploy-to-amp) or [Crew Studio](/en/enterprise/guides/enable-crew-studio).
</Step>
<Step title="Access via API">
Your deployed crew gets a REST API endpoint. Integrate it into any application:
```bash
curl -X POST https://app.crewai.com/api/v1/crews/<crew-id>/kickoff \
-H "Authorization: Bearer $CREWAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"inputs": {"topic": "AI agents"}}'
```
</Step>
</Steps>
<CardGroup cols={2}>
<Card title="Deploy to AMP" icon="rocket" href="/en/enterprise/guides/deploy-to-amp">
Full deployment guide — CLI, GitHub, and Crew Studio methods.
</Card>
<Card title="AMP introduction" icon="globe" href="/en/enterprise/introduction">
Platform overview — what AMP provides for production crews.
</Card>
</CardGroup>
---
## 4. Enterprise Features
CrewAI AMP is built for production teams. Here's what you get beyond deployment.
<CardGroup cols={2}>
<Card title="Observability" icon="chart-line">
Detailed execution traces, logs, and performance metrics for every crew run. Monitor agent decisions, tool calls, and task completion in real time.
</Card>
<Card title="Crew Studio" icon="paintbrush">
No-code/low-code interface to create, customize, and deploy crews visually — then export to code or deploy directly.
</Card>
<Card title="Webhook Streaming" icon="webhook">
Stream real-time events from crew executions to your systems. Integrate with Slack, Zapier, or any webhook consumer.
</Card>
<Card title="Team Management" icon="users">
SSO, RBAC, and organization-level controls. Manage who can create, deploy, and access crews across your team.
</Card>
<Card title="Tool Repository" icon="toolbox">
Publish and share custom tools across your organization. Install community tools from the registry.
</Card>
<Card title="Factory (Self-Hosted)" icon="server">
Run CrewAI AMP on your own infrastructure. Full platform capabilities with data residency and compliance controls.
</Card>
</CardGroup>
<AccordionGroup>
<Accordion title="Who is AMP for?">
AMP is for teams that need to move AI agent workflows from prototypes to production — with observability, access controls, and scalable infrastructure. Whether you're a startup or enterprise, AMP handles the operational complexity so you can focus on building agents.
</Accordion>
<Accordion title="What deployment options are available?">
- **Cloud (app.crewai.com)** — managed by CrewAI, fastest path to production
- **Factory (self-hosted)** — run on your own infrastructure for full data control
- **Hybrid** — mix cloud and self-hosted based on sensitivity requirements
</Accordion>
<Accordion title="How does pricing work?">
Sign up at [app.crewai.com](https://app.crewai.com) to see current plans. Enterprise and Factory pricing is available on request.
</Accordion>
</AccordionGroup>
<Card title="Explore CrewAI AMP →" icon="arrow-right" href="https://app.crewai.com">
Sign up and deploy your first crew to production.
</Card>

View File

@@ -0,0 +1,57 @@
"""
Test script for LinearTool — runs against the real Linear API.
Usage:
LINEAR_API_KEY=lin_api_xxxxxxxxxxxx python tests/tools/test_linear_tool.py
Set LINEAR_API_KEY to your actual Personal API key from:
https://linear.app/settings/api (Profile → API → Personal API keys)
"""
import json
import os
import sys
from crewai.tools.linear_tool import LinearAction, LinearTool
def pretty(data: object) -> str:
return json.dumps(data, indent=2, default=str)
def run_test(tool: LinearTool, label: str, action: LinearAction, first: int = 5) -> None:
print(f"\n{'' * 60}")
print(f" {label}")
print(f"{'' * 60}")
try:
result = tool._run(action=action, first=first)
if not result:
print(" (no records returned)")
else:
print(pretty(result))
except Exception as exc:
print(f" ERROR: {exc}", file=sys.stderr)
def main() -> None:
if not os.environ.get("LINEAR_API_KEY"):
print(
"ERROR: Set LINEAR_API_KEY before running.\n"
" export LINEAR_API_KEY=lin_api_xxxxxxxxxxxx",
file=sys.stderr,
)
sys.exit(1)
tool = LinearTool()
run_test(tool, "My assigned issues (up to 5)", LinearAction.MY_ISSUES, first=5)
run_test(tool, "Teams (up to 10)", LinearAction.LIST_TEAMS, first=10)
run_test(tool, "Projects (up to 10)", LinearAction.LIST_PROJECTS, first=10)
print(f"\n{'' * 60}")
print(" All tests complete.")
print(f"{'' * 60}\n")
if __name__ == "__main__":
main()