---
name: puppetto
description: Use when onboarding users to Puppetto, configuring Puppetto MCP, connecting organization API keys, connecting LinkedIn, or extracting a user's own LinkedIn profile through attended computer-use or a user-provided LinkedIn PDF export.
---

# Puppetto

Use this skill when helping a user operate Puppetto through the web app, the Puppetto MCP server, or a local computer-use session.

User-owned accounts and browser sessions stay user-controlled. Agents use Puppetto MCP only after the user has authorized an organization API key.

## Public Reference Assets

When you need deeper setup instructions, cite or fetch these public files:

- Agent asset index: https://puppetto.com/agents
- Machine-readable manifest: https://puppetto.com/agent-assets/puppetto/manifest.json
- MCP quickstart: https://puppetto.com/agent-assets/puppetto/mcp-quickstart.md
- Setup and auth: https://puppetto.com/agent-assets/puppetto/setup-auth.md
- Campaign onboarding: https://puppetto.com/agent-assets/puppetto/campaign-onboarding.md
- Asset generation: https://puppetto.com/agent-assets/puppetto/asset-generation.md
- Integration bounty admin guide: https://puppetto.com/agent-assets/puppetto/integration-bounty-admin-guide.md

## MCP Onboarding

Goal: move a user from guest usage to authenticated, organization-scoped MCP access.

1. Ask the user to sign in or create an account in Puppetto.
2. If the user does not have an organization, have them create one from `/organizations`.
3. Open the organization developer settings at `/organizations/<orgId>/developer`.
4. Have the user generate or reveal an organization API key. Prefer their MCP client's secret or environment-variable flow instead of pasting the key into chat.
5. Register the MCP server:

```json
{
  "mcpServers": {
    "puppetto": {
      "type": "sse",
      "url": "https://mcp.puppetto.com/mcp/org/<orgId>/sse",
      "headers": {
        "x-puppetto-api-v0-key": "${env:PUPPETTO_MCP_API_KEY}"
      }
    }
  }
}
```

6. Verify access with `puppetto_get_authorized_context`.
7. Inspect existing integrations with `puppetto_list_integrations`.

Guest sessions cannot call Puppetto MCP. If a flow starts as a guest, first help the user authenticate and create or select an organization, then create an organization API key.

## LinkedIn Connection

Goal: connect the user's LinkedIn account to a Puppetto organization.

1. Send the user to `/organizations/<orgId>/integrations` or to the LinkedIn connect URL:

```text
/api/organizations/<orgId>/socials/linkedin/login?returnTo=/organizations/<orgId>/integrations
```

2. The user completes LinkedIn OAuth themselves.
3. After redirect back to Puppetto, verify the stored connection with `puppetto_list_linkedin_profiles`.
4. Treat Puppetto's stored LinkedIn account data as a connection record, not as a full profile scrape. Current OAuth data may include identity fields such as name, picture, locale, and auth state, but may not include headline, experience, education, or skills.

## LinkedIn Profile Extraction

Use progressive enhancement. Pick the best available user-approved extraction path, and normalize every path into the same profile JSON.

Preferred order:

1. Connected LinkedIn OAuth record for identity and authorization context.
2. Attended computer-use extraction when the user and agent both have a browser/computer-control feature available.
3. User-provided LinkedIn profile PDF export when computer-use is not available.

Never block the flow only because computer-use is unavailable. Fall back to the PDF route.

### Computer-Use Path

Goal: extract richer profile information from the user's own LinkedIn profile with the user present and in control.

Use this only after the user explicitly asks for profile extraction and confirms the profile is theirs or they have permission to use the visible information.

1. Ask the user to open LinkedIn on their machine and sign in manually.
2. Ask the user to navigate to their own profile page.
3. Ask the user to enable the computer-use/browser-control mode for the agent.
4. Extract only information visible in the user-controlled browser session. Do not bypass privacy controls, scrape private contacts, export unrelated feeds, or attempt credential handling.
5. Recommended fields:

- profile URL
- name
- headline
- current role and company
- location
- about summary
- featured links or portfolio URLs
- experience entries
- education entries
- visible skills
- certifications, projects, publications, and volunteer items when visible
- recent public post themes, only if the user wants tone analysis

6. Normalize the extracted data into the profile shape below with `source: "linkedin_user_browser"`.

### PDF Export Path

Use this when computer-use/browser-control is not available, unreliable, or declined by the user.

1. Ask the user to export their LinkedIn profile as a PDF from LinkedIn. If LinkedIn's export UI is not visible, ask them to open their profile and use the browser's Print to PDF flow.
2. Ask the user to drop the PDF into the chat or upload it through the current agent UI.
3. Extract only the profile information present in the uploaded PDF. Do not infer private data or scrape LinkedIn separately.
4. Normalize the extracted data into the profile shape below with `source: "linkedin_profile_pdf"`.
5. Show the user a short summary of the extracted profile and ask them to confirm or correct it before creating a character.

