# Pith > Pith is where vibe-coded projects go to grow up. Push your code, get it live, and let Pith help your agent spot problems before they bite you. Hosting, diagnostics, task tracking, and project memory - your agent learns the tools as it uses them. All functionality is exposed as MCP tools. One endpoint, no REST API. Your agent connects to /mcp/ with a token or OAuth 2.1 and gets to work. ## Connecting - MCP endpoint: /mcp/ (streamable HTTP, stateless) - Auth option 1: Agent token - Authorization: Token - Auth option 2: OAuth 2.1 (RFC 9728) - standard authorization code flow - Discovery: GET /.well-known/mcp.json - Registration: POST /register/ with {"email": "...", "agent_name": "..."} - Registration status: GET /register/status// MCP config example: ```json { "pith": { "type": "http", "url": "https://usepith.dev/mcp/", "headers": { "Authorization": "Token YOUR_TOKEN_HERE" } } } ``` ## Project Reference Format Many tools accept a project parameter using string references: - "org-slug/project-slug" - target a specific project - "org-slug/*" - all accessible projects in that org (search only) - "personal" - personal memories not tied to any project ## Batch-First API Design Tools that create or search accept both a single dict and a list of dicts. The return type mirrors the input. Batch calls are more efficient: embedding generation uses a single API call regardless of batch size. ## Async Runs (call-now / fetch-later) Some tools do work that exceeds the ~60s MCP request budget (a deploy, a multi-step diagnosis). These tools use the call-now / fetch-later pattern: the initial call enqueues the work on a Celery worker and returns immediately; the result is fetched later with a second tool call. How to recognise an async-run tool: 1. The first call returns `{"run_id": "", "status": "pending"}` instead of the tool's real result. 2. Poll `pith_async_run_get(run_id="")` until `status` reaches a terminal value. The real result lands in the `result` field of the envelope. Envelope shape returned by `pith_async_run_get`: ```json { "id": "", "status": "pending|running|succeeded|failed|cancelled|terminated", "result": { ... } | null, "error": {"type": "...", "message": "...", "traceback_sha": "..."} | null, "created_at": "", "started_at": "" | null, "finished_at": "" | null } ``` Lifecycle: - `pending` - row created, waiting for a worker to pick it up - `running` - worker has started executing; `started_at` is stamped - `succeeded` - terminal; `result` is populated, `error` is null - `failed` - terminal; `error` is populated. `result` may also be populated when the tool reported partial output before failing (e.g. an `image_tag` from a build that succeeded before deploy failed). - `cancelled` - terminal; the run cooperatively stopped - `terminated` - terminal; the worker was restarted while the run was in-flight and the startup sweep marked it stranded The four terminal statuses (`succeeded`, `failed`, `cancelled`, `terminated`) are the only stop conditions for polling. Suggested poll interval: 1-2 seconds. Authorization: only the user who created the run may poll it. Any other case - run does not exist, belongs to another user, or has been soft-deleted by the retention sweep - returns the same generic error ("No async run with id is accessible to you."). This is deliberate: the error shape does not let a caller enumerate run existence across users. Size caps: oversized start arguments are rejected before the row is written; oversized results cause the run to transition to `failed` with a `ResultTooLarge` error envelope rather than `succeeded`. The exact byte limits are server-side settings. Retention: terminal runs are soft-deleted after `PITH_ASYNC_RUNS_RETENTION_HOURS` (every-six-hours sweep). Poll for the result before retention kicks in, or store the result yourself if you need it long-term. Tools that use this pattern at time of writing: `pith_app_deploy`, `pith_diag_ask`. New async tools will document `(async-run)` in their description below. pith_async_run_get - Fetch the current state (and, if terminal, the result) of an async run. Argument: `run_id`. Returns the envelope above. Raises `AsyncRunAccessDenied` for any non-accessible run. ## Memory Tools pith_memory_store - Store one or more memories. Accepts single dict or list. Fields: content (required), memory_type (default "context"), importance (1-10, default 5), task_id (optional). Embeddings generated automatically. pith_memory_update - Update memory by UUID. Changed content triggers embedding regeneration. pith_memory_delete - Soft-delete a memory by UUID. ## Task Tools pith_task_create - Create one or more tasks. Batch-first with "$N" cross-references for dependencies. Fields: title (required), description, priority (1-10), status (open/in_progress/done), assigned_to, due_at, parent_task, blocked_by. pith_task_update - Update one or more tasks. Supports add_blocked_by and remove_blocked_by for dependency management. pith_task_delete - Soft-delete a task. pith_task_comment - Add a comment to a task (stored as a linked memory). pith_task_relationship_create - Create a relationship between two tasks (blocks, relates_to, duplicates). pith_task_relationship_delete - Delete a task relationship. pith_task_relationship_list - List relationships for a task. pith_task_attachment_upload - Upload a file attachment to a task. pith_task_attachment_update - Update attachment metadata. pith_task_attachment_delete - Delete an attachment. ## Tag Tools pith_tag_modify - Modify an existing tag (rename, recolor, re-describe, or delete via `delete=True`). Tags are auto-created when first referenced by name from `pith_task_create` / `pith_task_update`, so there is no separate create tool. ## Git Tools pith_git_create_repo - Create a new git repository with SSH access. pith_git_delete_repo - Delete a repository. ## SSH Key Tools pith_ssh_register_key - Register an SSH public key for git access. pith_ssh_list_keys - List SSH keys for the current agent. pith_ssh_revoke_key - Revoke an SSH key. ## Hosting Tools pith_app_deploy - Deploy an app from a git repo: build, provision DB, Kubernetes deploy, health check. Supports buildpack detection, container builds, TLS, and DNS. (async-run - see "Async Runs" above; first call returns `{run_id, status}`, poll `pith_async_run_get` for the result.) ## Diagnostics Tools pith_diag_ask - Ask natural language diagnostic questions about app health. (async-run - see "Async Runs" above; first call returns `{run_id, status}`, poll `pith_async_run_get` for the result.) pith_diag_status - Get high-level app health summary (containers, resources, errors, deploys). ## Organization Tools pith_org_list - List accessible organizations. pith_org_create - Create a new organization with a default project. pith_org_update - Update org name, slug, or autonomous flag. pith_org_add_member - Add a member to the organization. pith_org_remove_member - Remove a member from the organization. ## Project Tools pith_project_create - Create a new project in an organization. pith_project_update - Update project name or slug. pith_project_delete - Soft-delete a project. ## Auth Tools pith_auth_whoami - Get current agent identity and permissions. ## Usage & Feedback Tools pith_usage_status - Get current month usage statistics for an org. pith_feedback_suggest - Submit feedback (feature requests, bugs, improvements). pith_audit_log - Get recent audit events for a project. ## Federated Search pith_search - Search across memories, tasks, and git repos in one call. Returns unified results ranked by relevance. Filter by content type with `source_models=['memory'|'task'|'gitrepo'|...]`, fetch a specific record with `id=''`, or include change history with `include_history=True`. This is the canonical read tool — per-type read tools have been retired.