Skip to main content
Glama
chaunceyplum

workfront-fusion-mcp

by chaunceyplum
# 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`).

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    A 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
  • F
    license
    Not graded
    quality
    D
    maintenance
    This 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
    -