Microsoft Project
NUGET · HORIZUNMSPROJECTMCP
Audit, reschedule and author Microsoft Project schedules. No Java, no Project install.
Available components
Last scanned (20 hours ago)
Scores higher than 65% of NuGet servers
Category Project Management
How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →
Supply Chain Security88
- No malware found by supply-chain analysis.Pass
- No known CVEs affecting this package version or its production dependencies.Pass
- Install-script risk not yet assessed.Unverified
- No production dependencies, so there is no dependency health to assess. View diagnostics → Pass
Provenance & Transparency48
- Source repository is publicly reachable at the declared URL. View diagnostics → Pass
- Build provenance not yet verified. View diagnostics → Unverified
- Clear OSI-approved license (MIT).Pass
- Actively maintained (last published 14 days ago).Pass
- Publishes a security disclosure policy (SECURITY.md).Pass
Schema Quality & AI Usability64
- AI-judged instruction clarity (excellent).Pass
- Context-footprint check failed: tool/resource definitions use about 7021 tokens (~260/item across 27 items; 27 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management100
- No destabilizing schema changes in the last 30 days.Pass
Tool Coverage100
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 100% of tool parameters carry a description.Pass
Tool Safety100
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- We read all 27 captured tool definition(s), and no name or description among them implies an irreversible operation.Pass
- An AI judge read all 27 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a current MCP spec version (2026-07-28).Pass
Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 29 Oct 26 +1
- Stability: fail → pass ▲ security
- 23 Oct 26 0
- Package version: 1.0.2 → 1.6.1 functional
- 21 Oct 26 +15
- Malware scan: unverified → pass ▲ security
- 20 Oct 26 −15
- Malware scan: pass → unverified ▼ security
- Package version: 1.6.0 → 1.6.1 functional
- 17 Oct 26 +3
No change was recorded against any check on this day. Stability & Change Management went from 78 to 98.
- 16 Oct 26 −3
No change was recorded against any check on this day. Stability & Change Management went from 98 to 78.
- 14 Oct 26 +1
- Package version: 1.0.2 → 1.6.0 functional
- 4 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 85 to 88.
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 4 Nov 2026 · Analysed nuget/HorizunMsProjectMcp@1.6.1
Provenance Inconclusive
We could not complete the check, so nothing is claimed either way. This is a gap on our side, not a finding about the package.
| Result | Inconclusive |
|---|---|
| Ecosystem | nuget |
| Reason | Package not fetched |
Background: How many MCP packages publish verified provenance →
Dependencies 0 packages
| Packages resolved | 0 |
|---|---|
| Tree resolution | Complete |
Background: SBOMs and build attestations, explained →
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
baseline_compare ~182
Earned-value analysis against a stored baseline: BCWS, BCWP, ACWP, schedule and cost variance, SPI, CPI, EAC and TCPI, for the whole project and optionally per top-level WBS branch, plus the tasks with the worst slippage. This is the number a project board asks for and what feeds the S-curve. Says so plainly when no baseline is stored rather than returning zeros that look real.
| Name | Type | Req | Description |
|---|---|---|---|
| baseline | integer | – | Which baseline to measure against: 0 (the main one, default) through 10. |
| byBranch | boolean | – | Also break the metrics down by top-level WBS branch. Defaults to true. |
| handle | string | yes | Document handle from project_open. |
| statusDate | string|null | – | Status date, yyyy-MM-dd. Defaults to the project's own status date, then today. |
No output schema declared.
No examples provided.
bim_link ~219
Tie schedule tasks to the model elements they build, matching on a shared code (HRZ_COD_PRES, a keynote, a budget code). op='suggest' proposes the mapping from an element export and separates out anything that matched only on a code prefix for you to confirm; 'set' stores it; 'get' reads it back; 'clear' removes it. The mapping lives in a sidecar next to the schedule, so re-exporting the model never touches the planner's file.
| Name | Type | Req | Description |
|---|---|---|---|
| codeField | string | – | Task custom field holding the code, e.g. 'Text1'. Defaults to Text1. |
| elementsPath | string|null | – | Path to the element export (JSON array or CSV with elementId, code, quantity, unit). Required for suggest. |
| handle | string | yes | Document handle from project_open. |
| op | string | – | suggest, set, get, or clear. |
| reviewBelow | number | – | Mappings below this confidence are listed for review instead of stored. Defaults to 100. |
No output schema declared.
No examples provided.
bim_sync ~219
Move data across the schedule/model boundary, in either direction. direction='model_to_schedule' turns measured quantities into duration proposals at a stated productivity rate — proposals only, which you then apply with tasks_write. direction='schedule_to_model' writes one row per element carrying its task's dates and progress: that file drives 4D animation in Navisworks, element parameters in Revit, and the progress dashboard in Power BI.
| Name | Type | Req | Description |
|---|---|---|---|
| defaultProductivity | number | – | Productivity to use when a unit is not listed. Defaults to 1. |
| direction | string | yes | model_to_schedule or schedule_to_model. |
| handle | string | yes | Document handle from project_open. |
| outputPath | string|null | – | Output path for schedule_to_model (.csv or .json). |
| productivity | object|null | – | Productivity per day per unit, e.g. {"m3": 25, "m2": 120}. Used by model_to_schedule. |
| statusDate | string|null | – | Status date used to classify element progress, yyyy-MM-dd. |
No output schema declared.
No examples provided.
calendars_write ~130
Manage working calendars: create them (optionally derived from another), delete them, set the working week and its hours (set_week), set exceptions for holidays, shutdowns or extra working days with their hours (set_exception), and choose the project calendar (set_project_calendar). Task and resource calendars are set with tasks_write and resources_write. Verified and dry-runnable exactly as tasks_write describes.
| Name | Type | Req | Description |
|---|---|---|---|
| dryRun | boolean | – | Simulate against a copy and report the impact without committing. |
| handle | string | yes | Document handle from project_open. |
| ops | array | yes | The calendar operations to apply. |
No output schema declared.
No examples provided.
links_query ~195
Read the dependency network. Almost always you want the subgraph around a few tasks rather than every link, so pass uids and a depth. drivingOnly returns just the chain that actually pushes the finish date, which is what you want when asking why the project ends when it does.
| Name | Type | Req | Description |
|---|---|---|---|
| cursor | integer | – | Row offset from a previous nextCursor. |
| depth | integer | – | How many hops out from the seed tasks. 0 = immediate neighbours only. Defaults to 1. |
| direction | string | – | 'pred', 'succ', or 'both' (default). |
| drivingOnly | boolean | – | Return only the driving chain that sets the project finish date. |
| handle | string | yes | Document handle from project_open. |
| limit | integer | – | Maximum rows. Defaults to 200. |
| uids | array|null | – | Centre the subgraph on these task uids. Omit for the whole network. |
No output schema declared.
No examples provided.
links_write ~93
Add, remove, and change dependencies in one batch. Cycles are detected and refused before anything is applied, with the offending chain named in the rejection. Verified and dry-runnable exactly as tasks_write describes.
| Name | Type | Req | Description |
|---|---|---|---|
| dryRun | boolean | – | Simulate against a copy and report the impact without committing. |
| handle | string | yes | Document handle from project_open. |
| ops | array | yes | The dependency operations to apply. |
No output schema declared.
No examples provided.
project_export ~335
Export the schedule for another tool. 'mspdi' and 'mpx' write real schedule files; 'csv' and 'json' write a flat task table; 'pbip_dataset' writes the shaped dataset our Power BI report consumes — tasks, assignments, earned value and the S-curve — rather than a raw dump. Every schedule file written is read back and compared task by task — progress, actual dates, baseline, status date, outline and WBS, assignments (resource and units), task and project calendars, fixed and baseline cost, and each resource's max units, rate and calendar: 'notes' says 'Verified' when all of it survived and WARNING with what was lost when not (mpx keeps baseline dates without times, xer drops the baseline, pmxml drops in-progress percent; mspdi keeps everything). format='mpp' is written by Microsoft Project where it is installed and is all-or-nothing: it replaces the target only after reading back intact, and fails otherwise.
| Name | Type | Req | Description |
|---|---|---|---|
| format | string | – | csv, json or pbip_dataset for a flat table; wbs_dictionary; scurve_xlsx for the S-curve as an Excel workbook with a native chart; mspdi, mpx, mpp, xer, pmxml, planner or sdef for a real schedule file… |
| handle | string | yes | Document handle from project_open. |
| path | string | yes | Output file path. |
| statusDate | string|null | – | Status date used for the earned-value block in pbip_dataset, yyyy-MM-dd. |
No output schema declared.
No examples provided.
project_health ~135
Diagnose what this server can do on this machine. Call it first in every session. Reports the active backend, runtime, whether Microsoft Project is installed AND whether its COM server actually starts, and a capability matrix the other tools honour. When something is wrong it returns the exact diagnosis and a repair path, not a stack trace. Pass deep=true to genuinely launch Microsoft Project instead of only reading its registration — slower and visible on screen, but the only way to know COM works.
| Name | Type | Req | Description |
|---|---|---|---|
| deep | boolean | – | Launch the Microsoft Project COM server for real instead of only inspecting its registration. Starts Project and closes it again. Defaults to false. |
No output schema declared.
No examples provided.
project_import ~124
Bring updates in from a CSV or JSON file — typically progress collected in the field. Runs plan-first: by default it matches rows to tasks by uid and returns the field-by-field diff without changing anything. Pass apply=true once you have read the plan, and the changes go through tasks_write so every one of them is verified by re-reading the model.
| Name | Type | Req | Description |
|---|---|---|---|
| apply | boolean | – | Apply the plan. Defaults to false — plan only. |
| handle | string | yes | Document handle from project_open. |
| path | string | yes | Path to the CSV or JSON file to import. |
No output schema declared.
No examples provided.
project_info ~69
Summarise an open schedule: dates, counts, calendars, which baselines actually hold data, and the aliases of the custom fields. Read this before tasks_query — without the aliases nobody can tell what Text1 means in this particular schedule.
| Name | Type | Req | Description |
|---|---|---|---|
| handle | string | yes | Document handle from project_open. |
No output schema declared.
No examples provided.
project_open ~220
Open a schedule — or start a new one — and get a handle for every other tool. Reads .mpp, .mpt, .mpx, MSPDI .xml, Primavera .xer and .pmxml, Asta .pp and more, with no Microsoft Project needed. Returns a fingerprint of the file; later writes revalidate it and refuse if the file changed on disk in the meantime, so a stale handle can never overwrite somebody else's edits. Pass create=true to begin an empty schedule at that path instead of reading one.
| Name | Type | Req | Description |
|---|---|---|---|
| create | boolean | – | Start a new empty schedule instead of reading an existing file. Refuses to clobber an existing file. |
| mode | string | – | 'readwrite' (default) or 'readonly'. A read-only handle refuses every write tool. |
| name | string|null | – | Project name for a newly created schedule. |
| path | string | yes | Absolute path to the schedule file. |
| startDate | string|null | – | Project start date for a newly created schedule, yyyy-MM-dd. |
No output schema declared.
No examples provided.
project_save ~275
Save or close an open schedule. Never saves on its own — closing with unsaved changes requires either saving first or passing discardChanges=true, so work is never silently lost. Every schedule file written is read back and compared task by task — progress, actual dates, baseline, status date: 'notes' says 'Verified' when all of it survived and WARNING with what was lost when not (mpx keeps baseline dates without times, xer drops the baseline, pmxml drops in-progress percent; mspdi keeps everything). format='mpp' is written by Microsoft Project where it is installed and is all-or-nothing: it replaces the target only after reading back intact, and fails otherwise.
| Name | Type | Req | Description |
|---|---|---|---|
| discardChanges | boolean | – | Allow close to drop unsaved changes. Defaults to false. |
| format | string | – | Output format: 'mspdi' (default, .xml), 'mpx', or 'json'. |
| handle | string | yes | Document handle from project_open. |
| keepOpen | boolean | – | Keep the handle open after saving. Defaults to true. |
| op | string | – | 'save' (write back over the original path), 'save_as' (write to path), or 'close'. |
| path | string|null | – | Target path for save_as. Ignored for save and close. |
No output schema declared.
No examples provided.
resources_query ~166
Read resources, their assignments, and who is overbooked. Overallocation is computed day by day from the assignment spans — Microsoft Project's file format carries no such flag, so this is a real calculation rather than a field read.
| Name | Type | Req | Description |
|---|---|---|---|
| cursor | integer | – | Row offset from a previous nextCursor. |
| handle | string | yes | Document handle from project_open. |
| includeAssignments | boolean | – | Include each resource's assignments. Off by default — they are bulky. |
| limit | integer | – | Maximum rows. Defaults to 50. |
| name | string|null | – | Name substring filter. |
| overallocatedOnly | boolean | – | Only resources that are overbooked on at least one day. |
| type | string|null | – | Filter by type: work, material, or cost. |
No output schema declared.
No examples provided.
resources_write ~83
Create, update, and delete resources, and assign or unassign them to tasks, in one batch. Verified and dry-runnable exactly as tasks_write describes.
| Name | Type | Req | Description |
|---|---|---|---|
| dryRun | boolean | – | Simulate against a copy and report the impact without committing. |
| handle | string | yes | Document handle from project_open. |
| ops | array | yes | The resource operations to apply. |
No output schema declared.
No examples provided.
schedule_analyze ~438
Answer questions about the schedule without downloading it. Computes the critical path, the float distribution, the driving (longest) path, day-by-day resource overallocation, milestone status against deadlines and baseline, and the health of the dependency network. PMO control: status_report is the period report (planned vs earned %, SPI/CPI, earned-schedule SPI(t), EAC by three methods, TCPI, forecast finish, milestones at risk, trend of past cut-offs, health); lookahead is the short-interval (Last Planner) plan for the next weeks with each task's constraints and ready/constrained state, plus PPC of the last recorded commitment; change_log lists every rebaseline, budget load and committed edit with reason, approver and finish impact. Ask for only the aspects you need — each one is computed independently.
| Name | Type | Req | Description |
|---|---|---|---|
| aspects | array|null | – | Which analyses to run: critical_path, float_distribution, longest_path, overallocation, milestones, dependency_health, status_report, lookahead, change_log. Omit for the first six except longest_path. |
| commit | boolean | – | lookahead: record the first week's ready tasks as the team's commitment, so the next report measures PPC against it. |
| constraintsField | string|null | – | lookahead: text field listing constraints logic cannot see, e.g. 'Text3' holding 'material: acero; permiso: municipal'. Items starting 'ok' or saying 'listo'/'liberado' count as released. |
| handle | string | yes | Document handle from project_open. |
| ownerField | string|null | – | lookahead: text field holding who answers for each task, e.g. 'Text2'. Without it, the crews assigned. |
| record | boolean | – | status_report: keep this cut-off in the project's history (.hzpmo.json beside the file) for the trend. |
| statusDate | string|null | – | Status date for status_report and lookahead, yyyy-MM-dd. Defaults to the project's status date, then today. |
| weeks | integer | – | Look-ahead window in weeks (1-8). Defaults to 3. |
No output schema declared.
No examples provided.
schedule_generate ~853
Build a new schedule — from the model, or from past projects. FROM THE MODEL: pass 'elements' as read from the Revit MCP (elementId, code, category, level, quantity, unit — no file needed) and get one task per trade per level, in construction sequence, from a start to a finish milestone with nothing left open-ended; durations are quantity over 'productivity' where a rate is given (by code, category or unit) and 'defaultDays' where not, flagged as assumed; the code goes into 'codeField' and every element is tied to its task, ready for bim_sync to write the 4D dates. FROM PAST PROJECTS: pass 'libraryPath' from schedule_learn. Each activity gets the duration its history says it takes, and the dependencies that usually surround it are recreated between the activities you asked for. Returns an open handle, so run schedule_qa on it before trusting it and adjust with tasks_write — this is a first draft grounded in what actually happened on past projects, not a finished programme.
| Name | Type | Req | Description |
|---|---|---|---|
| activities | array|null | – | Activity keys to include, as listed in the library. Omit to use every activity in it. |
| codeField | string | – | Task field that receives the element code for 4D, e.g. 'Text1'. Defaults to Text1. |
| columnsWithLevelAbove | boolean | – | Revit gives a column its BASE level and a beam its TOP level, so grouped as modelled the columns from level 02 to 03 land with level 02 and are scheduled before slab 02, which carries them. true move… |
| defaultDays | number | – | Duration for work with no productivity rate, in days. Defaults to 1. |
| durationBasis | string | – | 'median' (default) for a normal run, or 'p80' to plan with contingency. |
| elements | array|null | – | Model elements to build from, straight from the Revit MCP: [{elementId, code, category, family, type, level, quantity, unit}]. Grouped by code (or category when there is no code) per level. |
| elementsPath | string|null | – | Or a file with the same elements (JSON array or CSV), when they come from an export. |
| libraryPath | string|null | – | Path to the library JSON from schedule_learn. Not needed when building from 'elements'. |
| name | string|null | – | Name for the new project. |
| outputPath | string | yes | Path for the new schedule. Refuses to overwrite an existing file. |
| productivity | object|null | – | Productivity per day, keyed by code, category or unit, e.g. {"m3": 25, "Muros": 60}. Optional: without it durations are 'defaultDays' and marked as assumed. |
| quantities | object|null | – | Measured quantities per activity key, e.g. {"VACIADO LOSA": 340}. Where the library learned a productivity rate for that activity, the duration is sized from the quantity instead of copied from histo… |
| sequence | array|null | – | Order of trades, as case-insensitive fragments of code or category, each may hold alternatives separated by '|', e.g. ["cimenta", "column|viga", "losa", "muro"]. Defaults to a standard building seque… |
| startDate | string | yes | Project start date, yyyy-MM-dd. |
| unitLabel | string | – | Word naming a unit, used in the task names: 'apto', 'piso', 'torre'. Defaults to 'unidad'. |
| units | integer | – | How many units to build — apartments, floors, blocks. Activities the library found to repeat unit by unit are created once per unit and chained, which is how construction schedules are actually shape… |
No output schema declared.
No examples provided.
schedule_learn ~262
Mine finished schedules for how long each kind of activity actually takes and what usually comes before and after it. Reads any number of .mpp, MSPDI or Primavera files, normalises task names so the same activity matches across projects and units, and reports each activity's duration distribution — median, 80th percentile, range — together with its typical predecessors and successors and the lag between them. Save the result and hand it to schedule_generate to build a new schedule from experience rather than from a blank page.
| Name | Type | Req | Description |
|---|---|---|---|
| codeField | string|null | – | Custom field holding the budget code, e.g. 'Text1', to carry into the library. |
| minOccurrences | integer | – | Ignore activities seen fewer times than this. Defaults to 3. |
| paths | array | yes | Paths of past schedules to learn from. |
| quantitySources | array|null | – | Element exports (the same CSV or JSON bim_link reads) carrying measured quantities per code. Supply them together with codeField and the library reports a productivity rate per activity — how much a… |
| savePath | string|null | – | Where to save the library as JSON. Omit to return it without saving. |
No output schema declared.
No examples provided.
schedule_qa ~291
Run the DCMA 14-point schedule assessment plus Horizun's own rules, and report what is wrong with the schedule. This is the industry standard for judging whether a schedule can be run on: missing logic, leads and lags, hard constraints, high float and duration, negative float, invalid dates, unresourced work, missed baseline tasks, CPLI and BEI. Checks that genuinely cannot be evaluated (no baseline stored, no scheduling engine) are reported as not evaluated with the reason — never as a pass.
| Name | Type | Req | Description |
|---|---|---|---|
| budgetCodeField | string|null | – | Custom field carrying the budget code, e.g. 'Text1'. Supply it to also check that every task is tied to the cost model — the same code the BIM tools match on. |
| handle | string | yes | Document handle from project_open. |
| justifiedLags | array|null | – | Uids of tasks whose incoming lags or leads are justified (curing, a requested fast-track): left out of the lag and lead checks, and listed in the notes. |
| statusDate | string|null | – | Status date for the progress checks, yyyy-MM-dd. Defaults to the project's own status date, then today. |
| targetFinish | string|null | – | The finish CPLI (check 13) is measured against, yyyy-MM-dd. Defaults to a deadline or finish constraint on the finish milestone, then the baseline finish. |
No output schema declared.
No examples provided.
schedule_recovery ~272
Work out what is late, what it is costing the finish date, and which changes to the logic would actually recover time. Lists the late work ordered by how much of the schedule is stuck behind it, then measures recovery levers — removing lag on the driving chain, overlapping finish-to-start hand-offs, compressing the longest critical tasks. Every option is applied to a throwaway copy, rescheduled, and reported with the finish date it genuinely produces; an option that recovers nothing says so rather than being offered as advice. Also returns replanReview: the tasks a planner should re-plan at this cut-off and why — not started when due, overdue, progressing slower than its elapsed time, drifting from its baseline, eating its float, started out of sequence — each with the figures behind it and the move to make. It proposes; the planner decides. Nothing is written to the open document.
| Name | Type | Req | Description |
|---|---|---|---|
| handle | string | yes | Document handle from project_open. |
| maxOptions | integer | – | How many recovery options to return. Defaults to 5. |
| statusDate | string|null | – | Status date, yyyy-MM-dd. Defaults to the project's own, then today. |
| targetFinish | string|null | – | The date you need to finish by, yyyy-MM-dd. Adds the gap to the report. |
No output schema declared.
No examples provided.
schedule_risk ~326
Quantitative schedule risk analysis (Monte Carlo). Samples every remaining duration from a three-point range and re-runs the network logic (all four link types and lags) thousands of times, then reports the finish date at P10/P50/P80/P90, the probability of meeting a target and the baseline finish, the contingency needed for P80, and the risk drivers — how often each task is critical (criticality) and how strongly it moves the finish (sensitivity). Give per-task ranges from the team where you have them; the rest get the default spread.
| Name | Type | Req | Description |
|---|---|---|---|
| distribution | string | – | triangular (default) or pert. |
| handle | string | yes | Document handle from project_open. |
| iterations | integer | – | Number of simulations (100-20000). Defaults to 2000. |
| optimisticPct | number | – | Default optimistic deviation of remaining duration, percent (negative). Defaults to -10. |
| pessimisticPct | number | – | Default pessimistic deviation of remaining duration, percent. Defaults to 30. |
| ranges | object|null | – | Per-task three-point ranges in working days, keyed by UniqueID: {"12": {"optimistic":4, "mostLikely":5, "pessimistic":9}}. |
| seed | integer|null | – | Random seed, for a repeatable run. |
| statusDate | string|null | – | Data date the simulation starts from, yyyy-MM-dd. Defaults to the status date, then the project start. |
| target | string|null | – | Target finish date to test, yyyy-MM-dd. |
No output schema declared.
No examples provided.
schedule_scenarios ~202
Compare what-if scenarios without committing anything. Each scenario is a set of calendar, resource, task and dependency operations (the same ones the write tools take), applied to its own copy of the schedule, which is then scheduled. Returns, next to the schedule as it is: finish and its change in working days, total cost and its change, resource overallocation windows and peak load, critical task count, and anything a scenario asked for that was refused.
| Name | Type | Req | Description |
|---|---|---|---|
| extraTimeCostPerHour | number|null | – | Premium for working time a scenario adds to the calendars (Saturdays, longer days), per task-hour — the surcharge a crew costs on top of what the schedule already prices. Omit it and such scenarios a… |
| handle | string | yes | Document handle from project_open. |
| scenarios | array | yes | The scenarios to compare (1-8). |
No output schema declared.
No examples provided.
schedule_sequence ~447
Recover the logic a schedule is missing by reading the order its own dates already state. A schedule whose work was laid out in the right order but never linked is a bar chart, not a network: nothing moves when anything slips, float reads as enormous, and any target date computed over it is arithmetic. This finds the repeating groups — apartments, floors, spans, wells, whatever the work repeats over — reads the order each one runs in, keeps only the orderings the repetitions agree on, and proposes the missing links. It never invents an order the dates do not state and never proposes a link where a path already exists. Defaults to proposing only; pass apply=true to write them, verified.
| Name | Type | Req | Description |
|---|---|---|---|
| apply | boolean | – | Write the proposed links instead of only reporting them. Defaults to false. |
| groupBy | string | – | 'unit' (default) groups by the identifier that varies between repetitions — the number at the end of a task name. 'parent' groups by the WBS parent instead. |
| groupDepth | integer | – | How far down the WBS the grouping branch sits — the tower, phase or building a unit number is unique within. Defaults to 2. Raise it where units repeat within a deeper branch; lower it where one numb… |
| handle | string | yes | Document handle from project_open. |
| maxLinks | integer | – | Maximum links to propose in one pass. Defaults to 500. |
| minAgreement | number | – | How strongly the repetitions must agree on an ordering before it is trusted, 0-1. Defaults to 0.8. Lower it only where the variation between units is genuine. |
| preserveDates | boolean | – | Carry the existing gap between each pair as lag so no date moves. Off by default: it sounds like the safe choice and measurably is not, because it turns every recovered link into a positive lag. On a… |
No output schema declared.
No examples provided.
schedule_target ~142
Test a schedule against a date you have been given. Reports whether the target is achievable, how many working days short it falls, the driving chain with the dates each task would have to hit, and every task the network does not actually hold in place — work with no predecessor or no successor, which never moves when its neighbours do and makes any target date arithmetic rather than a plan. Read-only.
| Name | Type | Req | Description |
|---|---|---|---|
| anchor | string | – | 'finish' (default) to test a completion date, or 'start' to test a start date. |
| handle | string | yes | Document handle from project_open. |
| target | string | yes | The target date, yyyy-MM-dd. |
No output schema declared.
No examples provided.
schedule_update ~427
Engine-level operations that take no per-task payload: save or clear a baseline, set the status date, reschedule incomplete work, level resources, or force a recalculation. Levelling and rescheduling are the two that do the most damage by accident, so they require a dry run to be seen first. Operations that need Microsoft Project's scheduling engine are refused outright on the MPXJ backend rather than approximated.
| Name | Type | Req | Description |
|---|---|---|---|
| approvedBy | string|null | – | Who approved the change, for the change log. |
| baseline | integer | – | Baseline slot 0-10 for save_baseline and clear_baseline. Defaults to 0. |
| budget | object|null | – | For load_budget: amount per code, e.g. {"D021-A1-A01": 125000000}. |
| budgetPath | string|null | – | For load_budget: or a CSV of code,amount. |
| codeField | string | – | For load_budget: the task field holding the code. Defaults to Text1. |
| dryRun | boolean | – | Simulate against a copy and report the impact without committing. |
| handle | string | yes | Document handle from project_open. |
| levelingCanSplit | boolean | – | For level_resources: let levelling split remaining work. |
| op | string | yes | save_baseline, clear_baseline, set_status_date, reschedule_incomplete, load_budget, level_resources, or recalculate. |
| overwriteBaseline | boolean | – | Allow save_baseline to replace a baseline that already holds data. Off by default: overwriting one destroys the original plan every variance is measured against. |
| reason | string|null | – | Why — recorded in the change log. Required to replace a baseline (a rebaseline is a change to the approved plan and has to be justified); recommended for every save_baseline and load_budget. |
| statusDate | string|null | – | Status date for set_status_date and reschedule_incomplete, yyyy-MM-dd. |
| withinSlack | boolean | – | For level_resources: delay tasks only within their slack, so the finish date cannot move. |
No output schema declared.
No examples provided.
tasks_query ~481
The workhorse read. Filter, sort, and page through tasks without pulling the whole schedule into context. Every task is identified by its stable uid — the id field is the row number and shifts when tasks are inserted, so never use it to address a task in a write. Defaults to a compact field set and 50 rows; ask for more only when you need it.
| Name | Type | Req | Description |
|---|---|---|---|
| critical | boolean|null | – | true = only critical tasks, false = only non-critical, null = both. |
| cursor | integer | – | Row offset from a previous nextCursor. |
| customField | string|null | – | Custom field filter, e.g. 'Text1'. Pair with customValue. |
| customValue | string|null | – | Value the custom field must contain. |
| dateField | string|null | – | Date filter field: start, finish, baseline_finish, or deadline. |
| dateFrom | string|null | – | Date filter lower bound, yyyy-MM-dd. |
| dateTo | string|null | – | Date filter upper bound, yyyy-MM-dd. |
| handle | string | yes | Document handle from project_open. |
| includeCustom | boolean | – | Include the Text1..Text30 custom fields on each row. Off by default — they are bulky. |
| limit | integer | – | Maximum rows to return. Defaults to 50. |
| maxFloatDays | number|null | – | Only tasks whose float is at or below this many days — use 0 to find the driving work. |
| milestone | boolean|null | – | true = only milestones, false = exclude milestones, null = both. |
| minDurationDays | number|null | – | Only tasks whose duration exceeds this many days. |
| resource | string|null | – | Only tasks this resource is assigned to (name substring). |
| shape | string | – | Shape: flat (default), leaf_only, or summary_only. |
| sort | string | – | Sort by start (default), finish, float, duration, or wbs. |
| status | string|null | – | Status filter: not_started, in_progress, complete, or late. |
| text | string|null | – | Case-insensitive substring match on name and notes. |
| uids | array|null | – | Restrict to these task uids. |
| wbsPrefix | string|null | – | Only tasks whose WBS starts with this prefix, e.g. '1.2'. |
No output schema declared.
No examples provided.
tasks_write ~174
Create, update, delete and re-outline tasks in one batch. Progress (percentComplete, actual dates) is an ordinary update. Tasks are addressed by their stable uid — never by row id. Every change is re-read from the model after the write and only then counted as applied; anything the schedule refused comes back under 'rejected' with the reason and what the value actually became. Pass dryRun=true to run the whole batch against a throwaway copy and see the impact — how many tasks move, how far the finish date shifts, whether the critical path changes — without touching the open document.
| Name | Type | Req | Description |
|---|---|---|---|
| dryRun | boolean | – | Simulate against a copy and report the impact without committing. |
| handle | string | yes | Document handle from project_open. |
| ops | array | yes | The operations to apply, in order. |
No output schema declared.
No examples provided.
timephased_query ~261
Work or cost spread over time — the S-curve. Kept separate from the other reads because it is the expensive one: it refuses ranges that would generate an unreasonable number of buckets and tells you to coarsen the granularity instead of quietly returning tens of thousands of rows.
| Name | Type | Req | Description |
|---|---|---|---|
| from | string|null | – | Range start, yyyy-MM-dd. Defaults to the project start. |
| granularity | string | – | 'day', 'week' (default), or 'month'. |
| handle | string | yes | Document handle from project_open. |
| measure | string | – | 'work' (default), 'cost', 'duration', 'baseline_work', 'baseline_cost', or 's_curve' — the earned value S-curve: cumulative PV over the baseline, EV earned to the status date and AC actual cost, in m… |
| to | string|null | – | Range end, yyyy-MM-dd. Defaults to the project finish. |
| uids | array|null | – | Restrict to these task uids. Omit for the whole project. |
No output schema declared.
No examples provided.
How do I install the Microsoft Project MCP server?
Microsoft Project runs locally as a NuGet package, launched with dnx HorizunMsProjectMcp@1.6.1 --yes. Ready-made configuration for Claude, Cursor, VS Code, Codex and 3 more is on this page, copied from each client's own documentation.
nuget · HorizunMsProjectMcp
claude mcp add horizungroup-horizun-msproject-mcp -- dnx HorizunMsProjectMcp@1.6.1 --yes
What is the Microsoft Project MCP server?
Microsoft Project is an MCP server listed in the public MCP registry as io.github.HorizunGroup/horizun-msproject-mcp. Audit, reschedule and author Microsoft Project schedules. No Java, no Project install. This page covers its NuGet package (HorizunMsProjectMcp).
Is the Microsoft Project MCP server safe to use?
Microsoft Project scores 80 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 4 November 2026. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the Microsoft Project MCP server expose?
Microsoft Project exposes 27 tools: project_health, bim_link, schedule_qa, calendars_write, schedule_update, and 22 more. Their descriptions and schemas cost roughly 7,021 tokens of context every time the server is loaded.
Is the Microsoft Project MCP server still maintained?
Microsoft Project is still listed as active in the MCP registry. We last reached this channel on 4 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.
What licence is the Microsoft Project MCP server under?
Microsoft Project declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.