solman-fb-mcp
Manages SAP Solution Manager Focused Build requirements, work packages, and solution documentation hierarchy through the OData API, supporting lifecycle actions and element attachment.
Click 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., "@solman-fb-mcpcreate a requirement 'Fix login bug' with priority 'High'"
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.
solman-fb-mcp — SAP SolMan Focused Build Requirements MCP server
An MCP server that lets an AI assistant (Claude, etc.) operate SAP Solution Manager Focused Build directly over the OData API — no browser automation. It covers the full Requirement → Work Package → Work Item chain (create, link, lifecycle, all persisting), attachments (files + URL links on any object), multi-solution SolDoc navigation with name-based solution/branch/ scope resolution, trustworthy search on a gateway that silently ignores most filters, and generic read+lifecycle for every Focused Build object type.
Point it at your own SolMan Focused Build system via .env. It is cookie-only at
runtime (never opens a browser); an out-of-band refresh script mints the session
cookie via browser SSO.
Quickstart — install with one prompt in Claude Code
New to it? Open Claude Code (desktop or CLI) in any folder and paste the prompt below. Claude does the whole install: clones the repo, sets up Python, helps you sign in once, registers the server, and verifies the connection. The only thing you need to supply is your SolMan host (you'll be asked for it).
Set up the solman-fb-mcp server for me. Work through these steps and stop to ask me only where noted:
1. Clone https://github.com/odaiadnan23-design/solman-fb-mcp.git into my home directory (skip the clone if it's already there) and cd into it.
2. Make sure Python 3.11+ is available. Create a virtual environment (.venv) in the repo and install requirements.txt into it. Then run `python -m playwright install msedge` (skip if Microsoft Edge is already installed and usable).
3. Copy .env.example to .env. Ask me for my SolMan Focused Build host (for example solman.mycompany.com) and SAP client (default 100), and write them into .env. Leave the other create-defaults blank for now — they're only needed later for creating requirements/work packages and can be discovered with the tools.
4. Mint my login session: run `python refresh_session.py --timeout 300` (on Windows you can use `./refresh-session.ps1`). This opens a browser for single sign-on — I will complete the login. Wait until it writes the cookie file, then continue.
5. Register the server with Claude Code at user scope:
`claude mcp add solman-fb -s user -e SAP_CLIENT=100 -- <the .venv python path> <the repo>/server.py`
Use the venv's python and the absolute path to server.py. If the `claude` CLI isn't available, add an equivalent stdio entry named "solman-fb" to my MCP config instead.
6. Tell me to restart Claude Code (or reconnect MCP) so the new tools load.
7. Once the tools are available, verify the connection by calling, in order: session_status, then list_process_types, then list_lookup with kind "solutions". Show me the results. If session_status reports the session expired, tell me to re-run step 4.
Finish with a short summary of what worked and anything that still needs my input.Only
SOLMAN_HOSTis required to connect and read. The create-defaults in.env(solution/owner/category, WP release targeting) are optional and only used when you create requirements or work packages — discover them later withlist_lookup,solution_overview, and thesoldoc_*tools.
Related MCP server: @cap-js/mcp-server
Verify the connection
In Claude Code, after the server is registered and you've refreshed the session:
session_status()→ confirms the cookie is live (otherwise run the refresh).list_process_types()→ the Focused Build object types on your system.list_lookup('solutions')→ your solutions; thensolution_overview('<name>')for its branches + scopes.
If any tool returns SESSION EXPIRED: … run refresh_session.py, re-run the refresh and retry — that's the one manual step, and it's usually silent after the first sign-in.
Tips & use cases
Talk to it in plain language — Claude picks the right tools. Examples:
Explore
"What solutions, branches and scopes exist? Give me an overview of
<solution>.""List the last 20 requirements in
<solution>with their status and owner.""Find requirements about 'credit control' and show their FLP links."
Author the full Requirement → Work Package → Work Item chain
"Create a requirement titled '
<title>' in<solution>, classification WRICEF, and attach it to process step<S…>.""Approve requirement
<id>, create a Work Package under<project>, and add a Work Item to it.""Attach this file / this Jira URL to requirement
<id>."
Test Suite
"Search test cases for 'invoice' and show which test plans use them."
"Download the test-case template, then upload this filled xlsx into
<solution>(validate first).""Show the test execution status for
<solution>."
Good habits
Use names, not GUIDs — say "Release 5" or "
<solution>"; the server resolves them (resolve_context).A requirement must be Approved before a Work Package can link to it.
Attach requirements to the Business-Process reference step (under Business Processes → …), not the library original (under Libraries → Process Step Library) — the reference node is where traceability rolls up.
xlsx uploads validate by default. Review the validation result, then re-run with
validate_only=falseto commit.Seeing
SESSION EXPIRED? Run the refresh script — cookie refresh is the only out-of-band step.
Requirements & SAP's External Requirement API
This server manages requirements through the Requirements Fiori app's own OData service
(BUSINESS_REQUIREMENTS_SRV) — it works over your interactive SSO with no backend setup.
SAP also ships a separate, documented External Requirement API
(/SALM/EXT_R2D_INTEG_SRV) built for wiring an external backlog (Jira, etc.) into Focused
Build with external-ID mapping and two-way status sync — but it needs Basis to activate it
and a service user.
REQUIREMENTS.md covers both: the official field catalog (WRICEF / text / partner / status codes), how each MCP tool maps to the official operations, the shared rule that a requirement's branch comes from its Solution-Documentation element (not a create field), and when to use which path.
Manual setup
Prefer to do it by hand (or not using Claude Code to install)?
git clone https://github.com/odaiadnan23-design/solman-fb-mcp.git
cd solman-fb-mcp
pip install -r requirements.txt # mcp + httpx (+ playwright for refresh)
python -m playwright install msedge # or use an installed Edge/Chromium
cp .env.example .env # then fill in your host (see below)
python refresh_session.py --timeout 300 # sign in once; mints the session cookieFill .env with your host (and, when you're ready to create objects, the site-specific
ids). Discover the ids with the tools once connected: list_lookup('solutions'),
list_branches(<solutionId>), list_lookup('projects'|'categories'|'priorities'), and
the soldoc_* tools.
Register the server with your MCP client (stdio), e.g.:
{ "mcpServers": { "solman-fb": {
"type": "stdio",
"command": "python",
"args": ["/path/to/solman-fb-mcp/server.py"],
"env": { "SAP_CLIENT": "100", "SAP_LANGUAGE": "EN" }
} } }Auth model (browser SSO → cookie file → cookie-only server)
Many SolMan systems front HTTPS logon with SAML 2.0 → SAP Cloud Identity (IAS) or Windows SPNego. Rather than script that, a real browser establishes the session once and the cookie is reused:
Refresh (out-of-band, occasional):
./refresh-session.ps1 # opens Edge, completes SSO, saves the cookie # or: python refresh_session.py --timeout 300Writes the SAP session cookie to
%USERPROFILE%\.solman-mcp\cookies.txt(never committed). First run may need an interactive login; later runs are silent (persistent Edge profile).Server (runtime): loads the cookie, handles the CSRF token, never opens a browser. If the session expires, tools return
SESSION EXPIRED: … run refresh_session.py.
Note: ADT-based SSO cookie tools can't be reused here because a Focused Build system usually has its ADT node closed — hence the dedicated refresh script that lands on an allowed OData path.
Tools (60)
Tool | Purpose |
Session & discovery | |
| Check the session is live (else run refresh_session.py) |
| List Focused Build object types (Requirement, WP, Defect, RfC, Risk, …) |
| Resolve solution/branch/scope names ("Release 5") to ids in one call |
| A solution's branches, each with all scopes — one-call orientation |
| Reference values: solutions/priorities/classifications/categories/statuses/projects |
| Branches for a solution |
Requirements | |
| Find requirements by title substring |
| Filtered listing, newest first, FLP deep links (see query-semantics note) |
| Read a requirement in full (incl. FLP link) |
| Create — in ANY solution by name; attached element lands in the named scope |
| Many at once; shared context resolved once; continues on row errors |
| MERGE-update editable fields |
| Lifecycle actions (PPF) |
| Canonical lifecycle steps |
SolDoc elements & tree | |
| Flat element search in any solution |
| Attach element under a named scope (re-run = re-scope in place) |
| Explicitly re-file an attached element's scope |
| Read / remove element links |
| Tree navigation; all accept |
Attachments (requirements, WPs, WIs) | |
| Files + URL links on any object |
| Attach a file (verified) |
| Attach a URL link (verified) |
| Byte-exact download |
| Remove an attachment (verified) |
Work Packages & Work Items | |
| Create WP (S1IT) linked to its Approved requirement (self-verified) |
| Link / withdraw |
| Create a Work Item (scope item) that PERSISTS — auto-scoping + auto component pick |
| Valid technical components for WIs under a WP |
| Scope items under a WP |
Test Suite — test cases, steps, xlsx, plans/packages | |
| Find/read test cases (server-side name search + folder) |
| Ordered steps (description / expected result / instruction) |
| Create a test case (folder id from |
| MERGE header (description/prerequisites/exit-criteria/priority/…) |
| Write steps (deep-save; replace or append) |
| Delete (cleanup) |
| Test plans that contain the case (with links) |
| The blank upload template (xlsx) |
| A case's header+steps as the upload-format xlsx |
| Upload a filled xlsx — auto-maps template headers; validate-only by default |
| Browse plans & their packages |
| Test-status progress per plan |
| Test-data parameters (variants) |
| folders / status_schemas / statuses / priorities / solutions |
Generic (any object type) | |
| Read + lifecycle for every ProcessType (Defect, RfC, Risk, …) |
Coverage (toward full browser parity)
Covered
Requirements — full CRUD in any solution by name, batch create, trustworthy filtered listing with FLP deep links, attach/re-scope/detach SolDoc elements, whole lifecycle.
The full chain Requirement → Work Package → Work Item, entirely headless — create+approve a requirement, create+link the WP, move it into Scoping, and create persisting Work Items with valid technical components.
Attachments — upload files, attach URL links, list, download, delete — on requirements, WPs and WIs.
SolDoc hierarchy — tree navigation, scope resolution by name, element search, and structure assignment on WPs/WIs — across all solutions.
Test Suite — test cases (CRUD + steps via deep-save), the xlsx template flow (download sample / download a case / upload a filled sheet with auto column-mapping, validate-only by default), test plans & packages (read/browse), where-used, execution status, test-data parameters.
All object types (read + lifecycle) — Defect, RfC, Risk, Master WP, Urgent Change, Defect Correction … via the generic layer (
CRM_GENERIC_SRV).
Not built yet
Type-specific create flows for Defect / RfC / Risk (defects are normally born from test executions, RfCs from ChaRM — separate capture projects; read + lifecycle already work via the generic layer).
Editing WP fields and WP↔requirement unassign (
wpUnassignmentFromRequirement— structured param, uncaptured).Deeper SolDoc authoring (attributes, assigned docs/test cases, structure editing).
Query semantics on this gateway (READ FIRST — verified live)
The SALM gateway silently ignores most $filter fields instead of erroring:
REQUIREMENTSet: onlyBranchId,RequirementId(exact) andRequirementTitle(exact) are honored. Status/priority/owner/project predicates are dropped — and when a dropped predicate is present, even$topis ignored.or-chains keep only the last predicate.$orderbyreturns 500.$count/$inlinecountreturn wrong numbers. On a BranchId-filtered set,$skiplies — every page returns the same window.The one reliable enumerator is
CRM_GENERIC_SRV/WORKSPACESETwithProcessTypesubstringof(…, Description)— honored, and rows come back newest first.list_requirementsis built on it; everything else is filtered client-side.
The Work Item commit recipe (hard-won)
A plain POST BTSCOPESET returns 201 and a WpItemGuid — and the backend
silently discards the row. Three conditions make it persist:
the WP is in Scoping or later (
S1ITR_HANDOVER_TO_SCOPINGon a fresh WP);ConfigItemis valid for this WP/type — the component value help itself returns empty unless filtered byProcessTypeandSystemSwitch;the fill is a deep create to top-level
BTSCOPESETincluding an (empty)BTSCOPE_PARTNERSSetarray — the deep-create signature triggers the CRM one-order save.
create_work_item automates all three and self-verifies via list_work_items.
Test Suite: deep-save + the xlsx flow
Test cases are keyed
(CaseId GUID, CaseVersion, Language). Create =POST TestCaseSet; header edits = MERGETestCaseHeaderSet.Steps DON'T save individually. A direct
POST TestCaseStepSet201s but is silently discarded — steps commit only via a deep POST toTestCaseSetcarryingTestCasetoHeaderNav:[header]with the whole step list nested inheader.TestCaseHeadertoStepsNav(same shape the designer UI submits).set_test_case_stepsbuilds that payload.xlsx flow (
TM_TS_DESIGNER_SRV): download the blank template (TestCaseDownloadSampleSet('')/$value) or a case's steps (TestCaseDownloadSet), and upload in two phases — (1) POST the raw file toTestCaseUploadSet→ the server parses it and returns anUploadCacheIdplus per-column header texts; (2) MERGE the cache entry with the column map (Col<letter> = "<ATTR.KEY>:<index>", e.g.CASE.NAME,STXT.EXPECTED_RESULT) andValidateOnly. Standard template headers auto-map. The SolDoc-path column is only accepted when a branch is supplied ("Upload into SolDoc").Test plans/packages are read via
TM_DASH_SRV(TestPlanSetneeds aSolutionId;TestPackageSetfilters by the plan'sTplnGuid). Where-used per case is theTestCaseHeadertoWuTplnNavheader nav (the flat set returns nothing standalone). Plan/package creation is the classic STWB_2 transaction — no OData.
Attachments: RPC-over-OData
DROP_DOC_SRV requires an Action discriminator on every call, of the form
<consumer app id> + <operation suffix> (e.g. …attachments_Document_Create,
…_Document_Create_Url, delete via HTTP DELETE …?Action=…_Document_Delete).
List = CharmWP_WI_BRSet(CrmId,BranchId)/attachedDeltaDocuments; download =
DocumentContentCollection(…)/$value. Works for any CRM object (Req/WP/WI).
Connectivity
The HTTP client is reused across calls (one cookie load + one CSRF token, connection-pooled) and auto-reloads when refresh_session.py rewrites the cookie file (client_for() watches the file mtime). session_status() gives a cheap liveness check; an expired SAML session is detected (login-HTML response) and reported as SESSION EXPIRED rather than crashing. Refresh is still out-of-band (refresh_session.py). Future: a periodic keepalive ping to reduce session expiries.
Files
config.py— env-driven configuration (loads.env)refresh_session.py/refresh-session.ps1— Playwright SSO cookie mintingclient.py— cookie-only httpx client (CSRF, transient-fault retries, safe paging)solutions.py— solution/branch/scope resolution by NAME, cachedrequirements.py— requirement domain ops (create/batch/list/lifecycle/elements)attachments.py— files + URL links on any object (DROP_DOC_SRV)workpackages.py— WP create/assign/withdraw + Work Item create/list/componentsworkspaces.py— generic operations for every object type (CRM_GENERIC_SRV)soldoc.py— Solution Documentation tree navigation + structure assignment (soldoc_node_selection_srv)testsuite.py— Test Suite: test cases/steps, xlsx upload/download, plans/packages (TM_TS_DESIGNER_SRV,TM_TS_PARAM_SRV,TM_DASH_SRV)server.py— FastMCP stdio server (60 tools)test_mcp.py— read-only MCP stdio smoke test ·test_units.py— offline unit tests
Notes / gotchas (verified against a live SolMan 7.2 Focused Build system)
Requirement transaction type is configurable (
SOLMAN_REQ_PROCESS_TYPE, e.g.S1BR). Primary service =BUSINESS_REQUIREMENTS_SRV;CRM_GENERIC_SRVis used for the requirement search list + some lookups.SolDoc hierarchy = dedicated
soldoc_node_selection_srv(real parent/child tree, not the capped flatELEMENTSet). Root seedCrmObjectSet(CrmId='',BranchId=<b>); nodes via/elementsTree?$filter=ScopeId eq '<scope>'(+and ParentElementId eq '<id>'for children).ScopeIdis mandatory on the tree filter. NodeElementIdis the idattach_elementconsumes.Create needs Category + Owner — omitting them returns HTTP 201 with an empty entity that silently does not persist.
No DELETE / no status field-write. Lifecycle changes are PPF actions (
get_ppf_actions?ActionId='…'&WsGuid='…'), not MERGE ofStatusId.Attach element uses the
Assign_Requirementfunction import —POST REQELEMENTSetis a silent no-op. Attach the reference node (/Business Processes/…), not the library original (/Libraries/…). A step can be referenced into multiple parents — pick the right one.$format=jsonis rejected on write requests (use theAcceptheader).The WORKSPACE
Guid(dashed) ↔RequirementGuid(no dashes, upper) — handled internally.Requirement → Work Package chain: the requirement must be Approved before a WP links to it (
Assign_Existing_Wpsilently no-ops otherwise). WP create =POST BRWPSet(TypeId="WP", ProcessTypeS1IT); the create'sREQUIREMENTSarray does NOT persist the link — theAssign_Existing_Wp(WpGuid, RequirementGuid)function import does. WP targeting (project/phase/ release) comes fromSOLMAN_WP_*config. Withdraw a WP via PPF actionS1ITR_REJECT_SCOPE. The link is self-verified by readingWORKSPACESET(<wp>,'S1IT')/BT_RELATEDTRANSSet(the linked requirement appears there as aWsType='Requirement'row) — soassignedreflects the real state.Lifecycle note: an Approved requirement can no longer be Withdrawn — only Postponed (
S1BR_POSTPONE). Withdraw (S1BR_CANCEL) is only available from Draft / To Be Approved.Work Items are WP scope items (
BTSCOPE). Creating one that PERSISTS needs the three-condition recipe (see "The Work Item commit recipe" above) —create_work_itemautomates it.
This server cannot be installed
Maintenance
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
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/odaiadnan23-design/solman-fb-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server