workfront-fusion-mcp
Click on "Deploy 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., "@workfront-fusion-mcpShow me all active projects in Workfront"
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.
# Workfront & Workfront Fusion MCP
One repository, **14 independently deployable Lambda functions** -- one per
Workfront/Fusion domain -- each exposing only its own scoped set of MCP
tools at its own HTTP route. **282 tools total**, covering every endpoint
listed in `WORKFRONT_MCP_SOLUTIONS.md` (full CRUD per object where the
underlying API supports it, not just the common list/get/create path).
See `WORKFRONT_MCP_SOLUTIONS.md` for the full
architecture writeup (endpoint tables, call-order dependencies per server,
auth details, and the single-repo-vs-separate-repos tradeoff this repo
settled on).
This mirrors the pattern already proven in `chaunceyplum/mcp` (the AEC
Adobe Experience Cloud MCP server): a stateless JSON-RPC 2.0 Lambda
handler per server, a single flat `TOOLS` dict per function, and
credentials resolved from SSM at deploy time via `{{resolve:ssm:...}}`.
The difference here: instead of one Lambda with all tools, **each server
is its own function with its own route**, so an MCP client only ever sees
the tools relevant to whichever endpoint(s) it's wired to.
## Why one repo instead of separate repos per server
We evaluated splitting each server into its own GitHub repo (see the
"one repo per server" alternative in `WORKFRONT_MCP_SOLUTIONS.md`) and
settled on a single repo with N independently deployable functions
instead, because:
- **The actual goal -- "the LLM only sees relevant tools" -- is a runtime
endpoint property, not a source-control property.** A client hitting
`/mcp/workfront/core` never sees another server's
tools regardless of which repo the code lives in.
- **Isolation that matters (auth, blast radius) comes from per-function
config, not per-repo config**, and SAM gives us that directly: every
function below has its **own** `Environment` block resolving its
**own** SSM namespace -- nothing is shared via `Globals`, so a bug in
one server's code can't read another server's credentials.
- **One CI pipeline, one set of shared tooling (`common/`)** is simpler
to maintain solo/small-team than 14 repos + a versioned shared package,
and repos are cheap to split out later if team ownership ever actually
diverges.
## Servers
| Folder | Route | Covers |
|---|---|---|
| Folder | Route | Tools | Covers |
|---|---|---|---|
| `servers/core/` | /mcp/workfront/core | 43 | Core Work Management: portfolios, programs, templates, template tasks, projects, tasks, and issues (incl. issue→task conversion). |
| servers/users/ | /mcp/workfront/users | 36 | User & Resource Management: companies, roles, users, teams, resource pools, and resource allocations. |
| servers/documents/ | /mcp/workfront/documents | 27 | Document Management: folders, documents, versions, approvals, and document webhook subscriptions. |
| servers/time_approval/ | /mcp/workfront/time-approval | 25 | Time & Approval: approval paths, timesheets (incl. submit), hour entries, and approval instances. |
| servers/metadata/ | /mcp/workfront/metadata | 26 | Custom Fields & Metadata: parameters, parameter groups, categories (custom forms, incl. field-attach and category-assign), and category-parameter mappings. |
| servers/search/ | /mcp/workfront/search | 5 | Search & Query: object-scoped search, generic search, named queries, and saved report execution. |
| servers/comments/ | /mcp/workfront/comments | 11 | Commenting & Collaboration (Comment Stream API v1): full CRUD on comments, replies, and reactions. |
| servers/planning/ | /mcp/workfront/planning | 24 | Planning API (v2): full CRUD on workspaces, record types, fields, views, and bulk records. |
| servers/misc/ | /mcp/workfront/misc | 48 | Miscellaneous Objects: notes, messages, reports, calendars, preferences, config, activity updates, and journal entries. |
| servers/fusion_org/ | /mcp/fusion/org | 11 | Fusion Organization & Team: organizations (read), teams (full CRUD), and user-team assignment. |
| servers/fusion_connections/ | /mcp/fusion/connections | 6 | Fusion Connection Management: app connections (full CRUD) and connection-specs. |
| servers/fusion_hooks/ | /mcp/fusion/hooks | 7 | Fusion Webhook & Trigger: webhooks (full CRUD), payload history, trigger definitions. |
| servers/fusion_scenarios/ | /mcp/fusion/scenarios | 9 | Fusion Scenario Management: scenarios, metadata updates, drafts, templates, manual execution. |
| servers/fusion_executions/ | /mcp/fusion/executions | 4 | Fusion Execution & Monitoring: execution history, logs, run history. |
## Shared code (`common/`)
| Module | Purpose |
|---|---|
| `common/auth.py` | Generic Adobe IMS OAuth2 Server-to-Server (`client_credentials`) token fetch, cached per `(client_id, scope)`. |
| `common/workfront_client.py` | Classic Workfront REST API client (`/attask/api/v{version}`) + generic per-objcode CRUD helpers + `wf_set_custom_fields` (the `DE:` custom-form-value mechanism). |
| `common/crud_factory.py` | Builds a standard list/get/create/update/delete/set-custom-fields tool set for a single object code -- most server tool modules are a one-line call into this. |
| `common/comment_stream_client.py` | Comment Stream API v1 client (separate host + IMS scope from classic REST). |
| `common/fusion_client.py` | Workfront Fusion API client (separate host + IMS scope; Fusion is experimental per Adobe's own labeling). |
| `common/planning_client.py` | Planning API v2 client (workspaces / record-types / fields / views / records). |
| `common/dispatcher.py` | MCP JSON-RPC 2.0 Lambda handler factory (`initialize`, `tools/list`, `tools/call`) -- every server's `lambda_handler.py` is a few lines wiring its own `TOOLS` dict into this. |
## Deploy
```bash
sam build
sam deploy --guided # first time -- saves samconfig.toml (gitignored; see samconfig.toml.example)
sam deploy # subsequent deploys -- updates all 14 functions in one stack
```
`sam deploy` updates the whole stack in one pass; you're still deploying
14 independent functions with independent env/config, just via one
command. If you later want to deploy a single server's fix without
touching the others, target it directly:
```bash
sam deploy --resolve-s3 # or use `aws lambda update-function-code` for a hotfix to one function
```
### Populate SSM parameters
Each server reads only its own namespace. Populate the ones for the
servers you're actually standing up first (see the build order in
`WORKFRONT_MCP_SOLUTIONS.md` -- Users, then Core, tend to unblock the rest):
| SSM namespace | Env vars it feeds |
|---|---|
| `wf-mcp/core` | `WF_CLIENT_ID`, `WF_CLIENT_SECRET`, `WF_DOMAIN` |
| wf-mcp/users | WF_CLIENT_ID, WF_CLIENT_SECRET, WF_DOMAIN |
| wf-mcp/documents | WF_CLIENT_ID, WF_CLIENT_SECRET, WF_DOMAIN |
| wf-mcp/time-approval | WF_CLIENT_ID, WF_CLIENT_SECRET, WF_DOMAIN |
| wf-mcp/metadata | WF_CLIENT_ID, WF_CLIENT_SECRET, WF_DOMAIN |
| wf-mcp/search | WF_CLIENT_ID, WF_CLIENT_SECRET, WF_DOMAIN |
| wf-mcp/comments | WF_COMMENTS_CLIENT_ID, WF_COMMENTS_CLIENT_SECRET, WF_COMMENTS_ORG_ID |
| wf-mcp/planning | WF_PLANNING_CLIENT_ID, WF_PLANNING_CLIENT_SECRET, WF_DOMAIN |
| wf-mcp/misc | WF_CLIENT_ID, WF_CLIENT_SECRET, WF_DOMAIN |
| wf-mcp/fusion-org | FUSION_CLIENT_ID, FUSION_CLIENT_SECRET, FUSION_API_BASE |
| wf-mcp/fusion-connections | FUSION_CLIENT_ID, FUSION_CLIENT_SECRET, FUSION_API_BASE |
| wf-mcp/fusion-hooks | FUSION_CLIENT_ID, FUSION_CLIENT_SECRET, FUSION_API_BASE |
| wf-mcp/fusion-scenarios | FUSION_CLIENT_ID, FUSION_CLIENT_SECRET, FUSION_API_BASE |
| wf-mcp/fusion-executions | FUSION_CLIENT_ID, FUSION_CLIENT_SECRET, FUSION_API_BASE |
Example for the core server:
```bash
aws ssm put-parameter --name /wf-mcp/core/client-id --type SecureString --value "..."
aws ssm put-parameter --name /wf-mcp/core/client-secret --type SecureString --value "..."
aws ssm put-parameter --name /wf-mcp/core/domain --type String --value "yourtenant"
```
### Wire up an MCP client
Each server gets its own entry, pointing at its own route from the SAM
outputs:
```json
{
"mcpServers": {
"workfront-core": { "url": "https://<api-id>.execute-api.<region>.amazonaws.com/mcp/workfront/core" },
"workfront-users": { "url": "https://<api-id>.execute-api.<region>.amazonaws.com/mcp/workfront/users" }
}
}
```
Only wire up the servers relevant to a given client/session -- that's
what actually keeps the model's tool list scoped.
## Status
Every endpoint listed in `WORKFRONT_MCP_SOLUTIONS.md` has at least one
corresponding tool (282 total), and every server's `lambda_handler.py`
was re-verified end-to-end (import + a live `tools/list`/`tools/call`
dispatch against mocked HTTP) after each round of additions -- see the
commit history for the specific tool-by-tool audit.
That said, this is still a **scaffold** in one sense: the JSON-RPC
dispatcher, auth clients, and CRUD tool wiring are real and complete, but
several endpoint details are flagged inline (`# NOTE` / docstrings) as
pending verification against a live tenant -- there is no Workfront/Fusion
tenant credentialed against this repo yet. Before relying on any tool in
production, confirm against your own Adobe Developer Console app
registration:
- The exact OAuth scope string(s) for classic Workfront REST, Comment
Stream, Fusion, and Planning (placeholders are marked in `common/*_client.py`).
- The issue→task conversion endpoint/verb (`servers/core/tools/issues.py`).
- The Planning API v2 base path (`common/planning_client.py`).
- The Fusion API base host (`FUSION_API_BASE`).
- The Document Webhooks API registration path/payload shape
(`servers/documents/tools/document_webhooks.py` guesses `/documentwebhook`).
- The named-queries path (`servers/search/tools/named_queries.py` guesses
`/namedqueries` and `/namedqueries/run`).
- Whether Fusion actually exposes `PATCH /scenarios/{id}` for metadata
separately from `/scenarios/{id}/draft` for blueprint edits
(`servers/fusion_scenarios/tools/scenarios.py`).
This server cannot be deployed
Maintenance
Related MCP Connectors
Zero-setup MCP gateway securely connecting AI to your tools with authentication and workflows
Unified MCP Server is a remote MCP connector for AI agents and vertical AI products that provides access to 22,000+ authorized SaaS tools across 400+ integrations and 24 categories directly inside LLMs (Claude, GPT, Gemini, Cohere). Tools operate only on explicitly authorized customer connections, enabling agents to safely read and write against live third-party systems.
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
Marketo MCP server for AI. 130 tools to operate Marketo from Claude, Cursor, or ChatGPT.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceAn MCP server that exposes Adobe Marketo REST API operations as tools for AI assistants and MCP clients. It enables comprehensive management of Marketo assets including leads, activities, emails, smart campaigns, and programs.4-
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to discover and execute tools via a secure MCP server with JWT authentication, RBAC, rate limiting, and audit logging.1MIT
- AlicenseNot gradedqualityCmaintenanceA secure MCP gateway for enterprise AI tool execution, enabling governed invocation of business tools with authentication, RBAC, audit logging, PII redaction, and async processing.Apache 2.0
- FlicenseNot gradedqualityDmaintenanceThis MCP server provides AI coding assistants with curated Adobe developer knowledge on demand, enabling automatic retrieval of guidance and patterns for building App Builder actions and Workfront extensions.1-