# manifest.py — static metadata seeded into the database
MANIFEST = {
"id": "linear",
"name": "Linear",
"auth_type": "oauth2",
"oauth_authorize_url": "https://linear.app/oauth/authorize",
"oauth_token_url": "https://api.linear.app/oauth/token",
"oauth_scopes": ["read", "write"],
"oauth_credential_fields": [
{"name": "client_id", "label": "Client ID", "secret": False, "required": True},
{"name": "client_secret", "label": "Client Secret", "secret": True, "required": True},
{"name": "redirect_uri", "label": "Redirect URI (optional)", "secret": False, "required": False},
],
"actions": [
{
"name": "linear_create_issue",
"display_name": "Create Issue",
"description": "Create a new issue in a Linear team",
"tags": ["linear", "write"],
"input_schema": { "type": "object", "required": ["title"],
"properties": {"title": {"type": "string"}} },
}
],
}
# provider.py — execution logic
from src.providers.base import BaseProvider
class LinearProvider(BaseProvider):
provider_id = "linear"
async def execute_tool(self, action_name: str, input_data: dict, credentials: dict) -> dict:
if action_name == "linear_create_issue":
# call Linear API with credentials["access_token"]
...
raise ValueError(f"Unknown action: {action_name}")
async def refresh_token(self, credentials: dict) -> dict:
return credentials # Linear tokens don't expire; override if needed
# __init__.py — empty, required to make this a Python package