DocumentationGetting Started & SetupPart 9 of 14

    Connect Your Own App to Cogny Automations

    Expose your app's data and actions as an MCP endpoint, register it with Cogny, and run a scheduled agent against it. The full loop a coding agent can do end to end with the Cogny CLI.

    Cogny automations are scheduled agents that act through tools you have greenlit. Most of those tools come from Cogny's own integrations: Google Ads, Meta, GA4, Discord, and so on. When the data or the action lives in your own app (a booking system, a member database, an internal admin), you expose it as an MCP endpoint, register it with Cogny, and the automation calls it like any other integration.

    This guide is written for a coding agent or developer working in the user's codebase. Everything below can be done from the terminal with the Cogny CLI. The dashboard covers the simpler cases (one tool per job); see the end of this page.

    When to use this

    • Your app holds data Cogny can't reach through a built-in integration, and a weekly or daily agent should act on it.
    • The action needs rules only your app can enforce: consent, opening hours, per-customer limits, an approval queue.
    • You want every run recorded as a ticket, with a transcript of what the agent read and did.

    If you only need a nightly data sync with no judgement involved, use Scripts instead (Automations and content loops).

    The example: a retention agent for a membership business

    A martial-arts school, gym or dance studio has the same pattern: members who miss two weeks tend to quit. The agent runs once a week. It finds members who have not been seen in 14 days, books each a make-up class, and texts the family in the instructor's voice.

    The app exposes six tools:

    ToolKindWhat it does
    get_retention_reportreadAt-risk members with last visit, recent attendance, contact, text consent and make-up options
    get_studentreadOne member's profile, notes, history and messages already sent
    list_class_schedulereadUpcoming classes with ids and dates
    book_makeup_classwriteBooks a member into a class on a date
    send_parent_textwriteTexts the family, or queues the text for staff approval
    log_parent_messagewriteRecords a call, email or note

    1. Log in to the user's workspace

    Ask the user for an API key: Settings → Data & Integrations → Connect AI Clients, cogny cli tab. The key is shown once. The user already has a workspace, so don't run cogny init; that creates a new one.

    alias cogny="npx @cogny/cli"
    cogny login --api-key <key>
    cogny status          # subscription, credits, connected integrations
    cogny tools list      # automation tools appear only if automations are on
    

    Automations are included with Cloud. If create_automation is missing from cogny tools list, automations aren't switched on for this workspace; tell the user to contact Cogny support.

    2. Build the MCP endpoint

    Cogny talks to your endpoint over Streamable HTTP (JSON-RPC over POST) and sends Authorization: Bearer <api_key> on every call. A minimal Next.js route with mcp-handler and zod:

    // app/api/agent/mcp/route.ts
    import crypto from 'node:crypto';
    import { createMcpHandler } from 'mcp-handler';
    import { z } from 'zod';
    
    const handler = createMcpHandler((server) => {
      server.registerTool('get_retention_report', {
        description: 'Members not seen for 14+ days, with make-up options for the next 7 days.',
        inputSchema: z.object({ at_risk_only: z.boolean().default(true) }),
        annotations: { readOnlyHint: true },
      }, async ({ at_risk_only }) => json(await retentionReport(at_risk_only)));
    
      server.registerTool('send_parent_text', {
        description: 'Text a family. Refused without consent or outside 8am–9pm local time.',
        inputSchema: z.object({ student_id: z.string().uuid(), message: z.string().max(300) }),
        annotations: { readOnlyHint: false, destructiveHint: false },
      }, async (input) => json(await sendText(input))); // consent, quiet hours, opt-out line enforced here
    });
    
    // Constant-time compare, so the key can't be guessed from response timing.
    function validKey(req: Request) {
      const key = process.env.AGENT_API_KEY;
      const got = (req.headers.get('authorization') || '').replace(/^Bearer\s+/i, '');
      if (!key) return false;
      const a = Buffer.from(got), b = Buffer.from(key);
      return a.length === b.length && crypto.timingSafeEqual(a, b);
    }
    
    async function authed(req: Request) {
      if (!validKey(req)) return new Response('Unauthorized', { status: 401 });
      return handler(req);
    }
    export { authed as GET, authed as POST };
    

    json, retentionReport and sendText stand for your own code. Generate the key with openssl rand -hex 32, set it on the server, and deploy.

    Two rules decide what a run can do:

    • Read tools must be recognisable. Unless you list read tools yourself, a run is offered a tool on a granted server when its name starts with get, list, search, execute, inspect, run, fetch, query, read, describe, find, check, count, lookup, view or show (a leading tool_ is ignored). A tool annotated readOnlyHint: true also counts, unless it is also destructiveHint: true. A tool called retention_report with no annotation is left out, and the agent can't see it. Annotate it, rename it, or list it in read_tools (step 4).
    • Safety rules go in the write tools, not the prompt. Check consent, quiet hours, rate limits and opt-out inside send_parent_text, and return a clear error when a call is refused. The agent reads the error and moves on. A prompt can be misread; your endpoint can't be talked out of a rule. If staff should see messages before they go out, make the write tool queue a draft for approval in your admin rather than send.

    3. Register the endpoint

    cogny tools call add_custom_mcp_server --input '{
      "name": "Dojo",
      "server_url": "https://example-dojo.com/api/agent/mcp",
      "api_key": "<AGENT_API_KEY>",
      "description": "Members, attendance, make-up classes and family texts"
    }'
    

    The result has a server_id and every discovered tool with read_only: true|false. false means the tool wasn't recognised as read-only, not that it must be a write. A tool that really only reads but shows false can go in read_tools; a write tool goes in action_grants. Only owners and admins can register servers, and the URL must be https. Call it again with the same name to change the URL or rotate the key.

    After you deploy changes to the endpoint, run cogny tools call refresh_mcp_discovery --input '{"server_name":"Dojo"}' so Cogny sees the new tool list.

    In the dashboard, the same step is Settings → MCPs For Cogny → MCP Servers → Add Server, with auth type API key.

    4. Create the automation, disabled

    cogny tools call create_automation --input '{
      "name": "Weekly retention",
      "crontab": "0 10 * * 1",
      "timezone": "America/Indiana/Indianapolis",
      "enabled": false,
      "instructions": "Call get_retention_report. For each at-risk member: read get_student, skip anyone whose notes say not to contact or who was contacted this week, book one make-up class with book_makeup_class, then send_parent_text if they have text consent (warm, under 300 characters, first name, mention the class day and time). Without consent, log_parent_message a note that a call is needed. End with a summary: who was contacted, what was booked, who needs a call.",
      "action_grants": [
        { "server_name": "Dojo", "tool_name": "book_makeup_class" },
        { "server_name": "Dojo", "tool_name": "send_parent_text" },
        { "server_name": "Dojo", "tool_name": "log_parent_message" }
      ]
    }'
    
    • action_grants are the write tools the run may call, one entry each. mcp_server_id is optional and is looked up from server_name. Add constraints to pin an input field to a fixed value. For example, {"channel_id": "123"} locks a Discord post to one channel. A call with a different value is refused at call time.
    • read_tools (optional) is an explicit list of read tools, [{ "server_name": "Dojo", "tool_name": "retention_report" }]. Once set, it replaces the automatic read-tool selection. Some tools are refused here and have to be granted instead:
      • tools annotated as writes (readOnlyHint: false or destructiveHint: true)
      • tools whose name starts with a write verb (create, update, delete, send, post, …), unless annotated readOnlyHint: true
    • timezone is an IANA name. Without it, the crontab runs on Europe/Stockholm time.

    The result includes pre_approved_tools: the exact tool list every run gets. Nothing else is offered to the agent. list_automations shows the same list later.

    5. Dry-run and inspect

    cogny tools call run_automation --input '{"automation_id":"<id>","dry_run":true}'
    cogny tools call get_automation_run --input '{"ticket_id":"<ticket_id>"}'
    

    A dry run has no write authority. The agent reads, then reports what it would have booked and sent. get_automation_run returns the run status, any error, and a condensed transcript of each tool call with its input and a preview of the result. Fix the endpoint or the instructions and dry-run again until the report reads right. Dry runs use credits like any run.

    6. Run once for real, then enable

    Show the user the dry-run summary and get their OK. Then:

    cogny tools call run_automation --input '{"automation_id":"<id>","dry_run":false}'
    cogny tools call update_automation --input '{"automation_id":"<id>","enabled":true}'
    

    update_automation only changes the fields you pass. action_grants and read_tools replace the whole list, and read_tools: null goes back to automatic read-tool selection. Enabling needs a schedule: enabled: true fails with "Set a crontab before enabling" until the automation has a crontab. run_automation works without one.

    What a run looks like

    Every run, scheduled or run now, becomes a ticket on the Tickets board with its full transcript, so the user can see what the agent read, booked and sent. Runs use the workspace's credits like any agent run. When the workspace is out of credits, the run is skipped instead of starting. A schedule fires at most once an hour.

    Common mistakes

    • Wrong timezone. 0 10 * * 1 without a timezone runs at 10:00 Stockholm time, which is 04:00 in Indiana. A quiet-hours rule then refuses every text. Always pass the business's timezone.
    • Invisible read tools. A read tool named outside the prefix list and not annotated readOnlyHint: true is not offered. Check read_only in the add_custom_mcp_server result and pre_approved_tools after creating.
    • Consent only in the prompt. If the prompt is the only thing stopping a text to a family without consent, a misread prompt sends it. Enforce it in the write tool.
    • Unpinned grants. A grant on a tool that takes a target (a channel, an account, a campaign) without constraints lets the agent choose any target. Pin it.
    • Stale tool list. After deploying a new or renamed tool, run refresh_mcp_discovery. Otherwise Cogny still has the old list and the new tool is missing from the run.
    • Automations off. If the automation tools don't appear, automations aren't switched on for the workspace. They're included with Cloud; contact Cogny support.

    In the dashboard

    Reports → Create new → New Automation creates a job with one allowed tool, plus one optional pinned field. It is created disabled, on a Monday-morning schedule in your browser's timezone. After that, the automation's Settings dialog has the schedule picker with a Timezone selector. It also lets you edit each grant's label and pinned fields, or remove extra grants. Run now on the automation page is a real run, the same as run_automation with dry_run: false. Use the tool for dry runs.

    Adding more write tools, or setting read_tools, isn't in the dashboard. Do it through the in-app chat or with create_automation / update_automation over MCP or the CLI.

    Related: Automations and content loops · Use Cogny from your own agent · Cogny MCP server

    Reading this with an AI agent? Fetch the raw markdown at /docs/connect-your-own-app-to-automations/index.md or see llms.txt.

    Cogny Cloud
    Ready to set up Cogny Cloud?
    $499/mo with 5,000 credits included, month to month. Setup takes about an hour with us on the call.