Unfold It MCP Server
OfficialClick on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Unfold It MCP ServerCreate a goal to learn Python in 3 months"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Unfold It MCP Server
Connect AI assistants to Unfold It -- create goals with AI-generated plans, agent-assisted clarification, plan import with enrichment, individual progress tracking, cohort analytics, and skill assessments.
Built for platforms (academies, LMS tools, coaching apps) that want to use Unfold It as their execution layer. Three autonomy tiers: fully autonomous, semi-auto with review, or import your own steps with AI enrichment. Generate skill assessments with AI-validated MCQs, score them, and automatically create targeted learning paths from the results. Tag goals with custom metadata to track and analyze entire cohorts.
Quick Start
npx @unfoldit/mcp-serverOr install globally:
npm install -g @unfoldit/mcp-serverConfiguration
Set the following environment variables:
Variable | Required | Description |
| Yes | Org-scoped API key. Generate at app.unfoldit.com -> Organization -> API Keys |
| No | API base URL. Defaults to |
Claude Desktop / Claude Code
Add to your MCP config (claude_desktop_config.json or .mcp.json):
{
"mcpServers": {
"unfoldit": {
"command": "npx",
"args": ["@unfoldit/mcp-server"],
"env": {
"UNFOLD_API_KEY": "unfold_sk_..."
}
}
}
}Cursor
Add to .cursor/mcp.json in your project:
{
"mcpServers": {
"unfoldit": {
"command": "npx",
"args": ["@unfoldit/mcp-server"],
"env": {
"UNFOLD_API_KEY": "unfold_sk_..."
}
}
}
}API Key Scopes
Your API key needs specific scopes depending on which tools you use:
Scope | Tools | Included by default? |
| create_goal, unfold_goal, submit_clarification, import_plan | Yes |
| get_goal_status, list_goals, get_analytics, get_clarification | Yes |
| revoke_claim | Yes |
| generate_skill_assessment | No -- must be granted explicitly |
| score_skill_assessment | No -- must be granted explicitly |
| get_assessment_capabilities | No -- must be granted explicitly |
Assessment scopes are opt-in. Ask your org owner to enable them in the API Key settings.
Available Tools (12)
create_goal
Create a goal with an AI-generated plan. The agent auto-answers clarification questions using the context you provide. Set auto_respond=false to review agent suggestions before the plan generates. Tag goals with metadata to group and analyse entire cohorts.
Input:
title(required) -- Goal titledescription-- Goal description. More detail produces a better AI plancontext-- Rich context for the agent:tech_stack-- e.g. ["Python", "React"]team_size-- e.g. 3timeline-- e.g. "3 months", "Q3 2026"constraints-- e.g. "2 hours per week"experience_level-- e.g. "beginner", "advanced"industry-- e.g. "fintech"additional_notes-- Any other context
auto_respond-- true (default): agent answers all questions. false: returns questions with suggestions for reviewclarification_answers-- Pre-set answers by question ID (agent skips these)goal_context-- "personal" or "professional" (default: "professional")priority-- "low", "medium", or "high" (default: "medium")claim_expires_in_days-- Claim link validity (default: 30)progress_share-- Generate embeddable progress link (default: true)metadata-- Custom key-value tags for analytics grouping, e.g.{ cohort: "spring-2026", track: "frontend" }category-- Resource category hint: "learning", "health_adhd", or "general". Auto-detected from goal title and description if not provided. Determines which sources and search strategies are used when attaching resources to substeps.resource_world-- Override resource discovery for this goal:preferred_sources-- Source domains to prioritise, e.g.["coursera.org", "docs.python.org"]excluded_sources-- Source domains to suppressyoutube_playlists-- YouTube playlist IDs to draw resources fromlms_search_endpoint-- Custom LMS search endpoint URLcontent_policies--{ require_verified_sources, show_disclaimer, disclaimer_text }
assessment(since v0.7.0) -- Structured assessment input the planner uses to bias step selection. Discriminated byassessment_type:skill_proficiencyv1 -- Drop thescore_skill_assessmentresponse straight in. The planner prioritises weak facets, compresses strong ones, and anchors steps inwork_item_context.clinical_intakev1 -- ADHD / coaching / clinical context. Wire shape is locked; the prompt builder is currently stubbed and returnsassessment_type_not_supporteduntil a real partner drives it. Sensitive type -- requires superadmin enablement per org.generalv1 -- Catch-all for assessment data that does not fit either typed shape. Treated as soft hints; onlyconstraintshonoured as hard limits.
See GUIDE_ASSESSMENT_TO_PLAN_MCP for the canonical end-to-end walkthrough.
request_id(since v0.8.0, optional, idempotency key) -- Within a 5-minute window, twocreate_goalcalls with the samerequest_idreturn the SAME goal and claim link instead of creating a new one. See Idempotency below for the rules. Omit to get a fresh goal on every call (default).
Returns: goalId, claimLink, claimToken, progressLink, planGenerationStatus, questions (if auto_respond=false), agentAnswersUsed, idempotentReplay (since v0.8.0), claimStatus (since v0.8.0), warnings (always present, empty when none)
get_goal_status
Get the current status and full step-by-step detail of a goal. Returns individual step data (timestamps, time spent, blocker count, substep progress) when the plan is ready.
Input:
goal_id(required) -- The goal ID from create_goal
Returns: Goal status, progress, resourceCategory, steps[] (with per-step detail when plan is ready), metadata, claimCreatedAt, claimedAt, assignedTo, agentAnswersUsed
get_analytics
Aggregated cohort analytics across all API-created goals. Returns KPIs, at-risk learners, a step-level drop-off funnel, and optional breakdowns by metadata dimension or resource type.
Input:
group_by-- Metadata key to break down completion rates by (e.g. "track", "cohort", "department")inactive_days-- Flag goals with no step activity in this many days as at-risk (default: 7)include_funnel-- Include step-by-step completion funnel (default: true)include_resources-- Include resource engagement by type and source (default: false)metadata-- Filter to a specific cohort or segment, e.g.{ cohort: "spring-2026" }date_from-- ISO date (YYYY-MM-DD). Only include goals created on or after this datedate_to-- ISO date (YYYY-MM-DD). Only include goals created on or before this date
Returns:
totalGoals,activeGoals,completedGoals,blockedGoals,completionRate,avgDaysToCompleteclaimsTotal,claimsClaimed,claimsPending,claimsExpired,avgHoursToClaimatRiskCount,atRiskGoals[](goalId, title, metadata, daysInactive, progressPercent)completionByDimension[](when group_by is set)stepFunnel[](stepOrder, stepTitle, completionRate, avgHoursToComplete)resourceEngagement[](when include_resources=true)
get_clarification
Get pending clarification questions with agent-suggested answers and confidence levels. Use after create_goal with auto_respond=false.
Input:
goal_id(required) -- The goal ID from create_goal
Returns: Questions with agentAnswer, agentConfidence (high/medium/low/fallback), agentSource
submit_clarification
Submit answers to clarification questions and trigger plan generation. Provide your own answers for questions you want to override. Agent suggestions are kept for the rest.
Input:
goal_id(required) -- The goal ID from create_goalanswers-- Your answers keyed by question ID (only include overrides)accept_agent_answers-- Accept agent suggestions for unoverridden questions (default: true)
Returns: goalId, status, planGenerationStatus, agentAnswersUsed
import_plan
Import a pre-formulated plan with steps and substeps. Skips clarification entirely. AI enriches steps with dependencies, critical path, duration estimates, severity, complexity, and quick-win flags.
Input:
title(required) -- Goal titledescription-- Goal descriptionsteps(required) -- Array of steps, each with:title(required) -- Step titledescription-- Step descriptionsubsteps-- Optional array of substeps with title, description, type (research/work/decision/verification)
enrich-- Run AI enrichment (default: true). Set false for 0 creditsenrich_options-- Control which enrichment features to run:dependencies,critical_path,duration_estimates,severity,complexity,quick_wins,resources
goal_context-- "personal" or "professional" (default: "professional")priority-- "low", "medium", or "high" (default: "medium")claim_expires_in_days-- Claim link validity (default: 30)progress_share-- Generate embeddable progress link (default: true)metadata-- Custom key-value tags for analytics grouping, e.g.{ cohort: "spring-2026", track: "backend" }
Returns: goalId, planId, enriched steps[] with metadata, claimLink
list_resource_categories
List available resource categories for goal classification. Returns each category's active providers, content safety policies, and disclaimer text. Use this to build adaptive UIs or to discover which categories are available before creating goals.
Input: None
Returns: Array of categories, each with id, name, description, activeProviders, showDisclaimer, disclaimerText
list_goals
List all goals in your org with optional filters. Use metadata to filter to a cohort, category to segment by goal type, assigned_email to look up a specific learner, or inactive_days to find at-risk goals without pulling full analytics.
Input:
status-- Filter by goal status (draft, in_progress, completed, blocked, paused)claim_status-- Filter by claim status (unclaimed, claimed, expired, revoked)category-- Filter by resource category (learning, health_adhd, general). Use this to segment ADHD goals from learning goals in a mixed cohort.metadata-- Filter by metadata tag(s) in "key=value" format, e.g.["track=frontend", "cohort=spring-2026"]assigned_email-- Return only the goal assigned to this learner emailinactive_days-- Return only goals with no step activity in the last N days (1-365)limit-- Max results (default: 50)offset-- Pagination offset
Returns: Array of goal statuses with progress, resourceCategory, metadata, claimCreatedAt, claimedAt
revoke_claim
Invalidate a claim link so it can no longer be used.
Input:
claim_token(required) -- The token from the claim link URL
generate_skill_assessment
Generate a skill-proficiency assessment (MCQs) for a learner. Questions are AI-generated and validated (structural + semantic checks) before being returned. Returns a signed assessment_token that the learner's answers are scored against.
Input:
work_item_context(required) -- The work item the learner is preparing for:title(required) -- Work item titledescription-- Work item description (max 2000 chars)domain_tags-- Tags for question anchoring
skill(required) -- Skill to assess (e.g. "Python", "SQL", "Project Management")target_proficiency(required) -- Band the learner should reach: "beginner", "low", "medium", "high"num_questions(required) -- Number of MCQs to generate (3-20)difficulty_mix-- Distribution as{easy, medium, hard}floats summing to 1.0. Default:{easy: 0.2, medium: 0.5, hard: 0.3}band_thresholds-- Custom proficiency band ranges. Default: beginner [0,10], low [11,50], medium [51,85], high [86,100]language-- ISO language code (default: "en")request_id(required) -- Idempotency key. Same request_id returns the same assessment.
Returns: assessment_token, questions[] (stem, options, difficulty, skill_facet), band_map, max_raw_score, target_band, model_meta
Requires scope: assessment:generate
score_skill_assessment
Score a submitted assessment using the signed assessment_token from generate_skill_assessment. Returns the learner's proficiency band, gap vs target, and per-question results. When the learner falls short, includes a suggested_goal_seed you can pass to create_goal to create a targeted learning path.
Input:
assessment_token(required) -- The signed token from generate_skill_assessmentanswers(required) -- Array of{question_id, selected_option_id}(at least one)band_thresholds-- Optional override of proficiency band ranges (defaults to the thresholds embedded in the token)request_id(required) -- Idempotency key
Returns: raw_score, max_raw_score, raw_pct, band, target_band, gap_bands, per_question[], per_facet[] (server-side aggregation per sub-skill with total, correct, raw_pct, classification: weak | strong | mixed), weak_facets[], strong_facets[], facet_coverage (full | partial | difficulty_fallback), recommended_action (none / create_unfold_goal), suggested_goal_seed
Chaining tip: This response is shape-compatible with
create_goal's newassessmentfield (skill_proficiency v1). Drop it in with three header fields added (assessment_type: "skill_proficiency",schema_version: "v1",assessed_at: <ISO timestamp>) and the planner uses it directly. No client-side join logic, no threshold tuning.
Requires scope: assessment:score
get_assessment_capabilities
Get supported parameters for skill assessments. Use this to introspect before calling generate_skill_assessment. No input parameters required.
Returns: schema_version, supported_languages, min_questions, max_questions, supported_proficiency_bands, default_band_thresholds, default_difficulty_mix, open_domain, token_ttl_seconds
Requires scope: assessment:read_capabilities
Idempotency
Available since v0.8.0.
create_goal accepts an optional request_id so a partner can retry safely without producing duplicate goals.
The rules
Scope the key to one logical operation. A "logical operation" is one learner / one enrollment. Construct the key from your own per-learner identifier, for example:
request_id = "enrollment:42:learner:7" request_id = "course:python-101:user:abc-123"Reuse the key on retries, not on new learners. If a network blip or process restart makes you re-send the same call for the same learner, use the same
request_id. If you are creating a goal for a DIFFERENT learner, generate a NEW key.Do NOT derive the key from the body. Two learners enrolled in the same course will produce identical title / description / assessment payloads. If you reuse a body-derived key, the second learner will receive a claim link the first learner already claimed.
Without a
request_id, every call creates a fresh goal. This is the default and is always safe.
Cache window
Two calls with the same tenant + request_id within 5 minutes return the same response. After 5 minutes the key falls out of cache and a fresh call creates a new goal. Best-effort across pod restarts and horizontal scaling today; treat the window as a retry helper, not a deduplication guarantee.
Detecting a replay
Two new fields on the response tell you what happened:
idempotentReplay: true-- this response was served from cache. A prior call with the samerequest_idproduced this goal.claimStatus: "unclaimed" | "claimed" | "expired" | "revoked"-- current state of the underlying claim token, refreshed from the DB on every replay.nullon a fresh create (implicitly "unclaimed").
Branch on this when handling retries:
const result = await create_goal({ title, request_id: enrollmentKey });
if (result.idempotentReplay && result.claimStatus && result.claimStatus !== "unclaimed") {
// The link was already consumed by the original recipient. Don't
// forward it again -- prompt the human or open a support ticket
// depending on your flow.
} else {
// Safe to forward the claimLink to the learner.
}How It Works
Tier 1 -- Semi-Auto (Review agent suggestions)
Call
create_goalwithauto_respond=falseand your contextGet back questions with agent-suggested answers and confidence levels
Review suggestions, override any you disagree with
Call
submit_clarificationto trigger plan generationPoll
get_goal_statusuntilplanGenerationStatusis "completed"
Tier 2 -- Full-Auto (Agent handles everything)
Call
create_goalwith context (auto_respond defaults to true)Agent answers all clarification questions using your context + user history
Plan generates in the background (15-30s)
Get a claim link immediately -- send it to your user
Poll
get_goal_statusfor completion andagentAnswersUsedtransparency
Tier 3 -- Import (Bring your own steps)
Call
import_planwith your steps and substepsAI enriches with dependencies, durations, severity, critical path
Plan is ready immediately (no clarification needed)
Get a claim link and enriched step metadata
Assess-then-Learn (Assessment to goal) [updated v0.7.0]
The canonical chain that turns a scored assessment into a personalised plan, with no client-side join logic:
Call
generate_skill_assessmentwith the skill, target proficiency, and work item contextPresent questions to the learner in your UI
Call
score_skill_assessmentwith the token and the learner's answers. Response includesper_facet,weak_facets,strong_facets,facet_coverage(server-side aggregation).Call
create_goalwith the score response dropped into the newassessmentfield (skill_proficiency v1). The planner uses weak/strong facets to bias steps and anchors them inwork_item_context.Send the claim link to the learner.
Full walkthrough with payload examples for skill_proficiency, general, and clinical_intake lives at GUIDE_ASSESSMENT_TO_PLAN_MCP.
Legacy path. Pre-v0.7.0 integrations stuffed the score into
additional_context.unfold_assessmentper the payload convention. That still works onPOST /api/v1/ext/goalsfor backwards compat; behind the scenes both paths now route through the same prompt-builder registry. New integrations should use the structuredassessmentfield oncreate_goal.
Example Prompts
"Create a Python certification learning path for a beginner with 2 hours per week for 3 months."
"Import our Jira sprint backlog as a goal with dependencies and time estimates."
"Create a coaching plan for Sarah but let me review the questions before generating the plan."
"Create an ADHD morning routine coaching plan with category health_adhd for a patient who struggles with time blindness."
"List all health_adhd goals in the spring cohort and show me which ones are at risk."
"Show me all goals where the claim link hasn't been used yet."
"What's the progress on goal abc-123? Has the learner started?"
"Generate a Python assessment with 8 questions for someone who needs medium proficiency to work on the ML pipeline."
"Score this assessment and create a goal from the results if the learner didn't reach the target."
Getting an API Key
Go to app.unfoldit.com
Create or switch to your organization
Go to Organization settings
Scroll to API Keys section
Click + Create Key, give it a name, and copy the key
Typed errors and warnings (v0.7.0+)
When a tool fails with a typed error, the response is a structured JSON envelope rather than a stringified message. Branch on error_code:
| When | Notes |
| BYO provider role is not configured | Response includes |
| BYO provider key rejected | Includes |
| BYO provider returned quota/billing error | Includes |
| BYO provider 5xx or circuit breaker open | Transient; retry later |
|
| Response includes |
| Tenant has not opted into this assessment type | Sensitive types (clinical_intake) need superadmin enablement |
| Assessment token tampered or past TTL | Regenerate via generate_skill_assessment |
| Same request_id used with different request body | Pick a new request_id |
| Generation output failed validation after retry budget | Retry with different request_id |
Successful responses on goal creation also carry warnings: ApiWarning[] (always present, empty when none). Known warning codes:
| When |
|
|
| Both structured |
Both branches preserve the structured envelope so AI coding agents can deterministically branch on the error_code or warning code strings. See the versioning policy for stability guarantees on these codes.
Versioning
This package follows semver. Pin a minor version range ("@unfoldit/mcp-server": "^0.8.0") -- you will get fixes and additive features automatically; breaking changes require a major version bump. We support the latest two minor versions; older minors receive security fixes only.
Note: in the pre-1.0 era, each minor bump (e.g. 0.7.x -> 0.8.0) may include additive surface changes such as new optional request fields or new response fields. Existing code keeps working; opt in to new behaviour as you need it.
See GUIDE_MCP_VERSIONING for the full policy. See CHANGELOG.md for what changed in each release.
Learn More
Unfold It -- AI-powered goal planning and execution platform
Developers -- API and MCP documentation
GitHub -- Source code and issues
Assessment-to-Plan guide -- End-to-end walkthrough for the score-to-goal chain
Versioning policy -- Semver discipline, supported-versions window, deprecation policy
License
MIT
This server cannot be installed
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Unfold-it/unfoldit-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server