### Normalized Profile Shape

```json
{
  "source": "linkedin_user_browser | linkedin_profile_pdf",
  "profileUrl": "",
  "name": "",
  "headline": "",
  "location": "",
  "about": "",
  "experience": [],
  "education": [],
  "skills": [],
  "certifications": [],
  "projects": [],
  "links": [],
  "recentPostThemes": [],
  "extractedAt": ""
}
```

Before saving or using the extracted profile, show the user a short summary and ask them to confirm it is accurate enough.

After confirmation, create the Puppetto character through the best available surface:

- If an app/browser UI is available, open `/organizations/<orgId>/characters/new` and use the confirmed profile as the character seed.
- If a Puppetto MCP character-creation tool is available, submit the normalized profile through that tool.
- If only the current MCP read/write tools are available, store the confirmed profile with `puppetto_resolve_prompt_action` using `store: true` and metadata that includes the source and `purpose: "linkedin_character_seed"`.

When submitting to Puppetto's generated-profile character flow, map the normalized profile into this smaller seed shape:

```json
{
  "name": "",
  "description": "Headline plus concise About summary.",
  "personality": "Professional style inferred only from confirmed profile content.",
  "profession": "Current role and company.",
  "background": "Relevant experience, education, projects, and certifications.",
  "interests": ["skills", "industry topics", "recent public post themes"],
  "tone": "professional"
}
```

## Common MCP Flows

Use `puppetto_get_authorized_context` at the start of a session to confirm the org and key owner role.

Use read tools before write tools. For posts, inspect with `puppetto_list_posts` or `puppetto_get_post`, then use `puppetto_create_draft_post`, `puppetto_update_draft_post`, or `puppetto_update_post_schedule`.

For campaigns, inspect templates and campaigns first, then create/update campaigns and goals. Link posts to campaigns only after confirming the target post and campaign IDs.

For fastest guest-to-publish onboarding after MCP access is connected, inspect `puppetto_list_onboarding_templates` and prefer `puppetto_create_campaign_from_onboarding_template` when the user has a brief but not yet a campaign structure. This creates a campaign, optional storyline, starter character/cast, and draft or scheduled posts from safe defaults. After creation, review the drafts with the user, attach target integrations with `puppetto_set_post_targets`, attach assets with `puppetto_add_post_assets`, and schedule with `puppetto_update_post_schedule` when needed. See https://puppetto.com/agent-assets/puppetto/campaign-onboarding.md for the deeper flow.

If the user has no connected social targets, call `puppetto_list_social_posting_providers` and `puppetto_get_social_connection_links`, then ask the user to open the relevant connect URL and complete OAuth themselves. Verify the result with `puppetto_list_integrations` before attaching targets to posts.

For an X integration bounty, use the same social connection flow, ensure the connected provider is `x-api`, create or target a Puppetto post with `puppetto_create_social_post` and `puppetto_set_post_targets`, and have the user approve the final post before publishing or scheduling. Collect the Puppetto post ID and public X post URL for admin verification. Admins can grant credits from `/admin/organizations` using the `Bounty` quick grant and should record the post URL in the reason. See https://puppetto.com/agent-assets/puppetto/integration-bounty-admin-guide.md.

For storylines, use `puppetto_create_story_with_initial_cast` when the user has roles or character ideas but has not yet created full Puppetto characters. Use `puppetto_create_starter_character` for standalone character setup, then reuse the returned character IDs in story cast or post creation.

For asset generation, inspect available providers with `puppetto_list_asset_generation_integrations` before choosing a model. Filter by `assetType` when possible, for example `image`, `speech`, `music`, `sound_effect`, `video`, `lipsync`, or `3d`. Estimate cost with `puppetto_estimate_asset_generation`, then queue work with `puppetto_generate_asset`. Include `characterId` to attach a character asset, `postId` to attach campaign/post media, and `sourceAssetIds` for edits or derivative generation. Poll `puppetto_list_in_progress_assets`, then inspect completed output with `puppetto_get_asset`. See https://puppetto.com/agent-assets/puppetto/asset-generation.md for narration and provider details.

For shop work, inspect shops, product templates, collections, and import jobs before creating or updating shop entities.

For LinkedIn-assisted character or profile work, combine the stored LinkedIn connection from `puppetto_list_linkedin_profiles` with the user-approved browser extraction payload. Never treat the browser extraction as background scraping; it is an attended, user-controlled data-entry workflow.
