{"tools":[{"name":"get_project_details","alias":"karma_project_get_details","description":"Fetch the full record for a single project: title, description, problem/solution, members, link counts, and milestone counts. Use this when the user asks about a specific project by name or slug, or when you need the project owner / metadata before suggesting an action. For a quick health check (\"is this project active?\", \"how is it going?\") prefer get_project_status — it is cheaper and returns completion percentages directly. NEVER call this in a loop to enumerate many projects; for that use list-style tools first to narrow.","category":"project","requiresAuth":false},{"name":"get_project_status","alias":"karma_project_get_status","description":"Concise health snapshot for a project, distinguishing the two kinds of milestones Karma tracks: (1) ROADMAP milestones the project owner sets on the project itself, and (2) GRANT milestones tied to specific funding (one set per grant). Returns separate counts for each plus an overall total — never collapse them, since a project with 0 roadmap milestones can still have completed grant milestones (or vice-versa). Use this when the user asks \"how is X doing?\", \"what is the status of X?\", or wants a single-paragraph summary. Do NOT use this when the user needs the full project description, member roles, or per-milestone titles — call get_project_details / list_project_milestones for those. For per-program scoped progress (\"how is X doing in program Y?\") call get_project_progress_in_program.","category":"project","requiresAuth":false},{"name":"list_project_milestones","alias":"karma_project_list_milestones","description":"List a project's milestones — BOTH the project's own roadmap milestones AND its grant-tied milestones (grouped by grant). Use this when the user asks \"what milestones does X have?\", \"show me X's milestone updates\", \"what work is left?\", or wants per-milestone titles. Each item carries a `kind` field: \"roadmap\" (set by the project owner on the project itself) or \"grant\" (tied to a specific funding grant). Grant items also carry grantUid, grantTitle, and programId for chaining. Pass `grantUid` to scope the list to ONE grant — use this when the user already named a specific grant or program. For a numeric overview (\"how many milestones total / completed?\") prefer get_project_status — cheaper. For program-scoped progress (\"how is X doing in program Y?\") prefer get_project_progress_in_program — accepts programId directly. Page through results with the page parameter; defaults to page 1 with up to 20 items.","category":"project","requiresAuth":false},{"name":"get_program_details","alias":"karma_program_get_details","description":"Fetch a single funding program: name, description, intake form schema, status, deadlines, and configuration. Use this when the user mentions a specific program by name or ID and you need its setup before answering. For listing many programs in a community use list_community_programs first; for application-level questions use list_program_applications or get_application_details. NEVER fabricate program names, deadlines, or eligibility criteria — return only what this tool provides.","category":"program","requiresAuth":false},{"name":"list_community_programs","alias":"karma_community_list_programs","description":"List every funding program registered under a community (e.g. all Filecoin programs). Returns program IDs, names, statuses, and basic stats. Use this when the user asks \"what programs does community X run?\" or needs to discover programs before drilling into one. For details on a specific program from the list, follow up with get_program_details. NEVER list programs for a community the user has not explicitly named — ask which community they mean instead of guessing.","category":"program","requiresAuth":false},{"name":"generate_program_report","alias":"karma_program_generate_report","description":"Generate analytics report for a program including application statistics.","category":"program","requiresAuth":false},{"name":"get_program_application_form","alias":"karma_application_get_form","description":"Get the intake form schema for a funding program, showing what fields the applicant needs to fill in. Use this before submitting an application to know the required fields.","category":"program","requiresAuth":false},{"name":"list_milestone_completions","alias":"karma_milestone_list_completions","description":"List every milestone completion submitted by an application — text, verification status, who verified it and when. Use this when the user asks \"what milestones has X completed?\", \"is this application up to date?\", or wants to see grantee progress against the funding plan. For ONE specific milestone (when you know its field label and title) prefer get_milestone_completion. For program-wide pending work across many applications use list_pending_milestones.","category":"milestone","requiresAuth":false},{"name":"get_milestone_completion","alias":"karma_milestone_get_completion","description":"Fetch ONE specific milestone completion by application + field label + title. Returns the completion text, verification status, verifier, and timestamps. Use this when the user wants details on a specific milestone they have already named. NEVER call this without first knowing the exact milestoneFieldLabel and milestoneTitle — use list_milestone_completions to discover what is available, then call this to drill in.","category":"milestone","requiresAuth":false},{"name":"list_pending_milestones","alias":"karma_program_list_pending_milestones","description":"Across all approved applications in a program, find those with at least one unverified milestone completion. Returns one row per application with the count of pending milestones. Use this when the user asks \"what needs my review?\", \"what milestones are waiting on us?\", or wants the program-wide review queue. For per-application detail (which specific milestones are pending) follow up with list_milestone_completions on each reference number.","category":"milestone","requiresAuth":false},{"name":"get_payout_history","alias":"karma_payout_get_history","description":"List all completed and pending disbursements for a single grant: amounts, tokens, statuses, timestamps. Use this when the user asks \"how much has X received?\", \"what payouts have gone out for grant Y?\", or wants the full ledger of disbursements for one grant. For a single rolled-up total instead of the full list, prefer get_total_disbursed (cheaper, one number). For pending disbursements across an entire community use list_pending_disbursements.","category":"payout","requiresAuth":false},{"name":"get_total_disbursed","alias":"karma_payout_get_total_disbursed","description":"Single rolled-up total: how much has been disbursed across all payouts for one grant. Returns just `{ grantUID, totalDisbursed }`. Use this when the user asks \"how much has X been paid?\", \"what is the running total for grant Y?\". Do NOT use this when the user wants the breakdown by payout — call get_payout_history for that.","category":"payout","requiresAuth":false},{"name":"list_pending_disbursements","alias":"karma_payout_list_pending","description":"List disbursements for one community that are awaiting execution: amounts, recipient grants, statuses. Use this when the user asks \"what payouts are queued for community X?\", \"how many pending payouts do we have?\", or wants the work-to-do list before a treasury batch. For payouts that have ALREADY been initiated and are waiting for multi-sig signatures, use list_awaiting_signatures instead — different stage of the pipeline.","category":"payout","requiresAuth":false},{"name":"get_grant_agreement","alias":"karma_grant_get_agreement","description":"Fetch the grant agreement record for a single grant: signed-by addresses, status (active/revoked), template version. Returns `agreement: null` when no agreement exists yet — that means the grant has not been formalized. Use this when the user asks \"is grant X signed?\", \"what does the agreement for Y say?\". For a list of agreements across many grants in a program, use list_grant_agreements (cheaper than calling this in a loop).","category":"grant_agreement","requiresAuth":false},{"name":"get_project_context","alias":"karma_project_get_context","description":"Bundle the two reads a project owner usually chains for a status check: project details (title, owner, members, communities) + per-milestone status (titles, due dates, completion). Use this when the user asks \"what is happening with my project\", \"give me the full project picture\", or before suggesting an action that needs both project metadata and milestone state. Saves 1 tool call vs. chaining get_project_details + list_project_milestones manually. For just a one-line health snapshot prefer get_project_status (cheaper). NEVER call this for projects the user has not named explicitly — for discovery, ask the user which project they mean.","category":"workflow","requiresAuth":false},{"name":"get_process_guide","alias":"karma_process_get_guide","description":"Search for and retrieve a program's official process guide by program name. You MUST use this tool when a user asks process-related questions like how to submit milestones, manage their grant, or follow program procedures. If the tool returns found=false, tell the user that no process guide is available for that program. NEVER fabricate or improvise process steps from your own knowledge — only use content returned by this tool. Ask the user which program they are referring to if not clear from the conversation.","category":"knowledge","requiresAuth":false},{"name":"search_customer_docs","alias":"karma_customer_search_docs","description":"Search customer-specific guides, how-tos, and process documentation. Use this before answering customer process questions. Do not invent process steps when no matching documentation is returned.","category":"knowledge","requiresAuth":false},{"name":"query_community_metrics","alias":"karma_community_query_metrics","description":"Fetch community metrics from Karma data. Use this for questions about customer or community data, trends, reporting numbers, and metric-backed analysis.","category":"community","requiresAuth":false},{"name":"search_knowledge_base","alias":"karma_knowledge_base_search","description":"Search this community's curated knowledge base. CALL THIS FIRST for ANY question that mentions a topic, term, acronym, project name, program name, person, ecosystem, or process — including things that sound like a program lookup. The KB is where curators publish the canonical answer; only fall back to other tools (programs, applications, projects) if this returns no hits. Returns excerpts with source URLs you must cite. If results are empty, tell the user the topic is not covered — never fabricate an answer from general knowledge. Do not ask clarifying questions before searching; search first, clarify only if results are ambiguous.","category":"knowledge","requiresAuth":false},{"name":"answer_process_question","alias":"karma_process_answer_question","description":"Answer a specific process question by extracting the most relevant section(s) from a program’s official process guide. Use this when the user asks a focused HOW question (\"how do I submit a milestone update?\", \"what is the review timeline?\") and you can name the program. Returns deterministically-scored top sections plus the source URL as a citation. Saves ~80% tokens vs. get_process_guide for narrow questions. For broad questions (\"walk me through the whole process\"), prefer get_process_guide. NEVER paraphrase from your own knowledge — this tool returns the literal guide content.","category":"knowledge","requiresAuth":false},{"name":"discover","alias":"karma_search_discover","description":"Cross-resource search across Karma projects, communities, AND funding programs by partial name, slug, or description. Each result is labelled with `type: \"project\" | \"community\" | \"program\"` so you can pick the right follow-up tool. Use this FIRST when the user names something loosely without saying which type (\"what is drand?\", \"who got funded in ProPGF Batch 2?\", \"find filecoin\") — it is the cheapest way to resolve a free-form name before chaining into `get_project_details`, `get_community_overview`, or `get_program_details`/`get_program_funding_summary`. If the user explicitly said \"project\", \"community\", or \"program\", call the type-specific tool directly to save a hop.","category":"workflow","requiresAuth":false},{"name":"get_community_overview","alias":"karma_community_get_overview","description":"Single-call snapshot of a Karma community: metadata (name, description, image), aggregate stats (project count, grant count, milestone completion %), and the list of active funding programs. Use this when the user asks \"tell me about <community>\", \"what is <community> on Karma?\", \"what programs does <community> run?\", or any open-ended community question. Saves 2–3 tool calls vs. chaining detail + stats + program listing manually. For per-program detail (form, applications, reviewers) call get_program_details with a programId from the response.","category":"community","requiresAuth":false},{"name":"get_program_funding_summary","alias":"karma_program_get_funding_summary","description":"Single-call summary of approved/funded applications in a program: project names, amounts, totals per currency. Use this when the user asks \"who got funded in <program>?\", \"how much has program X disbursed?\", or \"what projects did <program> fund?\". Public-safe — strips applicant PII. Saves N tool calls vs. chaining list_program_applications + get_application_details per row. For per-application detail (form responses, comments, AI score) call get_application_details with a referenceNumber from this response.","category":"program","requiresAuth":false},{"name":"get_project_disbursement_total","alias":"karma_project_get_disbursement_total","description":"Single-call total of how much has actually been DISBURSED (paid out on-chain) to a project across ALL grants and programs. Different from \"approved amount\" — disbursed = funds actually transferred. Use this when the user asks \"how much has X received?\", \"how much has been paid out to project Y?\", or wants the running total of payouts. Returns a roll-up plus per-(program, token) breakdown — each row carries programId + grant title so the agent can chain into get_program_details or get_payout_history without an extra hop. For per-payout breakdown of one specific grant call get_payout_history.","category":"project","requiresAuth":false},{"name":"get_project_progress_in_program","alias":"karma_project_get_progress_in_program","description":"Single-call milestone-progress snapshot for a project SCOPED TO ONE PROGRAM. Use this whenever the user asks \"how many milestones has project X completed in <program>?\", \"how is X doing in <program>?\", or any per-program progress question. Different from list_project_milestones — that returns ALL milestones across all programs the project participates in. Returns 404-style envelope (reason=not_found) when the project has no grant in the given program — do NOT silently report \"0 milestones\" in that case.","category":"project","requiresAuth":false},{"name":"get_project_indicators","alias":"karma_project_get_indicators","description":"Single-call list of impact indicators (self-reported metrics) tracked by a project, with their datapoints. Use this when the user asks \"what indicators does X track?\", \"show me X's impact metrics\", \"how many users/transactions/TVL has X reported?\", or wants to read what the public /project/:slug/impact page shows. Each indicator carries id, name, unit-of-measure, last-updated timestamp, and (in detailed mode) the raw datapoints + aggregated views. Different from get_project_status — that returns milestone progress, NOT impact metrics. Returns an empty list (not an error) when the project has no indicators set up yet — many projects don't track impact metrics, so report that plainly without retrying.","category":"project","requiresAuth":false},{"name":"get_milestone_details","alias":"karma_milestone_get_details","description":"Single-call lookup for a milestone given its UID. Returns the milestone metadata (title, description, status, due date) AND the per-milestone allocation amount declared in the grant payout configuration. Use this whenever the user asks \"what is the value of milestone X?\", \"how much is milestone X worth?\", or \"show me milestone X\". Different from list_milestone_completions / get_milestone_completion — those return only completion text. Returns 404-style envelope (reason=not_found) when no grant contains the milestone UID.","category":"milestone","requiresAuth":false},{"name":"search_organizations","alias":"karma_philanthropy_search_funders_and_nonprofits","description":"Find foundations or nonprofits. Combine arguments freely:\n  • `query` (natural language, e.g. 'climate justice in California'): semantic search over name + description (uses pgvector embeddings).\n  • `name`: hybrid name lookup — substring ILIKE first ('Dobson Foundation' matches 'THE DOBSON FOUNDATION INC'), with semantic embedding fallback when the substring underfills the limit. This catches both spelling variants and reworded names ('Bill Gates Charity' → 'Bill and Melinda Gates Foundation'). May overmatch — agent should disambiguate by inspecting candidates.\n  • `ids`: batch fetch by funding_organization.id.\n  • `kinds`: e.g. ['private_foundation'] for grantmaking foundations, ['nonprofit'] for recipients.\n  • `location`: substring or 'City, ST'.\n  • `minAssets` / `maxAssets`: dollar range against funding_organization.total_assets.\n  • `sortBy`: 'total_assets' (default) or 'name'.\n  • `onlyGrantmakers`: set true for funder/prospect searches; this uses recent outbound grants rather than nonprofit kind alone.\n  • DAF sponsors, major intermediaries, and unresolved recipient sentinels are excluded by default; set includeIntermediaries/includeUnresolvedRecipients true only when explicitly needed.\nUse this for any organization lookup, ranking, or matching question. The result includes id, name, kind, ein, location, totalAssets, and (when query is set) similarity.","category":"philanthropy","requiresAuth":false},{"name":"search_grants","alias":"karma_philanthropy_search_grant_transactions","description":"Search grant transactions. Combine arguments freely:\n  • `query`: natural language topic (semantic search over grant description embeddings).\n  • `foundationName` / `recipientName`: case-insensitive substring match (ILIKE %name%). 'Dobson Foundation' matches 'The Dobson Foundation, Inc.'. Pass the most distinctive part of the name; resolve to an ID via search_organizations first if you need a specific entity.\n  • `foundationId` / `foundationIds`, `recipientId` / `recipientIds`: filter by IDs.\n  • `year` + `dateBasis`: e.g. year=2023, dateBasis='tax_period_end_year' (default).\n  • `minAmount` / `maxAmount`: dollar bounds.\n  • `sortBy`: 'amount' | 'actionDate' | 'taxPeriodEndYear' | 'filingYear'. `sortOrder`: 'asc' | 'desc' (default desc).\n  • Grantor intermediaries and unresolved recipient sentinels are excluded by default.\nReturns up to `limit` matching grants (default 50, max 500). Use aggregate_grants when you need totals across the FULL match set.","category":"philanthropy","requiresAuth":false},{"name":"aggregate_grants","alias":"karma_philanthropy_summarize_grant_totals","description":"Compute exact COUNT and SUM(amount) over ALL grants matching the supplied filters — not just a paginated slice.\n\nUse this when the user asks for totals, top-N, or anything that requires summing across the full match set:\n  • 'How much did MacArthur give in 2023?' → foundationName='MacArthur Foundation', year=2023\n  • 'Top 10 foundations by grants paid' → groupBy='grantor', limit=10\n  • 'Top funders of climate causes' → query='climate change biodiversity', groupBy='grantor'\n\nTopical aggregation: pass `query` (natural-language phrase) to restrict the aggregation to grants whose description embeddings are semantically similar (default cosine threshold 0.4). This catches synonyms — \"climate\" matches \"carbon offset\", \"biodiversity\", \"decarbonization\". Compose freely with structured filters (year, foundationName, recipientLocation, etc.).\n\nWhen `groupBy` is omitted, returns one overall row { grantCount, totalAmount }. When set to \"grantor\" or \"recipient\", returns one row per organization (with org metadata) ordered by totalAmount desc.\n\nNote: rows whose `description_embedding` has not yet been generated are excluded from `query`-filtered aggregations. Drop `query` if you need the full population.","category":"philanthropy","requiresAuth":false},{"name":"get_irs_990","alias":"karma_philanthropy_get_foundation_filing_details","description":"Fetch IRS 990 / 990-EZ / 990-PF detail for a foundation or nonprofit (financials, officers, filings).\nRouting: organizations with kind=private_foundation are read from the 990-PF tables; all others (community foundations, public charities, universities) are read from the 990 / 990-EZ tables.\n  • `section: 'financials'` → revenue, expenses, total assets, net assets. For private foundations also includes qualifying distributions; for public charities also includes Schedule I grant totals.\n  • `section: 'officers'` → name, title, compensation, benefits (shared table across all 990 form types).\n  • `section: 'filings'` → filing list (form_type, tax_period, return_timestamp).\nPass `filingYear` to scope to one tax period; otherwise returns all years.\nPre-requisite: resolve foundationId via search_organizations first.","category":"philanthropy","requiresAuth":false},{"name":"run_sql","alias":"karma_philanthropy_query_grants_database","description":"Read-only SQL escape hatch. Use ONLY when the structured tools cannot express the question (e.g. multi-year trends, complex co-funder analysis, custom group-bys, cross-table joins).\n\nConstraints:\n  • Single SELECT or WITH statement. No semicolons. No DML/DDL.\n  • Allowed tables only: funding_organization, funding_transaction, funding_relationship, funding_irs_filings, funding_irs_financials, funding_irs_officers, funding_irs_990_filings, funding_irs_990_financials, funding_org_grantmaker_stats.\n  • LIMIT auto-clamped to 200. statement_timeout = 5s.\n\nSchema (column lists auto-introspected from the database; notes hand-written):\n\nfunding_organization (id, source_id, external_id, name, kind, description, country, city, state, location, website_url, agency_code, uei, ror_id, ein, total_assets, metadata, created_at, updated_at)\n  ↳ kind ∈ {private_foundation, community_foundation, corporate_foundation, operating_foundation, nonprofit, university, research_institute, federal_agency, state_agency, local_agency, company, dao, individual, other}. ein is the IRS EIN for foundations / nonprofits. total_assets is decimal(18,2).\n\nfunding_transaction (id, source_id, external_id, grantor_id, recipient_id, opportunity_id, kind, program_identifier, amount, currency, start_date, end_date, action_date, description, filing_year, tax_period_end_year, source_row_hash, is_active, metadata, created_at, updated_at)\n  ↳ kind ∈ {grant, contract, cooperative_agreement, fellowship, prize, loan, contribution, disbursement, bounty, scholarship, program_related_investment, other}. grantor_id and recipient_id reference funding_organization.id. IRS 990 / 990-PF rows have filing_year and tax_period_end_year populated; government grants do not.\n\nfunding_relationship (id, parent_id, child_id, kind, source_id, metadata, created_at, updated_at)\n  ↳ kind ∈ {parent_agency, subsidiary, fiscal_sponsor, affiliated, dba, predecessor, same_as}\n\nfunding_irs_filings (id, foundation_id, filing_year, ein, form_type, tax_period, return_timestamp, object_id, raw_filing, created_at, updated_at)\n  ↳ 990-PF filings only (private foundations).\n\nfunding_irs_financials (id, foundation_id, filing_year, total_revenue, total_expenses, total_assets, net_assets, minimum_investment_return, distributable_amount, qualifying_distributions, undistributed_income, excess_distributions, created_at, updated_at)\n  ↳ 990-PF per-year financial snapshot (private foundations only).\n\nfunding_irs_officers (id, foundation_id, filing_year, name, title, compensation, benefits, expense_account, created_at, updated_at)\n  ↳ Shared officer table for ALL 990 form types (990, 990-EZ, 990-PF). foundation_id references funding_organization.id regardless of form type.\n\nfunding_irs_990_filings (id, organization_id, filing_year, ein, form_type, tax_period, return_timestamp, object_id, raw_filing, metadata, created_at, updated_at)\n  ↳ 990 / 990-EZ filings (public charities, community foundations, universities — anything that is NOT a private foundation). form_type ∈ {'990', '990EZ'}. organization_id references funding_organization.id.\n\nfunding_irs_990_financials (id, organization_id, filing_year, total_revenue, total_expenses, total_assets_eoy, total_liabilities_eoy, net_assets_eoy, contributions_and_grants, program_service_revenue, government_grants, investment_income, other_revenue, program_service_expenses, management_general_expenses, fundraising_expenses, schedule_i_total_grants, schedule_i_grant_count, created_at, updated_at)\n  ↳ 990 / 990-EZ per-year financial snapshot. schedule_i_* columns hold the total grants this nonprofit received via 990 Schedule I.\n\nfunding_org_grantmaker_stats (organization_id, outflow_grant_count_5y, outflow_grant_amount_5y, last_grant_at)\n  ↳ Materialized rollup used internally to detect \"is this org actively giving grants\". Joins to funding_organization.id.\n\nRouting rule: a private_foundation org has rows in funding_irs_filings / funding_irs_financials. Every other kind has rows in funding_irs_990_filings / funding_irs_990_financials. Both share funding_irs_officers.\n\nExamples:\n  -- Trend: MacArthur giving by year\n  SELECT tax_period_end_year AS year, SUM(amount) AS total\n  FROM funding_transaction t JOIN funding_organization o ON o.id = t.grantor_id\n  WHERE o.name ILIKE '%MacArthur%' AND tax_period_end_year IS NOT NULL\n  GROUP BY tax_period_end_year ORDER BY tax_period_end_year\n\n  -- Co-funders: top 5 foundations that also fund Hewlett's recipients\n  WITH hewlett_recipients AS (\n    SELECT DISTINCT recipient_id FROM funding_transaction t\n    JOIN funding_organization o ON o.id = t.grantor_id WHERE o.name ILIKE '%Hewlett%'\n  )\n  SELECT g.name, COUNT(*) AS shared_grants FROM funding_transaction t\n  JOIN hewlett_recipients h ON h.recipient_id = t.recipient_id\n  JOIN funding_organization g ON g.id = t.grantor_id\n  WHERE g.name NOT ILIKE '%Hewlett%' GROUP BY g.name ORDER BY shared_grants DESC LIMIT 5","category":"philanthropy","requiresAuth":false},{"name":"web_search","alias":"karma_web_search","description":"Search the public web for foundation contact pages, grant guidelines, application portals, RFPs, or any URL we do not already have on file. Use specific queries:  • \"<foundation name> contact email\"  • \"<foundation name> grant application 2026\"  • \"<foundation name> request for proposals\"Returns the top results with title, url, snippet, and domain. When you know the foundation's domain, pass `site` to restrict the search to that domain — much higher signal than an open-web query.","category":"web_research","requiresAuth":false},{"name":"fetch_page","alias":"karma_web_fetch_page","description":"Fetch a URL and return clean markdown plus outbound links. Use after web_search to read a contact page, grants page, or application form. Set `renderJs: true` for JS-heavy pages (Submittable, SmartSimple, most application portals); leave it false for static foundation sites — JS rendering costs more and is slower. The markdown is truncated to ~12000 characters; if you need a different page, follow a link from the response.","category":"web_research","requiresAuth":false},{"name":"extract_from_page","alias":"karma_web_extract_from_page","description":"Fetch a URL and extract structured data matching the requested schema. Prefer this over fetch_page when you already know what fields you need:  • foundation_contact — emails, phones, address, contact persons  • application_details — applicationUrl, deadlines, eligibility, fields, attachments  • grant_program_summary — list of programs run by a foundationResult includes a confidence indicator (low/medium/high). Low confidence usually means the page does not actually contain that information — try a different URL via web_search rather than retrying with the same input.","category":"web_research","requiresAuth":false}]}